From gitlab at gitlab.haskell.org Wed Jan 1 01:14:38 2025 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski (@monoidal)) Date: Tue, 31 Dec 2024 20:14:38 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25616-test Message-ID: <677496fe7b6_7265821c708688d0@gitlab.mail> Krzysztof Gogolewski pushed new branch wip/T25616-test at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25616-test You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 1 11:12:25 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Wed, 01 Jan 2025 06:12:25 -0500 Subject: [Git][ghc/ghc][wip/structured-ghci-errors] 364 commits: Handle exceptions from IO manager backend Message-ID: <677523192441b_ccdefa4f81c510e4@gitlab.mail> sheaf pushed to branch wip/structured-ghci-errors at Glasgow Haskell Compiler / GHC Commits: 69960230 by Fabian Thorand at 2024-10-10T19:03:59+00:00 Handle exceptions from IO manager backend If an IO manager backend throws, it will not actually have registered the file descriptor. However, at that point, the IO manager state was already updated to assume the file descriptor is being tracked, leading to errors and an eventual deadlock down the line as documented in the issue #21969. The fix for this is to undo the IO manager state change in case the backend throws (just as we already do when the backend signals that the file type is not supported). The exception then bubbles up to user code. That way we make sure that 1. the bookkeeping state of the IO manager is consistent with the actions taken by the backend, even in the presence of unexpected failures, and 2. the error is not silent and visible to user code, making failures easier to debug. - - - - - 1587cccf by Hassan Al-Awwadi at 2024-10-11T03:52:36-04:00 Put RdrName in the foExt field of FieldOcc The main purpose of this commit is to rip RdrName out of FieldOcc, in accordance with #21592, and as a side note it has simplified the method we use to deal with ambiguity somewhat. To do the first, we make FieldOccs store (LIdP p) instead of always storing Located RdrName, and moved the readername to the extension points where necessary. For the second, well, we just turn an ambiguous RdrName into a unbound Name through mkUnboundName. Later during disambiguateRecordBinds of the type checking phase, we will try and do type-directed disambiguation based on the rdrName field (for now), so this hack works out fine. See Note [Ambiguous FieldOcc in record updates] for more details. There are two additional minor changes in this commit: * The HsRecSel constructor of HsExpr has been moved to the extension constuctors, since its really GHC specific. * HsProjection no longer has a Located DotFieldOcc as a field, but just a regular DotFieldOcc, since DotFieldOcc already wraps a located FieldLabelString co-authored by: @Jade <Jade512 at proton.me> @alt-romes <rodrigo.m.mesquita at gmail.com> - - - - - 2338a971 by Cheng Shao at 2024-10-11T03:53:13-04:00 driver: bail out when -fllvm is passed to GHC not configured with LLVM This patch makes GHC bail out with an proper error message when it's not configured with LLVM but users attempt to pass -fllvm, see #25011 and added comment for details. Fixes #25011 Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 78ad81ec by Cristiano Moraes at 2024-10-11T03:53:55-04:00 configure: Find C++ probing when GCC version is the latest but G++ is old #23118 - - - - - 083703a1 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Consider Wanteds with rewriters as insoluble This MR fixes #25325 See GHC.Tc.Types.Constraint, Note [Insoluble Wanteds], especially (IW2) There is a small change in the error message for T14172, but it looks entirely acceptable to me. - - - - - 0dfaeb66 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Wibbles - - - - - 09d24d82 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Spelling errors - - - - - 694489ed by sheaf at 2024-10-11T03:55:14-04:00 LLVM: use sse4.2 instead of sse42 LLVM expects the former instead of the latter since version 3.4. Fixes #25019 - - - - - 06ae8507 by sheaf at 2024-10-11T03:55:14-04:00 LLVM: make SSE4.2 imply +popcnt For consistency with the NCG as well as with Clang and GCC, we make the SSE4.2 feature flag imply +popcnt when using the LLVM backend. Fixes #25353 - - - - - 3fe843c7 by Cheng Shao at 2024-10-11T03:55:50-04:00 Drop obsolete libffi Makefile This patch drops obsolete libffi Makefile from the tree, given it's completely unused since removal of make build system in !7094. - - - - - df70405c by Ben Gamari at 2024-10-11T03:56:26-04:00 ghc-internal: Fix incomplete matches on IOError As noted in #25362, these incomplete matches were previously not being warned about. They were easily addressed by use of `GHC.Internal.Event.Windows.withException`. Closes #25362. - - - - - 8584504b by Matthew Pickering at 2024-10-11T03:57:02-04:00 compiler: Fix orientation of GHC.Hs.Doc boot file We should be free to import things from Language.Haskell.Syntax in GHC modules. Therefore the the boot file for the loop between ImpExp and GHC.Hs.Doc was in the wrong place. Issue #21592 - - - - - d029f170 by Ben Gamari at 2024-10-11T23:43:17-04:00 testsuite: Normalise trailing digits from hole fits output The type variables in the holes fit output from `abstract_refinement_hole_fits` is quite sensitive to compiler configuration. Specifically, a slight change in the inlining behavior of `throw` changes type variable naming in `(>>=)` and a few others. Ideally we would make hole fits output more deterministic but in the meantime we simply normalise this difference away as it not relevant to the test's goal. - - - - - da5d7d0d by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Add test for #25066 - - - - - eb7ddae1 by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Fix #25066 As noted in #25066, the exception backtrace proposal introduced a rather subtle performance regression due to simplification producing Core which the demand analyser concludes may diverge with a precise exception. The nature of the problem is more completely described in the new Note [Hiding precise exception signature in throw]. The (rather hacky) solution we use here hides the problematic optimisation through judicious use of `noinline`. Ultimately however we will want a more principled solution (e.g. #23847). Fixes #255066 CLC proposal: https://github.com/haskell/core-libraries-committee/issues/290 Metric Decrease: T9872d - - - - - 0060ece7 by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Improve documentation of Control.Exception.Backtrace - - - - - 18f532f3 by Ben Gamari at 2024-10-11T23:43:53-04:00 Bump process submodule to v1.6.25.0 - - - - - a9a3badf by Hassan Al-Awwadi at 2024-10-11T23:44:29-04:00 Move HsInteger and HsRat to an extension constructor These constructors were only used during the TC stage, or during template haskell. It seemed clear that it was independent of the source syntax represented in L.H.S, and thus we removed it according to #21592. - - - - - 4dd30cba by Artem Pelenitsyn at 2024-10-11T23:45:09-04:00 Docs: Linear types: link Strict Patterns subsection Also, fix a bug in RST with missing newline before a listing. Co-authored-by: Arnaud Spiwack <arnaud at spiwack.net> - - - - - adca5f2b by Ben Gamari at 2024-10-11T23:45:45-04:00 users guide: Address remaining TODOs in eventlog format docs Closes #25296. - - - - - 9291c125 by Sylvain Henry at 2024-10-11T23:46:26-04:00 Fix z-encoding of tuples (#25364) Tuples with prefix/suffix strings weren't always properly encoded with their shortcut notations. Fix this. - - - - - c08b68bc by Sven Tennie at 2024-10-11T23:47:01-04:00 Delete constants that can be deduced There are macros in MachRegs.h to figure those out. - - - - - 8b402da2 by Zubin Duggal at 2024-10-12T20:36:57+00:00 hadrian: Handle broken symlinks properly when creating source dist directories If we have a broken symlink in the repository, don't try to `need` the symlink or the target of the symlink. Attempting to do so has `shake` attempt to read the target to compute its hash, which fails because the target doesn't exist. - - - - - 16f97667 by Zubin Duggal at 2024-10-12T20:36:57+00:00 hadrian: exclude cabal.project.symlink.broken from source archives Cabal 3.14 introduced a broken symlink in its testsuite. Unfortunately, this broke our source distribution as we use use `tar --dereference` to avoid issues with symlink compatibility on windows, and `tar --dereference` chokes when it encounters any broken symlinks. We can't get rid of `--dereference` because symlinks are generally broken on windows, so the only option is to exclude this file from source archives. see also https://github.com/haskell/cabal/issues/10442 - - - - - f1a2c9fc by Zubin Duggal at 2024-10-12T20:36:57+00:00 Bump Cabal submodule to 3.14 Metric Decrease: MultiLayerModulesTH_OneShot Metric Increase: haddock.Cabal - - - - - 745dd590 by Ben Gamari at 2024-10-14T09:13:12-04:00 users-guide: Document GHCi :where command Resolve #24509. - - - - - e9cc4699 by Alan Zimmerman at 2024-10-14T09:13:48-04:00 EPA: Remove [AddEpAnn] from IE, Pat and some Tys EPA: Remove [AddEpAnn] from LazyPat EPA: Remove [AddEpAnn] from RecordCon/RecordUpd/ConPat EPA: Remove [AddEpAnn] from HsFieldBind EPA: Remove [AddEpAnn] from PatSynBind EPA: Remove [AddEpAnn] from IPBind EPA: Remove [AddEpAnn] from FixSig EPA: Remove [AddEpAnn] from activation rules EPA: Remove [AddEpann] from SpecInstSig EPA: Remove [AddEpAnn] from MinimalSig EPA: Remove [AddEpAnn] from SCCFunSig EPA: Remove [AddEpAnn] from CompleteMatchSig EPA: Remove [AddEpAnn] from AnnSig, as used in PatSynSig, ClassOpSig, TypeSig EPA: Remove [AddEpAnn] from IEThingAbs EPA: Remove [AddEpAnn] from IEThingAll / IEThingWith EPA: Remove [AddEpAnn] from IEModuleContents EPA: Remove [AddEpAnn] from HsOpTy EPA: Remove [AddEpAnn] for various binders EPA: Remove [AddEpAnn] for HsIParamTy - - - - - 81a570bf by Sebastian Graf at 2024-10-14T22:15:31-04:00 Desugaring, plus -Wincomplete-record-selectors This commit does several related things: * Major refactor of the handling of applications in the desugarer. Now all applications are handled in `dsApp`, `ds_app` and related functions. This dramatically simplifies the code and removes complicated cruft that had accumulated. Hooray. Fixes #25281. * Improve the handling of -Wincomplete-record-selectors. We now incorporate the result type of unsaturated record selector applications as well as consider long-distance information in getField applications. Plus, the implmentation now builds the improved `dsApp` stuff above, so it is much easier to understand. Plus, incorporates improved error message wording suggested by Adam Gundry in !12685. Fixes #24824, #24891 See the long Note [Detecting incomplete record selectors] * Add -Wincomplete-record-selectors to -Wall, as specified in GHC Proposal 516. To do this, I also had to add -Wno-incomplete-record-selectors to the build flags for Cabal in GHC's CI. See hadrian/src/Settings/Warnings.hs. We can remove this when Cabal is updated so that it doesn't trigger the warning: https://github.com/haskell/cabal/issues/10402 2.6% decrease in compile time allocation in RecordUpPerf Metric Decrease: RecordUpdPerf - - - - - ae7bc08e by Simon Peyton Jones at 2024-10-14T22:15:31-04:00 Elmininate incomplete record selectors This patch is a pure refactor of GHC's source code, to avoid the use of partial record selectors. It was provoked by adding -Wincomplete-record-selectors to -Wall (as the GHC Proposal specified), which in turn showed up lots of places where GHC was using incomplete record selectors. This patch does mostly-simple refactoring to make it clear to the pattern match checker that there is in fact no partiality. There is one externally-visible change: I changed the data type HoleFit to split out the two cases data HoleFit = TcHoleFit TcHoleFit | RawHoleFit SDoc data TcHoleFit = HoleFit { ...lots of fields } There are large swathes of code that just deal with `TcHoleFit`, and having it as a separate data types makes it apparent that `RawHoleFit` can't occur. This makes it much better -- but the change is visible in the HolePlugin interface. I decided that there are so few clients of this API that it's worth the change. I moved several functions from Language.Haskell.Syntax to GHC.Hs. Reason, when instantiated at (GhcPass _), the extension data construtcor is guaranteed unused, and that justifies omitted patterns in these functions. By putting them in GHC.Hs.X I can specialise the type for (GhcPass _) and thereby make the function total. An interesting side-light is that there were a few local function definitions without a type signature, like this one in GHC.Parser.Header convImport (L _ i) = (ideclPkgQual i, reLoc $ ideclName i) This is fully closed, and so is generalised; but that generalises it to any old pass, not (GhcPass _), so GHC rightly complains about the use of the selector `ideclPkgQual`. I added a type signature to `i`, thus convImport (L _ (i::ImportDecl GhcPs)) = (ideclPkgQual i, reLoc $ ideclName i) which specialised the function enough to make the record selector complete. Quite a surprising consequence of local let-generalisation! - - - - - 6a067226 by Simon Peyton Jones at 2024-10-14T22:15:31-04:00 Add -Werror=-Wno-error=incomplete-record-selectors to hadrian-multi In the main MR, -Wall now includes -Wincomplete-record-selectors. However `hadrian-multi` has many, many warnings about incomplete record selectors, so this patch stops those warnings being treated as errors. (See discussion on !13308.) A better fix would be to remove the use of incomplete record selectors, since each of them represents a potential crash. - - - - - edeafc14 by Ben Gamari at 2024-10-14T22:16:08-04:00 users-guide: Document field coalescence - - - - - 55b83587 by ARATA Mizuki at 2024-10-14T22:16:49-04:00 LLVM backend: Use correct rounding for Float literals Fixes #22033 - - - - - e59fe5c6 by Hassan Al-Awwadi at 2024-10-15T08:25:33+00:00 Changed import from Ghc. module to L.H.S module Progresses #21592 For some reason we still imported GHC.Types.Fixity when the definitino of Fixity and LexicalFixity have already been moved to Language.Haskell.Syntax.Basic. This fixes that for - - - - - ab1767d5 by Simon Peyton Jones at 2024-10-15T23:45:04-04:00 Add a release-notes entry for -Wincomplete-record-selectors - - - - - 6f0a62db by ur4t at 2024-10-16T15:33:43+00:00 GHCi: fix improper location of ghci_history file Fixes #24266 - - - - - 5f67db48 by Alan Zimmerman at 2024-10-17T05:18:43-04:00 EPA: Remove [AddEpAnn] commit 3 EPA: Remove [AddEpAnn] from HsDocTy EPA: Remove [AddEpAnn] from HsBangTy EPA: Remove [AddEpAnn] from HsExplicitListTy EPA: Remove [AddEpAnn] from HsExplicitTupleTy EPA: Remove [AddEpAnn] from HsTypedBracket EPA: Remove [AddEpAnn] from HsUntypedBracket EPA: Remove [AddEpAnn] from PatBuilderOpApp EPA: break out 'EpToken "|"' from ClassDecl anns EPA: Remove [AddEpAnn] from ClassDecl EPA: Remove [AddEpAnn] from SynDecl - - - - - fbbbd010 by Daan Rijks at 2024-10-17T05:19:19-04:00 Expand the haddocks for Control.Category - - - - - 076c1a10 by Andrew Lelechenko at 2024-10-17T05:19:19-04:00 documentation: more examples for Control.Category - - - - - 90891962 by Cheng Shao at 2024-10-17T16:41:18+00:00 ghci: mitigate host/target word size mismatch in BCOByteArray serialization This patch mitigates a severe host/target word size mismatch issue in BCOByteArray serialization logic introduced since !12142, see added note for detailed explanation. - - - - - 839ac52e by Cheng Shao at 2024-10-17T16:41:18+00:00 ghci: use plain malloc for mkConInfoTable on non-TNTC platforms This patch avoids using mmap() to allocate executable memory for mkConInfoTable on platforms without tables-next-to-code, see added comment for explanation. - - - - - a998f69d by Cheng Shao at 2024-10-17T16:41:18+00:00 ghc-internal: add missing CPPs for wasm This patch adds some missing CPP guards to ghc-internal, given those functions are non existent on wasm and would cause linking issues. - - - - - 71a471e7 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: rename prelude.js to prelude.mjs This commit renames prelude.js to prelude.mjs for wasm backend rts jsbits, and slightly adjusts the jsbits contents. This is for preparing the implementation of dyld.mjs that contains wasm dynamic linker logic, which needs to import prelude.mjs as a proper ESM module. - - - - - 33d9db17 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: add __wrapped_freeJSVal This commit wraps imported freeJSVal in a __wrapped_freeJSVal C function for wasm backend RTS. In general, wasm imports are only supposed to be directly called by C; they shouldn't be used as function pointers, which confuses wasm-ld at link-time when generating shared libraries. - - - - - 0d0a16a8 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: correct stale link in comment - - - - - 90a35c41 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: drop interpretBCO support from non-dyn ways on wasm This commit drops interpretBCO support from non dynamic rts ways on wasm. The bytecode interpreter is only useful when the RTS linker also works, and on wasm it only works for dynamic ways anyway. An additional benefit of dropping interpretBCO is reduction in code size of linked wasm modules, especially since interpretBCO references ffi_call which is an auto-generated large function in libffi-wasm and unused by most user applications. - - - - - 98a32ec5 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: don't build predefined GloblRegs for wasm PIC mode This commit wraps the predefined GlobalRegs in Wasm.S under a CPP guard to prevent building for PIC mode. When building dynamic ways of RTS, the wasm globals that represent STG GlobalRegs will be created and supplied by dyld.mjs. The current wasm dylink convention doesn't properly support exporting relocatable wasm globals at all, any wasm global exported by a .so is assumed to be a GOT.mem entry. - - - - - bef94bde by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: fix conflicting StgRun definitions on wasm This commit fixes conflicting StgRun definition when building dynamic ways of RTS for wasm in unregisterised mode. - - - - - a6a82cdb by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: use targetSupportsRPaths predicate This commit changes the hostSupportsRPaths predicate to targetSupportsRPaths and use that to decide whether to pass RPATH-related link-time options. It's not applied to stage0, we should just use the default link-time options of stageBoot ghc. - - - - - f232c872 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: disable internal-interpreter of ghc library when cross compiling This commit disable the internal-interpreter flag of ghc library when cross compiling, only external interpreter works in such cases. - - - - - 577c1819 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: enable internal-interpreter for ghc-bin stage0 This commit enables internal-interpreter flag for ghc-bin even when compiling stage0, as long as target supports ghci. It enables ghci functionality for cross targets that support ghci, since cross ghc-bin is really stage0. - - - - - c247f2ee by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: fix CFLAGS for gmp shared objs on wasm This commit adds -fvisibility=default to CFLAGS of gmp when building for wasm. This is required to generate the ghc-bignum shared library without linking errors. Clang defaults to -fvisibility=hidden for wasm targets, which will cause issues when a symbol is expected to be exported in a shared library but without explicit visibility attribute annotation. - - - - - 775410fd by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: re-enable PIC for gmp on wasm This commit re-enables --with-pic=yes configuration option of gmp when building for wasm, given we're about to include support for shared libraries, TH and ghci. - - - - - b45080a3 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: add the host_fully_static flavour transformer This commit adds the host_fully_static flavour transformer to hadrian, which ensures stage0 is fully statically linked while still permitting stage1 libdir to contain shared libraries. This is intended to be used by the wasm backend to build portable linux bindists that contain wasm shared libraries. - - - - - 5043507c by Cheng Shao at 2024-10-17T16:41:18+00:00 ci: update wasm jobs configuration This commit bumps ci-image revision to use updated wasm toolchain, and use host_fully_static instead of fully_static for wasm jobs so to ensure wasm shared libraries can be properly built. - - - - - 2956a3f7 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian/testsuite: implement config.cross logic This commit implements the config.cross field in the testsuite driver. It comes from the "cross compiling" ghc info field for both in-tree/out-of-tree GHC, and is an accurate predicate of whether we're cross-compiling or not (compared to the precense of target emulator), and is useful to implement predicates to assert the precense of internal interpreter (only available on non-cross GHC) for tests that do require it (e.g. plugins). - - - - - 8c74a0ed by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian/compiler: implement targetRTSLinkerOnlySupportsSharedLibs This patch implements the targetRTSLinkerOnlySupportsSharedLibs predicate in hadrian. Its definition in hadrian is the single source of truth, and the information propagates to ghc settings file, ghc driver and testsuite driver. It is used in various places to ensure dynamic dependency is selected when the target RTS linker only supports loading dynamic code. - - - - - b4c3c340 by Cheng Shao at 2024-10-17T16:41:18+00:00 testsuite: don't use host cpu features when testing cross ghc This patch disables CPU feature detection logic when testing cross GHC, since those features don't make sense for the target anyway. - - - - - 3c21b696 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: implement & use req_plugins predicate This commit implements req_plugins predicate to indicate that the test requires plugin functionality. Currently this means cross GHC is disabled since internal-interpreter doesn't work in cross GHC yet. - - - - - 93b8af80 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: make use of config.interp_force_dyn This commit takes config.interp_force_dyn into consideration when setting up TH/ghci way flags. - - - - - 94673d41 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: bump T17572 timeout - - - - - 2b5efc2d by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: bump T22744 pre_cmd timeout - - - - - 45102e2a by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip terminfo_so for cross ghc - - - - - 05e40406 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: fix shared library size tests for cross ghc This commit fixes shared library size tests (e.g. array_so in testsuite/tests/perf/size/all.T) when testing cross ghc. Previously, if shared library file extension of host and target differs, those tests will fail with framework errors due to not finding the right files. - - - - - fa68f833 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip ghc api tests that attempt to spawn processes inside wasm This commit skips a few ghc api tests on wasm, since they would attempt to spawn processes inside wasm, which is not supported at all. - - - - - 1241c04e by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip T22840 due to broken -dtag-inference-checks on wasm - - - - - 78c8b900 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: ensure $(ghciWayFlags) can be overridden This commit revises boilerplate.mk in testsuite as well as a few other places, to ensure the tests that do make use of $(ghciWayFlags) can receive the right $(ghciWayFlags) from testsuite driver config. - - - - - 47989ecc by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: skip rdynamic on wasm - - - - - fefb4ea1 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: skip T2615 on wasm This commit marks T2615 as skip on wasm, given LD_* environment variables aren't supported on wasm anyway. - - - - - 77c79762 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: mark MultiLayerModulesTH_Make/MultiLayerModulesTH_OneShot as fragile on wasm - - - - - 69bb4745 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: fix T16180 on wasm This commit fixes T16180 on wasm once TH support is flipped on. The fix is simply adding right asm code for wasm. - - - - - 621c753d by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: fix -fexternal-interpreter flag for JS backend Previously, -fexternal-interpreter is broken for JS backend, since GHC would attempt to launch a non-existent ghc-iserv* executable. This commit fixes it by adjusting pattern matching order in setTopSessionDynFlags. - - - - - 80aa8983 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: use interpreterDynamic predicate in preloadLib This commit use the interpreterDynamic predicate in preloadLib to decide if we should do dynLoadObjs instead of loadObj. Previously we used hostIsDynamic which was only written with non-cross internal interpreter in mind. The testsuite is also adjusted to remove hard-wired -fPIC flag for cbits (doesn't work in i386 RTS linker in vanilla way, #25260) and properly pass ghc_th_way_flags to ghc. - - - - - 74411461 by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix Cmm dynamic CLabels for wasm This commit fixes the handling of dynamic CLabels for the wasm backend. Just do the simplest handling: preserve the original CLabel, both unreg/NCG backends can handle them properly without issue. - - - - - f6abaf13 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: add necessary compile-time flags for wasm PIC mode This commit adds necessary compile-time flags when compiling for wasm PIC mode, see added comment for detailed explanation. - - - - - 9745fcfb by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: add necessary link-time flags for wasm shared libs This commit adds necessary link-time flags for wasm shared libs, see added comments for detailed explanation. - - - - - 649aae00 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: enforce -fno-use-rpaths for wasm This commit ensures the GHC driver never passes any RPATH-related link-time flags on wasm, which is not supported at all. - - - - - 47baa904 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: ensure static archives are picked when linking static .wasm modules This commit ensures static archives are picked when linking .wasm modules which are supposed to be fully static, even when ghc may be invoked with -dynamic, see added comment for explanation. - - - - - fc3a5591 by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix dynamic_too_enable for targets that require dynamic libraries This commit fixes dynamic_too_enable for targets whose RTS linker can only load dynamic code. - - - - - 94ef949e by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix checkNonStdWay for targets that require dynamic libraries This commit fixes checkNonStdWay to ensure that for targets whose RTS linker can only load dynamic code, the dynamic way of object is selected. - - - - - 88e99248 by Cheng Shao at 2024-10-17T16:41:24+00:00 ghc-bin: enforce dynamic way when the target requires so This commit makes ghc-bin use dynamic way when it is doing interactive stuff on certain targets whose RTS linker can only handle dynamic code. - - - - - 549582ef by Cheng Shao at 2024-10-17T16:41:24+00:00 hadrian/ghci: add wasm dyld This commit adds the wasm dynamic linker implementation, as well as ghci logic to call it and hadrian logic to install it to the correct location. See the top-level note in utils/jsffi/dyld.mjs for more details. - - - - - b562e3a6 by Cheng Shao at 2024-10-17T16:41:29+00:00 driver: fix getGccSearchDirectory for wasm target This commit fixes getGccSearchDirectory logic for wasm target, ensures the correct search directory containing libc.so etc can be found by GHC. getGccSearchDirectory is also exported so it can be used elsewhere to obtain the wasi-sdk libdir and pass to the dyld script. - - - - - 2d6107dc by Cheng Shao at 2024-10-17T16:41:29+00:00 driver: add wasm backend iserv logic This commit adds wasm backend iserv logic to the driver, see added comments for explanation. - - - - - 61f5baa5 by Cheng Shao at 2024-10-17T16:41:29+00:00 compiler: add PIC support to wasm backend NCG This commit adds support for generating PIC to the wasm backend NCG. - - - - - 652e7239 by Cheng Shao at 2024-10-17T16:41:29+00:00 hadrian/compiler: flip on support for shared libs & ghci for wasm This commit flips on the support for shared libs and ghci for the wasm target, given all required support logic has been added in previous commits. - - - - - 74a1f681 by Cheng Shao at 2024-10-17T16:41:29+00:00 testsuite: flip on support for shared libs, TH & ghci for wasm This commit flips on support for shared libs, TH & ghci for wasm in the testsuite, given support has been landed in previous commits. - - - - - 525d451e by Cheng Shao at 2024-10-17T23:03:34-04:00 Revert "compiler: start deprecating cmmToRawCmmHook" This reverts commit 1c064ef1f3e1aa2afc996e962ad53effa99ec5f4. Turns out the GHC-WPC project does use it to observe Cmm in the pipeline, see #25363. - - - - - 5bcfefd5 by Cheng Shao at 2024-10-17T23:04:09-04:00 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. - - - - - eb67875f by Matthew Craven at 2024-10-18T12:18:35+00:00 Bump transformers submodule The svg image files mentioned in transformers.cabal were previously not checked in, which broke sdist generation. - - - - - 366a1109 by Matthew Craven at 2024-10-18T12:18:35+00:00 Remove reference to non-existent file in haddock.cabal - - - - - 826852e9 by Matthew Craven at 2024-10-18T12:18:35+00:00 Move tests T11462 and T11525 into tests/tcplugins - - - - - dbe27152 by Matthew Craven at 2024-10-18T12:18:35+00:00 Repair the 'build-cabal' hadrian target Fixes #23117. Fixes #23281. Fixes #23490. This required: * Updating the bit-rotted compiler/Setup.hs and its setup-depends * Listing a few recently-added libraries and utilities in cabal.project-reinstall * Setting allow-boot-library-installs to 'True' since Cabal now considers the 'ghc' package itself a boot library for the purposes of this flag Additionally, the allow-newer block in cabal.project-reinstall was removed. This block was probably added because when the libraries/Cabal submodule is too new relative to the cabal-install executable, solving the setup-depends for any package with a custom setup requires building an old Cabal (from Hackage) against the in-tree version of base, and this can fail un-necessarily due to tight version bounds on base. However, the blind allow-newer can also cause the solver to go berserk and choose a stupid build plan that has no business succeeding, and the failures when this happens are dreadfully confusing. (See #23281 and #24363.) Why does setup-depends solving insist on an old version of Cabal? See: https://github.com/haskell/cabal/blob/0a0b33983b0f022b9697f7df3a69358ee9061a89/cabal-install/src/Distribution/Client/ProjectPlanning.hs#L1393-L1410 The right solution here is probably to use the in-tree cabal-install from libraries/Cabal/cabal-install with the build-cabal target rather than whatever the environment happens to provide. But this is left for future work. - - - - - b3c00c62 by Matthew Craven at 2024-10-18T12:18:35+00:00 Revert "CI: Disable the test-cabal-reinstall job" This reverts commit 38c3afb64d3ffc42f12163c6f0f0d5c414aa8255. - - - - - a04959b8 by Daneel Yaitskov at 2024-10-19T09:34:15-04:00 base: speed up traceEventIO and friends when eventlogging is turned off #17949 Check the RTS flag before doing any work with the given lazy string. Fix #17949 Co-authored-by: Michael Peyton Jones <me at michaelpj.com> Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - eff16c22 by Matthew Pickering at 2024-10-19T21:55:55-04:00 ci: Add support for ONLY_JOBS variable to trigger any validation pipeline By setting the ONLY_JOBS variable to the name of the job (or multiple jobs), the resulting pipeline will include a validation job for that pipeline. For example - if you set ONLY_JOBS="x86_64-linux-ubuntu22_04-validate" then a ubuntu22_04 job will be included in the validation pipeline. This is useful for testing specific jobs. Fixes #25332 - - - - - 280b6278 by Zubin Duggal at 2024-10-19T21:56:31-04:00 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit d83f5bd730a8aef37d8a38b3560590d9798f8e45) - - - - - 25edf849 by Alan Zimmerman at 2024-10-19T21:57:08-04:00 EPA: Remove [AddEpAnn] Commit 4 EPA: Remove [AddEpAnn] from DataDecl This is quite a big change. The most important part is moving the annotations into HsDataDefn, using a specific annotation data type. It has a knock-on to everything that uses HsDataDefn EPA: Remove [AddEpAnn] for FunDep EPA: Remove [AddEpann] from FamilyDecl EPA: Remove [AddEpAnn] From InjectivityAnn EPA: Remove [AddEpAnn] from DefaultDecl EPA: Remove [AddEpAnn] from RuleDecls EPA: Remove [AddEpAnn] from Warnings - - - - - d5f42045 by Luite Stegeman at 2024-10-20T16:34:47-04:00 Interpreter: Add locking for communication with external interpreter This adds locking to communication with the external interpreter to prevent concurrent tasks interfering with each other. This fixes Template Haskell with the external interpreter in parallel (-j) builds. Fixes #25083 - - - - - d6bfea76 by Matthew James Kraai at 2024-10-20T16:35:29-04:00 Use monospace font for "Either a b" in fmap docs The documentation for fmap shows "`Either a b`" in the default font instead of showing "Either a b" in a monospace font. - - - - - 4bc7f9c8 by Luite Stegeman at 2024-10-20T16:36:15-04:00 Parser: remove non-ASCII characters from Parser.y Non-ASCII characters in the source causes a problem with the default Haskell Language Server setup in VSCode. Two characters seems to have been left in by accident. Workaround for #25396 - - - - - 7f61ed4e by Alan Zimmerman at 2024-10-21T06:39:45-04:00 EPA: Remove [AddEpAnn] Commit 5 EPA: Remove [AddEpAnn] from AnnPragma EPA: Remove [AddEpAnn] From ForeignDecl EPA: Remove [AddEpAnn] from RoleAnnotDecl EPA: Remove [AddEpAnn] from StandaloneKindSig EPA: Remove [AddEpAnn] From HsDeriving EPA: Remove [AddEpAnn] from ConDeclField EPA: Remove [AddEpAnn] from ConDeclGADT EPA: Remove [AddEpAnn] from ConDeclH98 EPA: Remove [AddEpAnn] from ClsInstDecl - - - - - f8694fe7 by Cheng Shao at 2024-10-21T06:40:21-04:00 wasm: bump dyld v8 heap size limit This patch adds `--max-old-space-size=8192` to wasm dyld shebang arguments to bump V8 heap size limit. The default limit (`heap_size_limit` returned by `v8.getHeapStatistics()`) is dynamically determined and a bit too low under certain workloads, and V8 would waste too much CPU time to garbage collect old generation heap more aggressively. Bumping the limit to 8G doesn't imply dyld would really take that much memory at run-time, but it lessens V8 heap stress significantly. - - - - - d328d173 by Luite Stegeman at 2024-10-21T12:39:18+00:00 Add requestTickyCounterSamples to GHC.Internal.Profiling This allows the user to request ticky counters to be written to the eventlog at specific times. See #24645 - - - - - 71765b1d by Simon Peyton Jones at 2024-10-21T20:55:00-04:00 Move defaulting code into a new module GHC.Tc.Solver had reached 4,000 lines -- although quite a lot of them are comments. This MR * Adds the new module GHC.Tc.Solver.Default, which has all the complex, but well modularised, defaulting code * Moves a bit of code from GHC.Tc.Solver into the existing GHC.Tc.Solver.Solve. Notably solveWanteds and simplifyWantedsTcM, which are called from GHC.Tc.Solver.Default It's a pure refactor. No code changes. - - - - - a398227b by Simon Peyton Jones at 2024-10-21T20:55:00-04:00 Improve the generalisation code in Solver.simplifyInfer The code in `decideQuantification` has become quite complicated. This MR straightens it out, adds a new Note, and on the way fixes #25266. See especially Note [decideAndPromoteTyVars] which is is where all the action happens in this MR. - - - - - 148059fe by Andrzej Rybczak at 2024-10-21T20:55:40-04:00 Adjust catches to properly rethrow exceptions https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13302 implemented exception rethrowing proposal, but it didn't adjust `catches`. This fixes it. - - - - - 25121dbc by doyougnu at 2024-10-22T09:38:18-04:00 linker: add --optimistic-linking flag This patch adds: - the --optimistic-linking flag which binds unknown symbols in the runtime linker to 0xDEADBEEF instead of exiting with failure - The test T25240 which tests these flags using dead code in the FFI system. - closes #25240 This patch is part of the upstreaming haskell.nix patches project. - - - - - f19e076d by doyougnu at 2024-10-22T09:38:18-04:00 ghc-internal: hide linkerOptimistic in MiscFlags - - - - - edc02197 by Cheng Shao at 2024-10-22T09:38:54-04:00 hadrian: fix bindist executable wrapper logic for cross targets This commit fixes an oversight of hadrian wrapper generation logic: when doing cross compilation, `wrapper` is called on executable names with cross prefix, therefore we must use `isSuffixOf` when matching to take the cross prefix into account. Also add missing cross prefix to ghci wrapper content and fix hsc2hs wrapper logic. - - - - - edf3bdf5 by Andreas Klebinger at 2024-10-22T16:30:42-04:00 mkTick: Push ticks through unsafeCoerce#. unsafeCoerce# doesn't exist at runtime so we should treat it like a Cast for the purpose of mkTick. This means if we have `{-# SCC foo #-} (unsafeCoerce# trivial_expr))` we now push the scope part of the cost centre up to `trivial_expr` at which point we can discard it completely if the expression is trivial enough. This fixes #25212. - - - - - 1bdb1317 by Cheng Shao at 2024-10-22T16:31:17-04:00 hadrian: enable late-CCS for perf flavour as well This patch enables late-CCS for perf flavour so that the testsuite can pass for perf as well. Fixes #25308. - - - - - fde12aba by Cheng Shao at 2024-10-22T16:31:54-04:00 hadrian: make sure ghc-bin internal-interpreter is disabled for stage0 when not cross compiling This patch disables internal-interpreter flag for stage0 ghc-bin when not cross compiling, see added comment for explanation. Fixes #25406. - - - - - 6ab8d751 by ignatiusm at 2024-10-24T01:23:35-04:00 Improve heap overflow exception message (#25198) Catch heap overflow exceptions and suggest using `+RTS -M<size>`. Fix #25198 - - - - - b3f7fb80 by Rodrigo Mesquita at 2024-10-24T01:24:12-04:00 determinism: Interface re-export list det In 'DocStructureItem' we want to make sure the 'Avails' are sorted, for interface file determinism. This commit introduces 'DetOrdAvails', a newtype that should only be constructed by sorting Avails with 'sortAvails' unless the avails are known to be deterministically ordered. This newtype is used by 'DocStructureItem' where 'Avails' was previously used to ensure the list of avails is deterministically sorted by construction. Note: Even though we order the constructors and avails in the interface file, the order of constructors in the haddock output is still determined from the order of declaration in the source. This was also true before, when the list of constructors in the interface file <docs> section was non-deterministic. Some haddock tests such as "ConstructorArgs" observe this (check the order of constructors in out/ConstructorArgs.html vs src/ConstructorArgs.hs vs its interface file) The updated tests are caused by haddock corners where the order in the source is not preserved (and was non-deterministic before this PR): * Module header in the latex backend * Re-export of pattern synonyms associated to a datatype (#25342) Fixes #25304 - - - - - e39c8c99 by Rodrigo Mesquita at 2024-10-24T01:24:12-04:00 Revert "ci: Allow abi-test to fail." After #25304, the abi-test with interface and object determinism succeeds. This reverts commit 7b37afc9f3e79559055488998ee73187886a0e00. - - - - - 7b1b0c6d by Alan Zimmerman at 2024-10-24T13:07:02-04:00 EPA: reduce [AddEpann] in AnnList Remove it from the `al_rest` field, and make `AnnList` parameterized on a type to be used in `al_rest`, for the various use cases. - - - - - 4a00731e by Rodrigo Mesquita at 2024-10-24T13:07:38-04:00 Fix -fobject-determinism flag definition The flag should be defined as an fflag to make sure the -fno-object-determinism flag is also an available option. Fixes #25397 - - - - - 55e4b9f2 by Sebastian Graf at 2024-10-25T07:01:54-04:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - 9f57c96d by Sebastian Graf at 2024-10-25T07:01:54-04:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * I reworked the whole narrative around "Tag inference". It's now called "EPT enforcement" and I recycyled the different overview Notes into `Note [EPT enforcement]`. * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Compiler perf generally improves, sometimes drastically: Baseline Test Metric value New value Change -------------------------------------------------------------------------------- ManyConstructors(normal) ghc/alloc 3,629,760,116 3,711,852,800 +2.3% BAD MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,502,735,440 2,565,282,888 +2.5% BAD T12707(normal) ghc/alloc 804,399,798 791,807,320 -1.6% GOOD T17516(normal) ghc/alloc 964,987,744 1,008,383,520 +4.5% T18140(normal) ghc/alloc 75,381,152 49,860,560 -33.9% GOOD T18698b(normal) ghc/alloc 232,614,457 184,262,736 -20.8% GOOD T18923(normal) ghc/alloc 62,002,368 58,301,408 -6.0% GOOD T20049(normal) ghc/alloc 75,719,168 70,494,368 -6.9% GOOD T3294(normal) ghc/alloc 1,237,925,833 1,157,638,992 -6.5% GOOD T9233(normal) ghc/alloc 686,490,105 635,166,688 -7.5% GOOD geo. mean -0.7% minimum -33.9% maximum +4.5% I looked at T17516. It seems we do a few more simplifier iterations and end up with a larger program. It seems that some things inline more, while other things inline less. I don't see low-hanging fruit. I also looked at MultiLayerModulesTH_OneShot. It appears we generate a strange join point in the `getUnique` method of `Uniquable GHC.Unit.Types.Module` that should better call-site inline, but does not. Perhaps with !11492. NoFib does not seem affected much either: +-------------------------------++--+------------+-----------+---------------+-----------+ | || | base/ | std. err. | T20749/ (rel) | std. err. | +===============================++==+============+===========+===============+===========+ | spectral/last-piece || | 7.263e8 | 0.0% | +0.62% | 0.0% | +===============================++==+============+===========+===============+===========+ | geom mean || | +0.00% | | | | +-------------------------------++--+------------+-----------+---------------+-----------+ I had a look at last-piece. Nothing changes in stg-final, but there is a bit of ... movement around Data.Map.insert's use of GHC.Exts.lazy that is gone in stg-final. Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> Metric Decrease: T12707 T18140 T18698b T18923 T19695 T20049 T3294 T9233 T21839c Metric Increase: ManyConstructors MultiLayerModulesTH_OneShot - - - - - 0225249a by Simon Peyton Jones at 2024-10-25T07:02:32-04:00 Some renaming This is a pure refactor, tidying up some inconsistent naming: isEqPred --> isEqClassPred isEqPrimPred --> isEqPred isReprEqPrimPred --> isReprEqPred mkPrimEqPred --> mkNomEqPred mkReprPrimEqPred --> mkReprEqPred mkPrimEqPredRold --> mkEqPredRole Plus I moved mkNomEqPred, mkReprEqPred, mkEqPredRolek from GHC.Core.Coercion to GHC.Core.Predicate where they belong. That means that Coercion imports Predicate rather than vice versa -- better. - - - - - 15a3456b by Ryan Hendrickson at 2024-10-25T07:02:32-04:00 compiler: Fix deriving with method constraints See Note [Inferred contexts from method constraints] Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - dbc77ce8 by Alan Zimmerman at 2024-10-25T18:20:13+01:00 EPA: Remove AddEpann commit 7 EPA: Remove [AddEpAnn] from HYPHEN in Parser.y The return value is never used, as it is part of the backpack configuration parsing. EPA: Remove last [AddEpAnn] usages Remove residual usage in GHC. It is still used - In haddock TTG extension point definitions (to be removed) - Some check-exact residual, to be removed - Comments around DisambECP in PostProcess EPA: Clean up [AddEpAnn] from check-exact There is one left, to be cleaned up when we remove AddEpann itself EPA: Remove [AddEpAnn] from haddock The TTG extension points need a value, it is not critical what that value is, in most cases. EPA: Remove AddEpAnn from HsRuleAnn EPA: Remove AddEpAnn from HsCmdArrApp - - - - - 23ddcc01 by Simon Peyton Jones at 2024-10-26T12:44:34-04:00 Fix optimisation of InstCo It turned out (#25387) that the fix to #15725 was not quite right: commit 48efbc04bd45d806c52376641e1a7ed7278d1ec7 Date: Mon Oct 15 10:25:02 2018 +0200 Fix #15725 with an extra Sym Optimising InstCo is quite subtle, and the invariants surrounding the LiftingContext in the coercion optimiser were not stated explicitly. This patch refactors the InstCo optimisation, and documents these invariants. See * Note [Optimising InstCo] * Note [The LiftingContext in optCoercion] I also did some refactoring of course: * Instead of a Bool swap-flag, I am not using GHC.Types.Basic.SwapFlag * I added some invariant-checking the coercion-construction functions in GHC.Core.Coercion.Opt. (Sadly these invariants don't hold during typechecking, becuase the types are un-zonked, so I can't put these checks in GHC.Core.Coercion.) - - - - - 589fea7f by Cheng Shao at 2024-10-27T05:36:38-04:00 ghcid: use multi repl for ghcid - - - - - d52a0475 by Andrew Lelechenko at 2024-10-27T05:37:13-04:00 documentation: add motivating section to Control.Monad.Fix - - - - - 301c3b54 by Cheng Shao at 2024-10-27T05:37:49-04:00 wasm: fix safari console error message related to import("node:timers") This patch fixes the wasm backend JSFFI prelude script to avoid calling `import("node:timers")` on non-deno hosts. Safari doesn't like it and would print an error message to the console. Fixes https://gitlab.haskell.org/ghc/ghc-wasm-meta/-/issues/13. - - - - - 9f02dfb5 by Simon Peyton Jones at 2024-10-27T15:10:08-04:00 Add a missing tidy in UnivCo We were failing to tidy the argument coercions of a UnivCo, which led directly to #25391. The fix is, happily, trivial. I don't have a small repro case (it came up when building horde-ad, which uses typechecker plugins). It should be possible to make a repro case, by using a plugin (which builds a UnivCo) but I decided it was not worth the bother. The bug is egregious and easily fixed. - - - - - 853050c3 by Andrew Lelechenko at 2024-10-27T15:10:44-04:00 Bump text submodule to 2.1.2 - - - - - 90746a59 by Andrew Lelechenko at 2024-10-27T15:10:44-04:00 hadrian: allow -Wunused-imports for text package - - - - - 8a6691c3 by Alan Zimmerman at 2024-10-27T19:44:48+00:00 EPA: Remove AddEpAnn Commit 8/final EPA: Remove AddEpAnn from AnnList EPA: Remove AddEpAnn from GrhsAnn This is the last actual use EPA: Remove NameAdornment from NameAnn Also rework AnnContext to use EpToken, and AnnParen EPA: Remove AddEpAnn. Final removal There are now none left, except for in a large note/comment in PostProcess, describing the historical transition to the disambiguation infrastructure - - - - - d5e7990c by Alan Zimmerman at 2024-10-28T21:41:05+00:00 EPA: Remove AnnKeywordId. This was used as part of AddEpAnn, and is no longer needed. Also remove all the haddock comments about which of are attached to the various parts of the AST. This is now clearly captured in the appropriate TTG extension points, and the `ExactPrint.hs` file. - - - - - e08b8370 by Serge S. Gulin at 2024-10-29T23:17:01-04:00 JS: Re-add optimization for literal strings in genApp (fixes #23479) Based on https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10588/ Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> Co-authored-by: Danil Berestov <goosedb at yandex.ru> ------------------------- Metric Decrease: T25046_perf_size_gzip size_hello_artifact size_hello_artifact_gzip size_hello_unicode size_hello_unicode_gzip ------------------------- - - - - - e3496ef6 by Cheng Shao at 2024-10-29T23:17:37-04:00 compiler: remove unused hscDecls/hscDeclsWithLocation This patch removes unused `hscDecls`/`hscDeclsWithLocation` functions from the compiler, to reduce maintenance burden when doing refactorings related to ghci. - - - - - b1eed26f by Cheng Shao at 2024-10-29T23:18:13-04:00 testsuite: add T25414 test case marked as broken This commit adds T25414 test case to demonstrate #25414. It is marked as broken and will be fixed by the next commit. - - - - - e70009bc by Cheng Shao at 2024-10-29T23:18:13-04:00 driver: fix foreign stub handling logic in hscParsedDecls This patch fixes foreign stub handling logic in `hscParsedDecls`. Previously foreign stubs were simply ignored here, so any feature that involve foreign stubs would not work in ghci (e.g. CApiFFI). The patch reuses `generateByteCode` logic and eliminates a large chunk of duplicate logic that implements Core to bytecode generation pipeline here. Fixes #25414. - - - - - 1d7cd7fe by Andreas Klebinger at 2024-10-30T19:14:28-04:00 Add since tag for -fwrite-if-compression in user guide. Partial fix for #25395 - - - - - b349fd1b by Alan Zimmerman at 2024-10-30T19:15:04-04:00 EPA: Remove some unused functions - - - - - f859d61c by Alan Zimmerman at 2024-10-30T19:15:04-04:00 EPA: use explicit vertical bar token for ExplicitSum / SumPat - - - - - 721ac00d by Ben Gamari at 2024-10-31T08:37:38-04:00 rts/Disassembler: Fix encoding of BRK_FUN instruction The offset of the CC field was not updated after the encoding change in b85b11994e0130ff2401dd4bbdf52330e0bcf776. Fix this. Fixes #25374. - - - - - 0bc94360 by Alan Zimmerman at 2024-10-31T08:38:15-04:00 EPA: Bring in last EpToken usages For import declarations, NameAnnCommas and NPlusKPat. And remove anchor, it is the same as epaLocationRealSrcSpan. - - - - - 0b11cdc0 by sheaf at 2024-10-31T08:38:55-04:00 Assert that ctEvCoercion is called on an equality Calling 'ctEvCoercion' on non-equality constraints is always incorrect. We add an assertion to this function to detect such cases; for example a type-checking plugin might erroneously do this. - - - - - ea458779 by doyougnu at 2024-11-01T18:11:33-04:00 ghc-internal: strict, unboxed src loc ranges - closes: #20449 - See CLC proposal: #55 - - - - - 778ac793 by Kazuki Okamoto at 2024-11-01T18:12:13-04:00 No haddock markup in doctest line - - - - - cf0deeaf by Andreas Klebinger at 2024-11-02T17:54:52-04:00 Reword -fexpose-overloaded-unfoldings docs. This should make them slightly clearer. Fixes #24844 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> - - - - - 1c21e7d4 by Andreas Klebinger at 2024-11-02T17:55:29-04:00 Compile T25062 simd tests even if we can't run them. Helps avoid them being utterly broken. Fixes #25341 - - - - - 573cad4b by Cheng Shao at 2024-11-02T17:56:04-04:00 Remove unused USE_REPORT_PRELUDE code paths from the tree This patch removes unused `USE_REPORT_PRELUDE` code paths from the tree. They have been present since the first git revision 4fb94ae5e5d632748fa2e6c35e259eccc5a1a3f4, and might have been useful for debugging purposes many years ago, but these code paths are never actually built. Removing these ease maintenance of relevant modules in the future, and also allows us to get rid of `CPP` extension in those modules as a nice byproduct. - - - - - 97f600c6 by Hassan Al-Awwadi at 2024-11-04T15:52:12+00:00 Refactored BooleanFormula to be in line with TTG (#21592) There are two parts to this commit. * We moved the definition of BooleanFormula over to L.H.S.BooleanFormula * We parameterized the BooleanFormula over the pass The GHC specific details of BooleanFormula remain in Ghc.Data.BooleanFormula. Because its parameterized over the pass its no longer a functor or traversable, but we defined bfMap and bfTraverse for the cases where we needed fmap and traverse originally. Most other changes are just churn. ------------------------- Metric Decrease: MultiLayerModulesTH_OneShot ------------------------- - - - - - d4fd3580 by Andreas Klebinger at 2024-11-05T07:36:16-05:00 ghc-heap: Fix incomplete selector warnings. Use utility functions instead of selectors to read partial attributes. Part of fixing #25380. - - - - - fdd9f62a by Peter Trommler at 2024-11-05T07:36:51-05:00 PPC NCG: Implement fmin and fmax - - - - - 8e217256 by Mike Pilgrem at 2024-11-07T04:34:20-05:00 Re CLC #293 - Don't specify Data.List.NonEmpty in terms of partial See https://github.com/haskell/core-libraries-committee/issues/293 `List.init` had already been driven out of `tails1` by 21fc180bec93d964a7f4ffdf2429ef6f74b49ab6 but this specification also avoided partial `fromList`, so I preferred it. The `changelog.md` for `base` is updated, with an entry added under `base-4.22.0.0`. - - - - - 346e4cd1 by Zubin Duggal at 2024-11-07T04:34:57-05:00 release: copy zip files into the correct directory Fixes #25446 - - - - - bbdbe225 by Zubin Duggal at 2024-11-07T04:34:57-05:00 release: Sign .gz bindists too Fixes #25447 - - - - - 0c722e14 by Hécate Kleidukos at 2024-11-07T04:35:37-05:00 hadrian: Enforce the usage of GHC >=9.8.1 for ghci-multi GHC 9.6 no good when it comes to multi-repl stuff, despite being well within the range of n-2 releases for bootstrapping, when the script was adapted to load haddock, in !12851 - - - - - d8f8a1c3 by Sylvain Henry at 2024-11-07T19:27:46-05:00 Handle the special ghc-prim:GHC.Prim module in the compiler Before this patch, some custom hacks were necessary in ghc-prim's Setup.hs to register the GHC.Prim (virtual) module and in Hadrian to generate haddocks properly. In this patch we special-case this module in the compiler itself instead (which it already is, see ghcPrimIface in GHC.Iface.Load). From Cabal/Hadrian's perspective GHC.Prim is now just a normal autogenerated module. This simplification is worthwhile on its own. It was found while looking into the work needed for #24453 which aims to merge ghc-prim, ghc-bignum, and ghc-internal. It's also one step closer to remove ghc-prim's custom setup. - - - - - a55adc8e by Cheng Shao at 2024-11-07T19:28:22-05:00 Clean up obsolete CPP guarded code paths from the tree This patch cleans up obsolete CPP guarded code paths from the tree. The minimum supported boot GHC version is 9.6, and all the pre-9.6 era code paths can be removed. - - - - - 9ede97f3 by Cheng Shao at 2024-11-07T19:28:58-05:00 Remove obsolete executable wrappers from the tree The executable wrappers are handled by hadrian and bindist Makefile. The various .wrapper scripts in the tree are unused since removal of Make build system, so this patch removes them all. - - - - - 7d42b2df by tristian at 2024-11-07T19:29:40-05:00 TcRnDuplicateDecls now suggests to use the DuplicateRecordFields extension. Fixes: !24627 - - - - - e56ed179 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: normalise some versions in callstacks (cherry picked from commit f230e29f30d0c1c566d4dd251807fcab76a2710e) - - - - - a28fc903 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: use -fhide-source-paths to normalise some backpack tests (cherry picked from commit b19de476bc5ce5c7792e8af1354b94a4286a1a13) - - - - - ed16d303 by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite/haddock: strip version identifiers and unit hashes from html tests (cherry picked from commit fbf0889eadc410d43dd5c1657e320634b6738fa5) - - - - - e45e5836 by Zubin Duggal at 2024-11-11T15:16:36+05:30 haddock: oneshot tests can drop files if they share modtimes. Stop this by including the filename in the key. Ideally we would use `ghc -M` output to do a proper toposort Partially addresses #25372 (cherry picked from commit e78c7ef96e395f1ef41f04790aebecd0409b92b9) - - - - - 9104e6eb by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: fix normalisation of T9930fail so that it doesn't get tripped up by ghc executable (ARGV[0]) differences (cherry picked from commit a79a587e025d42d34bb30e115fc5c7cab6c1e030) - - - - - 2c31264a by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: normalise windows file seperators (cherry picked from commit f858875e03b9609656b542aaaaff85ad0a83878a) - - - - - 2807f91b by Zubin Duggal at 2024-11-11T15:21:30+05:30 testsuite: Also match <VERSION> placeholders when normalising callsites - - - - - c02add17 by Ben Gamari at 2024-11-12T01:22:11-05:00 configure: Check version number validity Here we verify the previously informal invariant that stable release version numbers must have three components, preventing costly failed releases. Specifically, the check fails in the following scenarios: * `version=9.13` while `RELEASE=YES` since this would imply a release made from an unstable branch * `version=9.13.0` since unstable versions should only have two components * `version=9.12` since this has the wrong number of version components for a stable branch Fixes #25390. - - - - - 747fd322 by Teo Camarasu at 2024-11-12T01:22:49-05:00 docs: link to #14474 in the template-haskell docs - - - - - 6d96bb62 by Zubin Duggal at 2024-11-12T01:23:25-05:00 testsuite: normalise execvp vs exec differences in process tests Fixes #25431 - - - - - 502e6711 by Torsten Schmits at 2024-11-12T01:24:01-05:00 fix test lint that accumulated while the checks were broken I didn't fix the issues flagged by the #ifdef linter because it were so many that it seemed like the rule has become obsolete. - - - - - 223a4cb5 by Torsten Schmits at 2024-11-12T01:24:02-05:00 test driver: fix file collection for regex linters When a testsuite linter is executed with the `tracked` strategy, the driver runs `git ls-tree` to collect eligible files. This appears to have ceased producing any paths – `ls-tree` restricts its results to the current working directory, which is `testsuite/tests/linters` in this case. As a quick fix, this patch changes the working directory to match expectations. - - - - - 9ad9ac63 by Alan Zimmerman at 2024-11-12T01:24:39-05:00 EPA: Capture location of '_' for wild card type binder And keep track of promotion status in HsExplicitTupleTy, so the round-trip ppr test works for it. Updates Haddock output too, using the PromotionFlag in HsExplicitTupleTy. Closes #25454 - - - - - c37b96fa by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix setImmediate() implementation for Cloudflare Workers This patch fixes setImmediate() implementation for Cloudflare Workers in the wasm backend's js prelude script. Cloudflare Workers doesn't support the MessageChannel API, and we use a setTimeout() based fallback implementation in this case. - - - - - bea8ea4c by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix FinalizationRegistry logic for Cloudflare Workers This patch fixes FinalizationRegistry related logic for Cloudflare Workers in wasm backend js post linker. Cloudflare Workers doesn't support FinalizationRegistry, in this case we use a dummy implementation that doesn't do anything. - - - - - 00d551bf by Cheng Shao at 2024-11-13T08:48:21-05:00 Remove obsolete cross-port script This patch removes the obsolete cross-port script in the tree. The script was based on the legacy Make build system which has been pruned from the tree long ago. For hadrian, proper support for two-stage bootstrapping onto a new unsupported platform is a work in progress in !11444. - - - - - 75a2eae4 by Cheng Shao at 2024-11-13T08:48:58-05:00 hadrian: fix bindist makefile for wasm32-wasi target This patch fixes one incoherent place between bindist makefile and hadrian logic: I forgot to include wasi/wasm32 in OsSupportsGHCi/ArchSupportsGHCi as well. And this results in incorrect settings file generated after installing the bindist, and "Use interpreter"/"Have interpreter" fields incorrectly have "NO" values where they should be "YES" like --info output of in-tree version. - - - - - 0614abef by Alan Zimmerman at 2024-11-13T08:49:34-05:00 EPA: Correctly capture leading semis in decl list Closes #25467 - - - - - 00d58ae1 by Sebastian Graf at 2024-11-13T15:21:23-05:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. - - - - - 93233a66 by Ben Gamari at 2024-11-13T15:21:59-05:00 boot: Do not attempt to update config.sub While Apple ARM hardware was new we found that the autoconf scripts included in some boot packages were too old. As a mitigation for this, we introduced logic in the `boot` script to update the `config.sub` with that from the GHC tree. However, this causes submodules which have `config.sub` committted to appear to be dirty. This is a considerable headache. Now since `config.sub` with full platform support is more common we can remove `boot`'s `config.sub` logic. Fixes #19574. - - - - - fa66fa64 by Ryan Scott at 2024-11-14T19:05:00-05:00 Add regression test for #16234 Issue #16234 was likely fixed by !9765. This adds a regression test to ensure that it remains fixed. Fixes #16234. - - - - - bfe64df8 by Matthew Pickering at 2024-11-14T19:05:36-05:00 ghc-internal: Update to Unicode 16 This patch updates the automatically generated code for querying unicode properties to unicode 16. Fixes #25402 - - - - - 1fd83f86 by Ben Gamari at 2024-11-14T19:06:13-05:00 configure: Accept happy-2.1.2 happy-2.1 was released in late Oct 2024. I have confirmed that master bootstraps with it. Here we teach configure to accept this tool. Fixes #25438. - - - - - aa58fc5b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Tighten up invariants of PACK - - - - - 8aa4c10a by Ben Gamari at 2024-11-14T19:06:49-05:00 testsuite: Fix badly escaped literals Use raw string literals to ensure that `\s` is correctly interpreted as a character class. - - - - - 0e084029 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Improve documentation of SLIDE bytecode instruction - - - - - 9bf3663b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Assert that TEST*_P discriminators are valid - - - - - 1f668511 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Improve documentation of TEST*_P instructions - - - - - 59e0a770 by Cheng Shao at 2024-11-14T19:07:25-05:00 misc: improve clangd compile_flags.txt flags This patch improves the compile_flags.txt config used to power clangd for the rts C codebase. The flags in the file are sampled & deduped from a real stage1 build with clang-19 and vastly improves the IDE accuracy when hacking the rts. For maximum code coverage under the default settings, compile_flags.txt defaults to threaded+profiled+dynamic+debug way. This does not mean profdyn needs to be actually built in _build/stage1 for IDE to work. To activate IDE for other RTS ways, simply remove one of the -D flags at the end of compile_flags.txt and restart clangd. - - - - - c2c562e0 by Ben Gamari at 2024-11-14T19:08:01-05:00 testsuite: Don't consider untracked files in dirtiness check Considering trees containing untracked files as dirty is a bridge too far. The chance of an untracked file significantly affecting measured performanced metrics is quite small whereas not collecting measurements is quite inconvenient for some workflows. We now ignore untracked files in the dirtiness check. Fixes #25471. - - - - - ed2ed6c5 by Cheng Shao at 2024-11-14T19:08:37-05:00 testsuite: add regression test T25473 This commit adds regression test T25473 marked as broken due to #25473. It will be fixed in the subsequent commit. - - - - - bd0a8b7e by Cheng Shao at 2024-11-14T19:08:37-05:00 wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. - - - - - f1b0bc32 by Ben Gamari at 2024-11-14T19:09:13-05:00 rts/linker: Make FreeBSD declarations proper prototypes The iconv declarations for FreeBSD were previously not prototypes, leading to warnings. - - - - - 086cbbc1 by Ben Gamari at 2024-11-14T19:09:13-05:00 base: Drop redundant import in FreeBSD ExecutablePath implementation - - - - - 79ecd199 by Ben Gamari at 2024-11-14T19:09:13-05:00 compiler: Fix partial selector warnings in GHC.Runtime.Heap.Inspect - - - - - 1acb73bf by Andrew Lelechenko at 2024-11-15T06:10:47-05:00 gitlab: mention CLC in MR template - - - - - 8f2e0832 by Ben Gamari at 2024-11-15T06:11:24-05:00 rts: Allow use of GNU-stack notes on FreeBSD Previously we gated use of GNU-style non-executable stack notes to only apply on Linux. However, these are also supported by FreeBSD, which also uses ELF. Fix this. Fixes #25475. - - - - - 2c427cb0 by Ben Gamari at 2024-11-16T05:27:40-05:00 rts: Fix EINTR check in timerfd ticker When `poll` failed we previously checked that `errno == -EINTR` to silence the failure warning. However, this is wrong as `errno` values are generally not negated error codes (in contrast to many system call results, which is likely what the original author had in mind). Fixes #25477. - - - - - a0fa4941 by Ben Gamari at 2024-11-16T05:28:16-05:00 rts: Increase gen_workspace alignment to 128 bytes on AArch64 Increase to match the 128-byte cache-line size of Apple's ARMv8 implementation. Closes #25459. - - - - - 142d8afa by Ben Gamari at 2024-11-16T16:20:47-05:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - b7a146e5 by Ben Gamari at 2024-11-16T16:20:47-05:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - ddb7afa6 by Ben Gamari at 2024-11-16T16:21:23-05:00 users guide: Mention language extensions in equality constraints discussion As suggested in #24127, mention the language extensions necessary for usage of equality constriants in their documentation. Closes #24127. - - - - - 36133dac by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/9.14.1-notes: Fix list syntax - - - - - 888de658 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/debug-info: Fix duplicate flag descriptions - - - - - f120e427 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide: Fix reference to 9.14.1 release notes - - - - - 8e975032 by Ben Gamari at 2024-11-16T16:21:59-05:00 Introduce GHC.Tc.Plugin.lookupTHName This makes it significantly more convenient (and less GHC-version-dependent) to resolve a template-haskell name into a GHC Name. As proposed in #24741. - - - - - a0e168ec by ARATA Mizuki at 2024-11-16T16:22:40-05:00 x86 NCG SIMD: Lower packFloatX4#, insertFloatX4# and broadcastFloatX4# to SSE1 instructions Fixes #25441 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 3936bf1b by sheaf at 2024-11-16T16:23:22-05:00 X86 NCG: allow VXOR at scalar floating-point types The NCG can emit VXOR instructions at scalar floating-point types, but the pretty-printer would panic instead of emitting the appropriate VXORPS/VXORPD instructions. This patch rectifies that oversight. Fixes #25455 - - - - - d9dff93a by Ben Gamari at 2024-11-16T16:23:58-05:00 rts: Fix platform-dependent pointer casts Previously we had unnecessary (and incorrect) platform-dependent casts to turn `OSThreadIds`s into a integer. We now just uniformly cast first to a `uintptr_t` (which is always safe, regardless of whether `OSThreadId` is a pointer), and then cast to the desired integral type. This fixes a warning on musl platforms. - - - - - 6d95cdb8 by Ben Gamari at 2024-11-16T16:24:34-05:00 testsuite: Mark encoding004 as broken on FreeBSD Due to #22003, CP936 fails to roundtrip: ```diff == CP936 +Failed to roundtrip given mutant byte at index 891 (251 /= 123 at index 891) +Failed to roundtrip given mutant byte at index 1605 (197 /= 69 at index 1605) +Failed to roundtrip given mutant byte at index 2411 (235 /= 107 at index 2411) +Failed to roundtrip given mutant byte at index 6480 (208 /= 80 at index 6480) +Failed to roundtrip given mutant byte at index 6482 (210 /= 82 at index 6482) +Failed to roundtrip given mutant byte at index 6484 (212 /= 84 at index 6484) +Failed to roundtrip given mutant byte at index 6496 (224 /= 96 at index 6496) +Failed to roundtrip given mutant byte at index 7243 (203 /= 75 at index 7243) +Failed to roundtrip given mutant byte at index 7277 (237 /= 109 at index 7277) +Failed to roundtrip given mutant byte at index 8027 (219 /= 91 at index 8027) +Failed to roundtrip given mutant byte at index 8801 (225 /= 97 at index 8801) ``` - - - - - 26e86984 by Ben Gamari at 2024-11-18T04:05:31-05:00 hadrian: Allow haddock options to be passed via key-value settings - - - - - 6e68b117 by Matthew Pickering at 2024-11-18T04:06:07-05:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - a4e0d235 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 exceptions: Improve the message layout as per #285 This commit fixes the layout of the additional information included when displaying an exception, namely the type of the exception. It also fixes the default handler's heading message to work well together with the improved display message of SomeException. CLC proposal#285 - - - - - 284ffab3 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 Display type and callstack of exception on handler This commit changes the Exception instance of SomeException to *simply* display the underlying exception in `displayException`. The augmented exception message that included the type and backtrace of the exception are now only printed on a call to `displayExceptionWithInfo`. At a surface level, existing programs should behave the same since the `uncaughtExceptionHandler`, which is responsible for printing out uncaught exceptions to the user, will use `displayExceptionWithInfo` by default. However, unlike the instance's `displayException` method, the `uncaughtExceptionHandler` can be overriden with `setUncaughtExceptionHandler`. This makes the extra information opt-in without fixing it the instance, which can be valuable if your program wants to display uncaught exceptions to users in a user-facing way (ie without backtraces). This is what was originally agreed for CLC#231 or CLC#261 with regard to the type of the exception information. The call stack also becoming part of the default handler rather than the Exception instance is an ammendment to CLC#164. Discussion of the ammendment is part of CLC#285. - - - - - 36cddd2c by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Remove redundant CallStack from exceptions Before the exception backtraces proposal was implemented, ErrorCall accumulated its own callstack via HasCallStack constraints, but ExceptionContext is now accumulated automatically. The original ErrorCall mechanism is now redundant and we get a duplicate CallStack Updates Cabal submodule to fix their usage of ErrorCallWithLocation to ErrorCall CLC proposal#285 Fixes #25283 - - - - - 7a74330b by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Freeze call stack in error throwing functions CLC proposal#285 - - - - - 3abf31a4 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 De-duplicate displayContext and displayExceptionContext The former was unused except for one module where it was essentially re-defining displayExceptionContext. Moreover, this commit extends the fix from bfe600f5bb3ecd2c8fa71c536c63d3c46984e3f8 to displayExceptionContext too, which was missing. - - - - - c0d783f8 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Re-export NoBacktrace from Control.Exception This was originally proposed and accepted in section "2.7 Capturing Backtraces on Exceptions" of the CLC proposal for exception backtraces. However, the implementation missed this re-export, which this commit now fixes. - - - - - 802b5c3e by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Fix exception backtraces from GHCi When running the program with `runhaskell`/`runghc` the backtrace should match the backtrace one would get by compiling and running the program. But currently, an exception thrown in a program interpreted with `runhaskell` will: * Not include the original exception backtrace at all * Include the backtrace from the internal GHCi/ghc rethrowing of the original exception This commit fixes this divergence by not annotating the ghc(i) backtrace (with NoBacktrace) and making sure that the backtrace of the original exception is serialized across the boundary and rethrown with the appropriate context. Fixes #25116 The !13301 MR (not this commit in particular) improves performance of MultiLayerModules. Unfortunately, T3294 regresses on aarch64-linux-deb12 by 1% allocations. Since this patch must be merged for 9.12 ASAP, we will not be able to investigate the slight regression on this platform in time. ------------------------- Metric Decrease: MultiLayerModulesRecomp MultiLayerModulesTH_OneShot Metric Increase: T3294 ------------------------- - - - - - 3e89eb65 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 base: Add to changelog.md CLC #285 - - - - - d9326a48 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Bump array and stm submodules for testsuite The testsuites of array and stm had to be updated according to !13301. Updates submodule array and stm. - - - - - 325fcb5d by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Clean up code style of Nativei386 adjustor - - - - - 39bb6e58 by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Fix stack overrun error in Nativei386 adjustor We were reserving the wrong kind of adjustor context (the generic `AdjustorContext` used by other adjustor implementations, rather than the i386-specific `CCallContext`) to return the adjustor context while freeing, resulting in #25485. Fixes #25485. - - - - - 831aab22 by sheaf at 2024-11-18T21:22:36-05:00 Include diagnostic reason in -fdiagnostics-as-json This commit ensures that the -fdiagnostics-as-json output includes the diagnostic reason. This allows the full error message produced by GHC to be re-constructed from the JSON output. Fixes #25403 - - - - - 3e5bfdd3 by Ben Gamari at 2024-11-18T21:23:12-05:00 rts: Introduce printIPE This is a convenience utility for use in GDB. - - - - - 44d909a3 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Don't store boot locations in finder cache Partially reverts commit fff55592a7b Amends add(Home)ModuleToFinder so that locations for boot files are not stored in the finder cache. Removes InstalledModule field from InstalledFound constructor since it's the same as the key that was searched for. - - - - - 64c95292 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Concentrate boot extension logic in Finder With new mkHomeModLocation that takes an extra HscSource to add boot extensions if required. - - - - - 11bad98d by ARATA Mizuki at 2024-11-19T14:39:08-05:00 Better documentation for floating-point min/max and SIMD primitives See #25350 for floating-point min/max Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 791a47b2 by Arnaud Spiwack at 2024-11-20T14:00:05+00:00 Add test for #25185 - - - - - 374e18e5 by Arnaud Spiwack at 2024-11-20T14:09:30+00:00 Quick look: emit the multiplicity of app heads in tcValArgs Otherwise it's not scaled properly by the context, allowing unsound expressions. Fixes #25185. - - - - - 1fc02399 by sheaf at 2024-11-20T18:11:03-05:00 x86 NCG: fix regUsageOfInstr for VMOVU & friends This commit fixes the implementation of 'regUsageOfInstr' for vector operations that take an 'Operand' as the destination, by ensuring that when the destination is an address then the address should be *READ*, and not *WRITTEN*. Getting this wrong is a disaster, as it means the register allocator has incorrect information, which can lead to it discard stores to registers, segfaults ensuing. Fixes #25486 - - - - - 7bd407a6 by Brandon Chinn at 2024-11-21T14:08:15-05:00 Fix CRLF in multiline strings (#25375) - - - - - 7575709b by Rodrigo Mesquita at 2024-11-21T14:08:52-05:00 Improve reachability queries on ModuleGraph Introduces `ReachabilityIndex`, an index constructed from a `GHC.Data.Graph.Directed` `Graph` that supports fast reachability queries (in $O(1)$). This abstract data structure is exposed from `GHC.Data.Graph.Directed.Reachability`. This index is constructed from the module graph nodes and cached in `ModuleGraph`, enabling efficient reachability queries on the module graph. Previously, we'd construct a Map of Set of ModuleGraph nodes which used a lot of memory (`O(n^2)` in the number of nodes) and cache that in the `ModuleGraph`. By using the reachability index we get rid of this space leak in the module graph -- even though the index is still quadratic in the number of modules, it is much, much more space efficient due to its representation using an IntMap of IntSet as opposed to the transitive closure we previously cached. In a memory profile of MultiLayerModules with 100x100 modules, memory usage improved from 6GB residency to 2.8GB, out of which roughly 1.8GB are caused by a second space leak related to ModuleGraph. On the same program, it brings compile time from 7.5s to 5.5s. Note how we simplify `checkHomeUnitsClosed` in terms of `isReachableMany` and by avoiding constructing a second graph with the full transitive closure -- it suffices to answer the reachability query on the full graph without collapsing the transitive closure completely into nodes. Unfortunately, solving this leak means we have to do a little bit more work since we can no longer cache the result of turning vertex indices into nodes. This results in a slight regression in MultiLayerModulesTH_Make, but results in large performance and memory wins when compiling large amounts of modules. ------------------------- Metric Decrease: mhu-perf Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - bcbcdaaf by Cheng Shao at 2024-11-21T14:09:28-05:00 driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code This commit fixes an undefined symbol error in RTS linker when attempting to compile home modules with -fhpc and -fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for detailed description and analysis of the bug. Also adds T25510/T25510c regression tests to test make mode/oneshot mode of the bug. - - - - - 970ada5a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Bump ci-images For introduction of Alpine/i386 image. Thanks to Julian for the base image. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 8115abc2 by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Add release job for i386/Alpine As requested by Mikolaj and started by Julian. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 639f0149 by Ben Gamari at 2024-11-22T23:32:06-05:00 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ - - - - - 490d4d0a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Mark i386 Alpine test breakages Marks the following tests as broken on i386/Alpine: * T22033 due to #25497 * simd009, T25062_V16, T25169, T22187_run due to #25498 - - - - - 536cdf09 by Cheng Shao at 2024-11-22T23:32:42-05:00 compiler: remove unused GHC.Linker.Loader.loadExpr This patch removes the unused `GHC.Linker.Loader.loadExpr` function. It was moved from `GHC.Runtime.Linker.linkExpr` in `ghc-9.0` to `GHC.Linker.Loader.loadExpr` in `ghc-9.2`, and remain completely unused and untested ever since. There's also no third party user of this function to my best knowledge, so let's remove this. Anyone who wants to write their own GHC API function to load bytecode can consult the source code in older release branches. - - - - - 6ee35024 by Drew Fenwick at 2024-11-22T23:33:26-05:00 Fix a non-compiling example in the type abstractions docs This patch adds a missing Show constraint to a code example in the User Guide's type abstractions docs to fix issue #25422. - - - - - d1172e20 by Rodrigo Mesquita at 2024-11-22T23:34:02-05:00 Re-introduce ErrorCallWithLocation with a deprecation pragma With the removal of the duplicate backtrace, part of CLC proposal #285, the constructor `ErrorCallWithLocation` was removed from base. This commit re-introduces it with a deprecation. - - - - - 1187a60a by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Skip tests requiring Hadrian deps in out-of-tree testsuite runs Some testsuite tests require specific tools (e.g. `check-ppr` and `check-exact`) beyond those shipped in the binary distribution. Skip these tests. Fixes #13897. - - - - - c37d7a2e by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Declare exactprint tests' dependency on check-exact - - - - - 454ce957 by Ben Gamari at 2024-11-22T23:35:15-05:00 ghc-internal: Fix a few cases of missing Haddock markup - - - - - a249649b by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/GHCiPrimCall : Add missing Makefile includes - - - - - a021a493 by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/IpeStats: Use Make rather than shell interpolation - - - - - 6e1fbda7 by Ben Gamari at 2024-11-25T03:55:44-05:00 hadrian-ghci-multi: Pass -this-package-name in unit response files As noted in #25509, the `-this-package-name` must be passed for each package to ensure that GHC can response references to the packages' exposed modules via package-qualified imports. Fix this. Closes #25509. - - - - - a05e4a9b by Simon Hengel at 2024-11-25T03:56:33-05:00 Refactoring: Use `OnOff` more consistently for `Extension` - - - - - 7536181d by Matthew Pickering at 2024-11-25T14:00:07-05:00 driver: Always link against "base" package when one shot linking The default value for base-unit-id is stored in the settings file. At install time, this can be set by using the BASE_UNIT_ID environment variable. At runtime, the value can be set by `-base-unit-id` flag. For whether all this is a good idea, see #25382 Fixes #25382 - - - - - 7f90f319 by Andreas Klebinger at 2024-11-25T14:00:44-05:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 - - - - - 291388e1 by Cheng Shao at 2024-11-25T14:01:19-05:00 ci: minor nix-in-docker improvements This patch makes some minor improvements re nix-in-docker logic in the ci configuration: - Update `nixos/nix` to the latest version - Apply $CPUS to `cores`/`max-jobs` to avoid oversubscribing while allowing a reasonable degree of parallelism - Remove redundant `--extra-experimental-features nix-command` in later `nix shell` invocations, it's already configured in `/etc/nix/nix.conf` - - - - - e684c406 by Cheng Shao at 2024-11-25T14:01:57-05:00 ci: avoid depending on stack job for test-bootstrap jobs This patch makes test-bootstrap related ci jobs only depend on hadrian-ghc-in-ghci job to finish, consistent with other jobs in the full-build stage generated by gen_ci.hs. This allows the jobs to be spawned earlier and improve overall pipeline parallelism. - - - - - caaf5388 by Simon Hengel at 2024-11-25T14:02:41-05:00 Refactoring: Remove `pSupportedExts` from `ParserOpts` This is never used for lexing / parsing. It is only used by `GHC.Parser.Header.getOptions`. - - - - - 41f8365c by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Add test for #25515 - - - - - 9279619f by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Desugar record notation with correct multiplicities Simply uses the multiplicity as stored in the field. As I'm writing this commit, the only possible multiplicity is 1, but !13525 is changing this. It's actually easier to take !13525 into account. Fixes #25515. - - - - - fcc3ae6e by Andreas Klebinger at 2024-11-26T08:24:58-05:00 Clarify INLINE unfolding optimization docs. Fixes #24660 - - - - - 88c4fe1d by Cheng Shao at 2024-11-26T08:25:34-05:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. - - - - - 53f978c0 by doyougnu at 2024-11-26T16:07:26-05:00 ghc-experimental: expose GHC.RTS.Flags, GHC.Stats See this CLC proposal: - https://github.com/haskell/core-libraries-committee/issues/289 and this CLC proposal for background: - https://github.com/haskell/core-libraries-committee/issues/288 Metric Decrease: MultiLayerModulesTH_OneShot - - - - - e70d4140 by Wang Xin at 2024-11-26T16:08:10-05:00 Add -mcmodel=medium moduleflag to generated LLVM IR on LoongArch platform With the Medium code model, the jump range of the generated jump instruction is larger than that of the Small code model. It's a temporary fix of the problem descriped in https://gitlab.haskell .org/ghc/ghc/-/issues/25495. This commit requires that the LLVM used contains the code of commit 9dd1d451d9719aa91b3bdd59c0c6679 83e1baf05, i.e., version 8.0 and later. Actually we should not rely on LLVM, so the only way to solve this problem is to implement the LoongArch backend. Add new type for codemodel - - - - - df42ba16 by Andreas Klebinger at 2024-11-27T11:40:49-05:00 Cmm constant folding: Narrow results to operations bitwidth. When constant folding ensure the result is still within bounds for the given type by explicitly narrowing the results. Not doing so results in a lot of spurious assembler warnings especially when testing primops. - - - - - bf3db97e by Ben Gamari at 2024-11-27T11:41:26-05:00 ghc-toolchain: Introduce basic flag validation We verify that required flags (currently `--output` and `--triple`) are provided. The implementation is truly awful, but so is getopt. Begins to address #25500. - - - - - a104508d by Ben Gamari at 2024-11-27T11:42:03-05:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. - - - - - c3fc9b86 by Ben Gamari at 2024-11-27T11:42:39-05:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. - - - - - a362b943 by sheaf at 2024-11-27T23:44:28-05:00 Add checkExact to toolTargets This change means that the Hadrian multi target will include exactprint. In particular, this means that HLS will work on exactprint inside the GHC tree. - - - - - e6c957e4 by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Add test for #25428 - - - - - 52d97f4e by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Don't bypass MonoLocalBind in empty patterns Fixes #25428 - - - - - 7890f2d8 by Ben Gamari at 2024-11-28T10:26:46-05:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. - - - - - 0fd43ea6 by Adam Sandberg Ericsson at 2024-11-28T10:27:22-05:00 mention -Iw in +RTS -? - - - - - 6cf579b9 by Ben Gamari at 2024-11-28T10:27:59-05:00 gitlab-ci: Set GIT_SUBMODULE_FORCE_HTTPS GitLab recommends using `https://` to clone submodules and provides the `GIT_SUBMODULE_FORCE_HTTPS` variable to force this. Fixes #25528. - - - - - 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - 5be0ed12 by sheaf at 2025-01-01T11:11:31+01:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - 09ee56b9 by Jade at 2025-01-01T12:09:31+01:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - 6 changed files: - .ghcid - .gitattributes - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/hello.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f677e846558ae7f3a2300e07f955fb659fb1f1c...09ee56b9eb270dde86fa75a1c3d329f42012734c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4f677e846558ae7f3a2300e07f955fb659fb1f1c...09ee56b9eb270dde86fa75a1c3d329f42012734c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 2 08:16:25 2025 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Thu, 02 Jan 2025 03:16:25 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/b/toolchain-tmp-cleanup Message-ID: <67764b59be517_3f363c13ce8e8869e7@gitlab.mail> Bryan R pushed new branch wip/b/toolchain-tmp-cleanup at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/b/toolchain-tmp-cleanup You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 2 08:38:51 2025 From: gitlab at gitlab.haskell.org (Bryan R (@chreekat)) Date: Thu, 02 Jan 2025 03:38:51 -0500 Subject: [Git][ghc/ghc][wip/b/toolchain-tmp-cleanup] Remove tmp files after toolchain check Message-ID: <6776509b9e36f_3f363c15bfd5090282@gitlab.mail> Bryan R pushed to branch wip/b/toolchain-tmp-cleanup at Glasgow Haskell Compiler / GHC Commits: ecedf876 by Bryan Richter at 2025-01-02T10:38:19+02:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 1 changed file: - m4/ghc_toolchain.m4 Changes: ===================================== m4/ghc_toolchain.m4 ===================================== @@ -187,6 +187,7 @@ AC_DEFUN([VALIDATE_GHC_TOOLCHAIN],[ "$GHC_TOOLCHAIN_BIN" format --input="$1" --output="$o1" "$GHC_TOOLCHAIN_BIN" format --input="$2" --output="$o2" diff_output=`diff "$o1" "$o2" 2>&1` + rm -f "$o1" "$o2" if test -z "$diff_output"; then true else View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecedf87643b43058052d77092d5a126f8555ad3b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ecedf87643b43058052d77092d5a126f8555ad3b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 2 15:05:37 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 02 Jan 2025 10:05:37 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] 23 commits: Flip the order of arguments of setField (#24668) Message-ID: <6776ab415bad0_333fba1bc842c1217c2@gitlab.mail> Matthew Pickering pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - 665783a5 by Matthew Pickering at 2025-01-02T10:11:38+00:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - bb09c682 by Rodrigo Mesquita at 2025-01-02T10:11:38+00:00 driver: Store the HomePackageTable in a mutable reference Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - e12c61ed by Matthew Pickering at 2025-01-02T12:20:39+00:00 Restrict HPT after load - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/upload.sh - compiler/GHC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Names.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fb24e5510f894a20282f08cba72e5fd36ad63c91...e12c61ed9e7f9001ce4ee91f45509e5bf9b91405 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fb24e5510f894a20282f08cba72e5fd36ad63c91...e12c61ed9e7f9001ce4ee91f45509e5bf9b91405 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 2 17:34:57 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 02 Jan 2025 12:34:57 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] 2 commits: WIP: Use a stable scc algorithm Message-ID: <6776ce41945ff_3df81fca85643463c@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: c1f36074 by Matthew Pickering at 2025-01-02T17:33:50+00:00 WIP: Use a stable scc algorithm - - - - - c220dfed by Matthew Pickering at 2025-01-02T17:34:02+00:00 MP cleanup - - - - - 4 changed files: - compiler/GHC/Data/Graph/Directed/Internal.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs Changes: ===================================== compiler/GHC/Data/Graph/Directed/Internal.hs ===================================== @@ -7,6 +7,10 @@ import Data.Array import qualified Data.Graph as G import Data.Graph ( Vertex, SCC(..) ) -- Used in the underlying representation import Data.Tree +import Data.Array.ST.Safe (STUArray) +import Control.Monad.ST +import Data.Array.ST.Safe (newArray, readArray, writeArray) +import Data.List (sort) data Graph node = Graph { gr_int_graph :: IntGraph, @@ -69,7 +73,7 @@ reachable g vs = preorderF (G.dfs g vs) scc :: IntGraph -> [SCC Vertex] scc graph = map decode forest where - forest = {-# SCC "Digraph.scc" #-} G.scc graph + forest = {-# SCC "Digraph.scc" #-} scc2 graph decode (Node v []) | mentions_itself v = CyclicSCC [v] | otherwise = AcyclicSCC v @@ -77,3 +81,68 @@ scc graph = map decode forest where dec (Node v ts) vs = v : foldr dec vs ts mentions_itself v = v `elem` (graph ! v) + + +newtype SetM s a = SetM { runSetM :: STUArray s Vertex Bool -> ST s a } + +instance Monad (SetM s) where + return = pure + {-# INLINE return #-} + SetM v >>= f = SetM $ \s -> do { x <- v s; runSetM (f x) s } + {-# INLINE (>>=) #-} + +instance Functor (SetM s) where + f `fmap` SetM v = SetM $ \s -> f `fmap` v s + {-# INLINE fmap #-} + +instance Applicative (SetM s) where + pure x = SetM $ const (return x) + {-# INLINE pure #-} + SetM f <*> SetM v = SetM $ \s -> f s >>= (`fmap` v s) + -- We could also use the following definition + -- SetM f <*> SetM v = SetM $ \s -> f s <*> v s + -- but Applicative (ST s) instance is present only in GHC 7.2+ + {-# INLINE (<*>) #-} + +run :: G.Bounds -> (forall s. SetM s a) -> a +run bnds act = runST (newArray bnds False >>= runSetM act) + +contains :: Vertex -> SetM s Bool +contains v = SetM $ \ m -> readArray m v + +include :: Vertex -> SetM s () +include v = SetM $ \ m -> writeArray m v True + +scc2 :: G.Graph -> [Tree Vertex] +scc2 g = dfs g (reverse (postOrd (G.transposeG g))) + +postorder :: Tree a -> [a] -> [a] +postorder (Node a ts) = postorderF ts . (a :) + +postorderF :: [Tree a] -> [a] -> [a] +postorderF ts = foldr (.) id $ map postorder ts + +postOrd :: G.Graph -> [Vertex] +postOrd g = postorderF (dff g) [] + +dff :: G.Graph -> [Tree Vertex] +dff g = dfs g (G.vertices g) + + +-- This dfs provides stability under transposition. +dfs :: G.Graph -> [Vertex] -> [Tree Vertex] +dfs g vs0 = run (bounds g) $ go vs0 + where + go :: [Vertex] -> SetM s [Tree Vertex] + go [] = pure [] + go (k: is') = do + visited <- contains k + if visited + then go is' + else do + include k + as <- go (sort (g!k)) + bs <- go is' + pure $ Node k as : bs + + ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1751,7 +1751,7 @@ downsweep_imports hsc_env old_summaries excl_mods allow_dup_roots (root_errs, ro Just {} -> loopUnit cache uxs Nothing -> case unitDepends <$> lookupUnitId (hsc_units hsc_env) u of Just us -> loopUnit (loopUnit (Map.insert nk (PackageNode us u) cache) us) uxs - Nothing -> panic "bad" + Nothing -> pprPanic "loopUnit" (text "Malformed package database, missing " <+> ppr u) getRootSummary :: [ModuleName] -> ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -417,11 +417,6 @@ loadInterfaceWithException doc mod_name where_from -- -- This operation is used just before TH splices are run (in 'getLinkDeps'). -- --- TODO: SHOULD WE ASSERT THIS IS ONLY CALLED ON ONESHOT MODE? WE SHOULD NEVER --- WANT TO LOAD HOME MODULE PACKAGES INTO THE EPS ANY OTHER WAY. --- --- The first time this is run...?? --- -- A field in the EPS tracks which home modules are already fully loaded, which we use -- here to avoid trying to load them a second time. -- @@ -430,7 +425,7 @@ loadInterfaceWithException doc mod_name where_from -- graph in 'getLinkDeps' another way. loadHomePackageInterfacesBelow :: (Module -> SDoc) -> Maybe HomeUnit {-^ The current home unit -} -> [Module] -> IfM lcl () -loadHomePackageInterfacesBelow _ Nothing _ = error "No home unit, what to do?" +loadHomePackageInterfacesBelow _ Nothing _ = panic "loadHomePackageInterfacesBelow: No home unit" loadHomePackageInterfacesBelow msg (Just home_unit) mods = do dflags <- getDynFlags let ctx = initSDocContext dflags defaultUserStyle ===================================== compiler/GHC/Linker/Deps.hs ===================================== @@ -118,7 +118,6 @@ get_link_deps opts pls maybe_normal_osuf span mods = do -- 1. Find the dependent home-pkg-modules/packages from each iface -- (omitting modules from the interactive package, which is already linked) (mods_s, pkgs_s) <- get_reachable_nodes opts relevant_mods - pprTraceM "Linkable deps:" (ppr relevant_mods $$ ppr mods_s $$ ppr pkgs_s) let -- 2. Exclude ones already linked View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19367100257652a203c4cb1de61f1da0a9936845...c220dfed4f7279e19aec4ae68624590f5e051083 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/19367100257652a203c4cb1de61f1da0a9936845...c220dfed4f7279e19aec4ae68624590f5e051083 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 2 17:45:55 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 02 Jan 2025 12:45:55 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/stable-scc Message-ID: <6776d0d3a6c7c_3df81ffe08f83715c@gitlab.mail> Matthew Pickering pushed new branch wip/stable-scc at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/stable-scc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 3 06:07:59 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 03 Jan 2025 01:07:59 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] include constructor in kind-checking for data family instance Message-ID: <67777ebfaf900_156ec1345bac467d@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: a27926ba by Patrick at 2025-01-03T14:07:45+08:00 include constructor in kind-checking for data family instance - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -717,7 +717,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons new_or_data -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -917,7 +917,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> NewOrData -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are @@ -926,7 +926,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons new_or_data = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -948,6 +948,10 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Do not add constraints from the data constructors -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + ; kcConDecls new_or_data res_kind hs_cons + + -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a27926ba7af5654df1e6eb95a9eeb2953f128d7e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a27926ba7af5654df1e6eb95a9eeb2953f128d7e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 3 13:01:15 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 03 Jan 2025 08:01:15 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] Fix performance issue Message-ID: <6777df9b3eaaa_d63f1e076f82817e@gitlab.mail> Matthew Pickering pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 499c8c70 by Matthew Pickering at 2025-01-03T13:00:57+00:00 Fix performance issue - - - - - 7 changed files: - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Unit/Env.hs - compiler/GHC/Unit/Home/Graph.hs - compiler/GHC/Unit/Home/PackageTable.hs Changes: ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -99,7 +99,7 @@ core2core hsc_env guts@(ModGuts { mg_module = mod dflags = hsc_dflags hsc_env logger = hsc_logger hsc_env extra_vars = interactiveInScope (hsc_IC hsc_env) - home_pkg_rules = UnitEnv.hugRulesBelow (hsc_unit_env hsc_env) (hsc_mod_graph hsc_env) (moduleUnitId mod) + home_pkg_rules = rulesBelow hsc_env (moduleUnitId mod) (GWIB { gwib_mod = moduleName mod, gwib_isBoot = NotBoot }) name_ppr_ctx = mkNamePprCtx ptc (hsc_unit_env hsc_env) rdr_env ptc = initPromotionTickContext dflags ===================================== compiler/GHC/Driver/Env.hs ===================================== @@ -29,6 +29,10 @@ module GHC.Driver.Env , lookupIfaceByModule , mainModIs + , rulesBelow + , instancesBelow + , annsBelow + -- * Legacy API , hscUpdateHPT ) @@ -52,6 +56,8 @@ import GHC.Unit.Module.ModIface import GHC.Unit.Module.ModDetails import GHC.Unit.Home.ModInfo import GHC.Unit.Home.PackageTable +import GHC.Unit.Home.Graph +import GHC.Unit.Module.Graph import qualified GHC.Unit.Home.Graph as HUG import GHC.Unit.Env as UnitEnv import GHC.Unit.External @@ -71,6 +77,13 @@ import GHC.Utils.Panic import GHC.Utils.Misc import GHC.Utils.Logger +import GHC.Core.Rules +import GHC.Types.Annotations +import GHC.Types.CompleteMatch +import GHC.Core.InstEnv +import GHC.Core.FamInstEnv +import GHC.Builtin.Names + import Data.IORef import qualified Data.Set as Set @@ -199,6 +212,126 @@ configured via command-line flags (in `GHC.setSessionDynFlags`). hscEPS :: HscEnv -> IO ExternalPackageState hscEPS hsc_env = readIORef (euc_eps (ue_eps (hsc_unit_env hsc_env))) + +-------------------------------------------------------------------------------- +-- TODO +-------------------------------------------------------------------------------- +-- WE MAY WANT TO CACHE SOME OF THESE AS WE BUILD UP THE HPT, to make these +-- queries O(1). But it's kind of hard because they wouldn't be rehydrated!!!!! +-- Then we'd have the HPT itself rehydrated, but the cached fields with +-- bad references. + +-- | Get annotations from all modules "below" this one (in the dependency +-- sense) within the home units. If the module is @Nothing@, returns /all/ +-- annotations in the home units. +annsBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv +annsBelow hsc_env uid mn = hugAnnsBelow hsc_env uid mn + +---- | Get rules from modules "below" this one (in the dependency sense) within +--the home units. +rulesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase +rulesBelow hsc_env uid mn = hugRulesBelow hsc_env uid mn + +-- | Find instances visible from the given set of imports +instancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst]) +instancesBelow hsc_env uid mn = hugInstancesBelow hsc_env uid mn + +-------------------------------------------------------------------------------- +-- * Queries on Transitive Closure +-------------------------------------------------------------------------------- +-- ROMES:TODO: Something else I want to do here is to receive a ModuleGraph and +-- then use the fast reachability queries to determine whether something is +-- reachable or not. That means we can very efficiently filter out things which +-- are not part of the transitive closure... +-- +-- So, e.g. it could probably be done faster by filtering out a cached list of +-- rules using a 'ReachabilityIndex' as the filter $O(1)$ fast queries. + +-- ROMES:TODO: Do something about the +-- +-- | isOneShot (ghcMode (hsc_dflags hsc_env)) = [] +-- +-- shortcut that we used when this was a function on HscEnv... + +-- | Find all rules in modules that are in the transitive closure of the given +-- module. +-- +-- $O(n)$ in the number of dependencies? +hugRulesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase +hugRulesBelow hsc uid mn = foldr (flip extendRuleBaseList) emptyRuleBase <$> + hugSomeThingsBelowUs (md_rules . hm_details) False hsc uid mn + +-- | Get annotations from modules "below" this one (in the dependency sense) +-- +-- $O(n)$ in the number of dependencies? +hugAnnsBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv +hugAnnsBelow hsc uid mn = foldr (flip extendAnnEnvList) emptyAnnEnv <$> + hugSomeThingsBelowUs (md_anns . hm_details) False hsc uid mn + +hugInstancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst]) +hugInstancesBelow hsc_env uid mnwib = do +-- ouch... improve + let mn = gwib_mod mnwib + (insts, famInsts) <- + unzip . concat <$> + hugSomeThingsBelowUs (\mod_info -> + let details = hm_details mod_info + -- Don't include instances for the current module + in if moduleName (mi_module (hm_iface mod_info)) == mn + then [] + else [(md_insts details, md_fam_insts details)]) + True -- Include -hi-boot + hsc_env + uid + mnwib + return (foldl' unionInstEnv emptyInstEnv insts, concat famInsts) + +-- | Get things from modules in the transitive closure of the given module. +-- +-- Note: Don't expose this function. We can improve the interface further -- +-- let's keep the queries on the HPT contained in this module so we can optimise +-- internally without breaking the API to the rest of GHC. This is a footgun if +-- exposed! +-- +-- NOTE: We should be able to import this considerably with the reachability +-- index and caching?... +-- +-- For example, easiest to go through all modules and filter out the ones in the +-- hpt via the module graph......... +-- +-- TODO: This include_hi_boot business is also pretty weird. Do we need it at all? +hugSomeThingsBelowUs :: (HomeModInfo -> [a]) -> Bool -> HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO [[a]] +hugSomeThingsBelowUs extract include_hi_boot hsc_env uid mn + = let hug = hsc_HUG hsc_env + mg = hsc_mod_graph hsc_env + in + sequence + [ things + -- "Finding each non-hi-boot module below me" maybe could be cached (well, + -- the inverse) in the module graph to avoid filtering the boots out of + -- the transitive closure out every time this is called + | (ModNodeKeyWithUid (GWIB { gwib_mod = mod, gwib_isBoot = is_boot }) mod_uid) + <- Set.toList (moduleGraphModulesBelow mg uid mn) + , include_hi_boot || (is_boot == NotBoot) + + -- unsavoury: when compiling the base package with --make, we + -- sometimes try to look up RULES etc for GHC.Prim. GHC.Prim won't + -- be in the HPT, because we never compile it; it's in the EPT + -- instead. ToDo: clean up, and remove this slightly bogus filter: + , mod /= moduleName gHC_PRIM + , not (mod == gwib_mod mn && uid == mod_uid) + + -- Look it up in the HUG + , let things = lookupHug hug mod_uid mod >>= \case + Just info -> return $ extract info + Nothing -> pprTrace "WARNING in hugSomeThingsBelowUs" msg mempty + msg = vcat [text "missing module" <+> ppr mod, + text "When starting from" <+> ppr mn, + text "below:" <+> ppr (moduleGraphModulesBelow mg uid mn), + text "Probable cause: out-of-date interface files"] + -- This really shouldn't happen, but see #962 + ] + -- | Deal with gathering annotations in from all possible places -- and combining them into a single 'AnnEnv' prepareAnnotations :: HscEnv -> Maybe ModGuts -> IO AnnEnv @@ -211,7 +344,7 @@ prepareAnnotations hsc_env mb_guts = do -- entries regardless of dependency ordering. get_mod mg = (moduleUnitId (mg_module mg), GWIB (moduleName (mg_module mg)) NotBoot) home_pkg_anns <- fromMaybe (hugAllAnns (hsc_unit_env hsc_env)) - $ uncurry (hugAnnsBelow (hsc_unit_env hsc_env) (hsc_mod_graph hsc_env)) + $ uncurry (hugAnnsBelow hsc_env) . get_mod <$> mb_guts let other_pkg_anns = eps_ann_env eps ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1212,11 +1212,11 @@ interpretBuildPlan hug mhmi_cache old_hpt plan = do !build_deps = getDependencies (map gwib_mod deps) build_map let loop_action = withCurrentUnit loop_unit $ do !_ <- wait_deps build_deps - hsc_env_TODO <- asks hsc_env + hsc_env <- asks hsc_env let mns :: [ModuleName] mns = mapMaybe (nodeKeyModName . gwib_mod) deps - hmis' <- liftIO $ rehydrateAfter hsc_env_TODO mns + hmis' <- liftIO $ rehydrateAfter hsc_env mns checkRehydrationInvariant hmis' deps ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -462,7 +462,7 @@ tcRnImports hsc_env import_decls -- modules batch (@--make@) compiled before this one, but -- which are not below this one. ; (home_insts, home_fam_insts) <- liftIO $ - UnitEnv.hugInstancesBelow (hsc_unit_env hsc_env) (hsc_mod_graph hsc_env) unitId mnwib + instancesBelow hsc_env unitId mnwib -- Record boot-file info in the EPS, so that it's -- visible to loadHiBootInterface in tcRnSrcDecls, ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -99,9 +99,6 @@ module GHC.Unit.Env , hugCompleteSigs , hugAllInstances , hugAllAnns - , hugAnnsBelow - , hugRulesBelow - , hugInstancesBelow -- * Legacy API @@ -141,21 +138,6 @@ import GHC.Core.FamInstEnv -- The hard queries -------------------------------------------------------------------------------- --- | Get annotations from all modules "below" this one (in the dependency --- sense) within the home units. If the module is @Nothing@, returns /all/ --- annotations in the home units. -hugAnnsBelow :: UnitEnv -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv -hugAnnsBelow = HUG.annsBelow . ue_home_unit_graph - ----- | Get rules from modules "below" this one (in the dependency sense) within ---the home units. -hugRulesBelow :: UnitEnv -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase -hugRulesBelow = HUG.rulesBelow . ue_home_unit_graph - --- | Find instances visible from the given set of imports -hugInstancesBelow :: UnitEnv -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst]) -hugInstancesBelow = HUG.instancesBelow . ue_home_unit_graph - -- | Find all the instance declarations (of classes and families) from -- the Home Package Table filtered by the provided predicate function. -- Used in @tcRnImports@, to select the instances that are in the ===================================== compiler/GHC/Unit/Home/Graph.hs ===================================== @@ -43,9 +43,6 @@ module GHC.Unit.Home.Graph , allFamInstances , allAnns , allCompleteSigs - , rulesBelow - , annsBelow - , instancesBelow -- * Utilities , hugSCCs @@ -94,32 +91,6 @@ import GHC.Types.CompleteMatch import GHC.Core.InstEnv import GHC.Types.Name.Env --------------------------------------------------------------------------------- --- TODO --------------------------------------------------------------------------------- --- WE MAY WANT TO CACHE SOME OF THESE AS WE BUILD UP THE HPT, to make these --- queries O(1). But it's kind of hard because they wouldn't be rehydrated!!!!! --- Then we'd have the HPT itself rehydrated, but the cached fields with --- bad references. - --- | Get annotations from all modules "below" this one (in the dependency --- sense) within the home units. If the module is @Nothing@, returns /all/ --- annotations in the home units. -annsBelow :: HomeUnitGraph -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv -annsBelow hug mg uid mn = foldr go (pure emptyAnnEnv) hug where - go hue = liftA2 plusAnnEnv (hptAnnsBelow (homeUnitEnv_hpt hue) mg uid mn) - ----- | Get rules from modules "below" this one (in the dependency sense) within ---the home units. -rulesBelow :: HomeUnitGraph -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase -rulesBelow hug mg uid mn = foldr go (pure emptyRuleBase) hug where - go hue = liftA2 plusNameEnv (hptRulesBelow (homeUnitEnv_hpt hue) mg uid mn) - --- | Find instances visible from the given set of imports -instancesBelow :: HomeUnitGraph -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst]) -instancesBelow hug mg uid mn = foldr go (pure (emptyInstEnv, [])) hug where - go hue = liftA2 (\(a,b) (a',b') -> (a `unionInstEnv` a', b ++ b')) - (hptInstancesBelow (homeUnitEnv_hpt hue) mg uid mn) -- | Get all 'CompleteMatches' (arising from COMPLETE pragmas) present across -- all home units. ===================================== compiler/GHC/Unit/Home/PackageTable.hs ===================================== @@ -58,15 +58,6 @@ module GHC.Unit.Home.PackageTable , hptAllFamInstances , hptAllAnnotations - -- ** Transitive closure queries - -- - -- | These are the queries which also require access to the 'ModuleGraph' - -- which describes the structure of the modules, rather than being "global queries". - -- Typically about the transitive closure - , hptRulesBelow - , hptAnnsBelow - , hptInstancesBelow - -- ** More Traversal-based queries , hptCollectDependencies , hptCollectObjects @@ -250,99 +241,6 @@ hptAllFamInstances = fmap mkModuleEnv . concatHpt (\hmi -> [(hmiModule hmi, hmiF hptAllAnnotations :: HomePackageTable -> IO AnnEnv hptAllAnnotations = fmap mkAnnEnv . concatHpt (md_anns . hm_details) --------------------------------------------------------------------------------- --- * Queries on Transitive Closure --------------------------------------------------------------------------------- --- ROMES:TODO: Something else I want to do here is to receive a ModuleGraph and --- then use the fast reachability queries to determine whether something is --- reachable or not. That means we can very efficiently filter out things which --- are not part of the transitive closure... --- --- So, e.g. it could probably be done faster by filtering out a cached list of --- rules using a 'ReachabilityIndex' as the filter $O(1)$ fast queries. - --- ROMES:TODO: Do something about the --- --- | isOneShot (ghcMode (hsc_dflags hsc_env)) = [] --- --- shortcut that we used when this was a function on HscEnv... - --- | Find all rules in modules that are in the transitive closure of the given --- module. --- --- $O(n)$ in the number of dependencies? -hptRulesBelow :: HomePackageTable -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase -hptRulesBelow hpt mg uid mn = foldr (flip extendRuleBaseList) emptyRuleBase <$> - hptSomeThingsBelowUs (md_rules . hm_details) False hpt mg uid mn - --- | Get annotations from modules "below" this one (in the dependency sense) --- --- $O(n)$ in the number of dependencies? -hptAnnsBelow :: HomePackageTable -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv -hptAnnsBelow hpt mg uid mn = foldr (flip extendAnnEnvList) emptyAnnEnv <$> - hptSomeThingsBelowUs (md_anns . hm_details) False hpt mg uid mn - -hptInstancesBelow :: HomePackageTable -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst]) -hptInstancesBelow hpt mg uid mnwib = do --- ouch... improve - let mn = gwib_mod mnwib - (insts, famInsts) <- - unzip . concat <$> - hptSomeThingsBelowUs (\mod_info -> - let details = hm_details mod_info - -- Don't include instances for the current module - in if moduleName (mi_module (hm_iface mod_info)) == mn - then [] - else [(md_insts details, md_fam_insts details)]) - True -- Include -hi-boot - hpt - mg - uid - mnwib - return (foldl' unionInstEnv emptyInstEnv insts, concat famInsts) - --- | Get things from modules in the transitive closure of the given module. --- --- Note: Don't expose this function. We can improve the interface further -- --- let's keep the queries on the HPT contained in this module so we can optimise --- internally without breaking the API to the rest of GHC. This is a footgun if --- exposed! --- --- NOTE: We should be able to import this considerably with the reachability --- index and caching?... --- --- For example, easiest to go through all modules and filter out the ones in the --- hpt via the module graph......... --- --- TODO: This include_hi_boot business is also pretty weird. Do we need it at all? -hptSomeThingsBelowUs :: (HomeModInfo -> [a]) -> Bool -> HomePackageTable -> ModuleGraph -> UnitId -> ModuleNameWithIsBoot -> IO [[a]] -hptSomeThingsBelowUs extract include_hi_boot hpt mg uid mn - = sequence - [ things - -- "Finding each non-hi-boot module below me" maybe could be cached (well, - -- the inverse) in the module graph to avoid filtering the boots out of - -- the transitive closure out every time this is called - | (ModNodeKeyWithUid (GWIB { gwib_mod = mod, gwib_isBoot = is_boot }) mod_uid) - <- Set.toList (moduleGraphModulesBelow mg uid mn) - , include_hi_boot || (is_boot == NotBoot) - - -- unsavoury: when compiling the base package with --make, we - -- sometimes try to look up RULES etc for GHC.Prim. GHC.Prim won't - -- be in the HPT, because we never compile it; it's in the EPT - -- instead. ToDo: clean up, and remove this slightly bogus filter: - , mod /= moduleName gHC_PRIM - , not (mod == gwib_mod mn && uid == mod_uid) - - -- Look it up in the HPT - , let things = lookupHpt hpt mod >>= \case - Just info -> return $ extract info - Nothing -> pprTrace "WARNING in hptSomeThingsBelowUs" msg mempty - msg = vcat [text "missing module" <+> ppr mod, - text "When starting from" <+> ppr mn, - text "below:" <+> ppr (moduleGraphModulesBelow mg uid mn), - text "Probable cause: out-of-date interface files"] - -- This really shouldn't happen, but see #962 - ] -------------------------------------------------------------------------------- -- * Traversal-based queries View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/499c8c70f73010262d843da475577f416d3cf9a6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/499c8c70f73010262d843da475577f416d3cf9a6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 3 16:15:28 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 03 Jan 2025 11:15:28 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] unused imports Message-ID: <67780d20e5750_1ecb6a1023688776e@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 4d40680b by Rodrigo Mesquita at 2025-01-03T16:14:45+00:00 unused imports - - - - - 5 changed files: - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Unit/Env.hs - compiler/GHC/Unit/Home/Graph.hs - compiler/GHC/Unit/Home/PackageTable.hs Changes: ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -63,7 +63,6 @@ import GHC.Types.Var ( Var ) import Control.Monad import qualified GHC.LanguageExtensions as LangExt import GHC.Unit.Module -import qualified GHC.Unit.Env as UnitEnv {- ************************************************************************ ===================================== compiler/GHC/Driver/Env.hs ===================================== @@ -62,7 +62,6 @@ import qualified GHC.Unit.Home.Graph as HUG import GHC.Unit.Env as UnitEnv import GHC.Unit.External -import GHC.Types.Annotations ( AnnEnv, mkAnnEnv, plusAnnEnv ) import GHC.Types.Error ( emptyMessages, Messages ) import GHC.Types.Name import GHC.Types.Name.Env @@ -79,7 +78,6 @@ import GHC.Utils.Logger import GHC.Core.Rules import GHC.Types.Annotations -import GHC.Types.CompleteMatch import GHC.Core.InstEnv import GHC.Core.FamInstEnv import GHC.Builtin.Names ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -114,7 +114,6 @@ import GHC.Unit.External import GHC.Unit.State import GHC.Unit.Home import GHC.Unit.Types -import GHC.Unit.Module.Graph import GHC.Unit.Home.ModInfo import GHC.Unit.Home.PackageTable import GHC.Unit.Home.Graph (HomeUnitGraph, HomeUnitEnv) @@ -128,7 +127,6 @@ import GHC.Driver.DynFlags import GHC.Utils.Outputable import GHC.Utils.Panic -import GHC.Core.Rules import GHC.Types.Annotations import GHC.Types.CompleteMatch import GHC.Core.InstEnv ===================================== compiler/GHC/Unit/Home/Graph.hs ===================================== @@ -71,7 +71,6 @@ import GHC.Unit.Home import GHC.Unit.Home.ModInfo import GHC.Unit.Home.PackageTable import GHC.Unit.Module -import GHC.Unit.Module.Graph import GHC.Unit.Module.ModIface import GHC.Unit.State import GHC.Utils.Outputable @@ -85,11 +84,9 @@ import qualified Data.Set as Set import GHC.Data.Maybe import GHC.Data.Graph.Directed -import GHC.Core.Rules import GHC.Types.Annotations import GHC.Types.CompleteMatch import GHC.Core.InstEnv -import GHC.Types.Name.Env -- | Get all 'CompleteMatches' (arising from COMPLETE pragmas) present across ===================================== compiler/GHC/Unit/Home/PackageTable.hs ===================================== @@ -97,7 +97,6 @@ import qualified Data.Set as Set import GHC.Core.FamInstEnv import GHC.Core.InstEnv -import GHC.Core.Rules import GHC.Linker.Types import GHC.Types.Annotations import GHC.Types.CompleteMatch @@ -105,11 +104,9 @@ import GHC.Types.Unique.DFM import GHC.Unit.Home.ModInfo import GHC.Unit.Module import GHC.Unit.Module.Deps -import GHC.Unit.Module.Graph import GHC.Unit.Module.ModDetails import GHC.Unit.Module.ModIface import GHC.Utils.Outputable -import GHC.Builtin.Names (gHC_PRIM) import GHC.Types.Unique (getUnique, getKey) import qualified GHC.Data.Word64Set as W64 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d40680b3a75ff89a8496a4d429dfdbc34ad029e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4d40680b3a75ff89a8496a4d429dfdbc34ad029e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 3 17:52:33 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 03 Jan 2025 12:52:33 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] 5 commits: stable sort Message-ID: <677823e1750b8_29547a1a91f4938ed@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: 4c9a552e by Matthew Pickering at 2025-01-03T12:52:52+00:00 stable sort - - - - - 60579bfd by Matthew Pickering at 2025-01-03T12:52:57+00:00 Revert "stable sort" This reverts commit 4c9a552e74a0f71457ade17f1074d6c87d5b6d7c. - - - - - 74376306 by Matthew Pickering at 2025-01-03T14:34:34+00:00 Revert "WIP: Use a stable scc algorithm" This reverts commit c1f36074deb6f3b1508aa9ac92d464dd20624c82. - - - - - a2d7b093 by Matthew Pickering at 2025-01-03T17:22:39+00:00 fixes - - - - - d29af41a by Matthew Pickering at 2025-01-03T17:51:32+00:00 Rework module structure - - - - - 10 changed files: - compiler/GHC/Data/Graph/Directed/Internal.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Unit/Module/Graph.hs - compiler/GHC/Unit/Module/ModIface.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - testsuite/tests/count-deps/CountDepsAst.stdout Changes: ===================================== compiler/GHC/Data/Graph/Directed/Internal.hs ===================================== @@ -7,10 +7,6 @@ import Data.Array import qualified Data.Graph as G import Data.Graph ( Vertex, SCC(..) ) -- Used in the underlying representation import Data.Tree -import Data.Array.ST.Safe (STUArray) -import Control.Monad.ST -import Data.Array.ST.Safe (newArray, readArray, writeArray) -import Data.List (sort) data Graph node = Graph { gr_int_graph :: IntGraph, @@ -73,7 +69,7 @@ reachable g vs = preorderF (G.dfs g vs) scc :: IntGraph -> [SCC Vertex] scc graph = map decode forest where - forest = {-# SCC "Digraph.scc" #-} scc2 graph + forest = {-# SCC "Digraph.scc" #-} G.scc graph decode (Node v []) | mentions_itself v = CyclicSCC [v] | otherwise = AcyclicSCC v @@ -81,68 +77,3 @@ scc graph = map decode forest where dec (Node v ts) vs = v : foldr dec vs ts mentions_itself v = v `elem` (graph ! v) - - -newtype SetM s a = SetM { runSetM :: STUArray s Vertex Bool -> ST s a } - -instance Monad (SetM s) where - return = pure - {-# INLINE return #-} - SetM v >>= f = SetM $ \s -> do { x <- v s; runSetM (f x) s } - {-# INLINE (>>=) #-} - -instance Functor (SetM s) where - f `fmap` SetM v = SetM $ \s -> f `fmap` v s - {-# INLINE fmap #-} - -instance Applicative (SetM s) where - pure x = SetM $ const (return x) - {-# INLINE pure #-} - SetM f <*> SetM v = SetM $ \s -> f s >>= (`fmap` v s) - -- We could also use the following definition - -- SetM f <*> SetM v = SetM $ \s -> f s <*> v s - -- but Applicative (ST s) instance is present only in GHC 7.2+ - {-# INLINE (<*>) #-} - -run :: G.Bounds -> (forall s. SetM s a) -> a -run bnds act = runST (newArray bnds False >>= runSetM act) - -contains :: Vertex -> SetM s Bool -contains v = SetM $ \ m -> readArray m v - -include :: Vertex -> SetM s () -include v = SetM $ \ m -> writeArray m v True - -scc2 :: G.Graph -> [Tree Vertex] -scc2 g = dfs g (reverse (postOrd (G.transposeG g))) - -postorder :: Tree a -> [a] -> [a] -postorder (Node a ts) = postorderF ts . (a :) - -postorderF :: [Tree a] -> [a] -> [a] -postorderF ts = foldr (.) id $ map postorder ts - -postOrd :: G.Graph -> [Vertex] -postOrd g = postorderF (dff g) [] - -dff :: G.Graph -> [Tree Vertex] -dff g = dfs g (G.vertices g) - - --- This dfs provides stability under transposition. -dfs :: G.Graph -> [Vertex] -> [Tree Vertex] -dfs g vs0 = run (bounds g) $ go vs0 - where - go :: [Vertex] -> SetM s [Tree Vertex] - go [] = pure [] - go (k: is') = do - visited <- contains k - if visited - then go is' - else do - include k - as <- go (sort (g!k)) - bs <- go is' - pure $ Node k as : bs - - ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -125,7 +125,8 @@ import qualified Control.Monad.Catch as MC import Data.IORef import Data.Maybe import Data.Time -import Data.List (sortOn, unfoldr) +import Data.Function +import Data.List (sortOn, unfoldr, sortBy) import Data.Bifunctor (first) import System.Directory import System.FilePath @@ -1491,7 +1492,24 @@ topSortModuleGraph topSortModuleGraph drop_hs_boot_nodes module_graph mb_root_mod = -- stronglyConnCompG flips the original order, so if we reverse -- the summaries we get a stable topological sort. - topSortModules drop_hs_boot_nodes (reverse $ mgModSummaries' module_graph) mb_root_mod + topSortModules drop_hs_boot_nodes (sortBy (cmpModuleGraphNodes `on` mkNodeKey) $ mgModSummaries' module_graph) mb_root_mod + + + where + -- In order to get the "right" ordering + -- Module nodes must be in reverse lexigraphic order. + -- All modules nodes must appear before package nodes or link nodes. + -- + -- Given the current implementation of scc, the result is in + -- The order is sensitive to the internal implementation in Data.Graph, + -- if it changes in future then this ordering will need to be modified. + cmpModuleGraphNodes (NodeKey_Module k1) (NodeKey_Module k2) = compare k2 k1 + cmpModuleGraphNodes (NodeKey_Link uid1) (NodeKey_Link uid2) = compare uid2 uid1 + cmpModuleGraphNodes (NodeKey_Link {}) _ = LT + cmpModuleGraphNodes _ (NodeKey_Link {}) = GT + cmpModuleGraphNodes (NodeKey_Module {}) _ = LT + cmpModuleGraphNodes _ (NodeKey_Module {}) = GT + cmpModuleGraphNodes n1 n2 = compare n2 n1 topSortModules :: Bool -> [ModuleGraphNode] -> Maybe HomeUnitModule -> [SCC ModuleGraphNode] topSortModules drop_hs_boot_nodes summaries mb_root_mod @@ -1723,7 +1741,10 @@ downsweep_imports hsc_env old_summaries excl_mods allow_dup_roots (root_errs, ro case mb_s of NotThere -> loopImports ss done summarised External uid -> do - let done' = loopUnit done [uid] + -- Pass an updated hsc_env to loopUnit, as each unit might + -- have a different visible package database. + let hsc_env' = hscSetActiveHomeUnit home_unit hsc_env + let done' = loopUnit hsc_env' done [uid] (other_deps, done'', summarised') <- loopImports ss done' summarised return (NodeKey_ExternalUnit uid : other_deps, done'', summarised') FoundInstantiation iud -> do @@ -1743,14 +1764,14 @@ downsweep_imports hsc_env old_summaries excl_mods allow_dup_roots (root_errs, ro GWIB { gwib_mod = L loc mod, gwib_isBoot = is_boot } = gwib wanted_mod = L loc mod - loopUnit :: Map.Map NodeKey ModuleGraphNode -> [UnitId] -> Map.Map NodeKey ModuleGraphNode - loopUnit cache [] = cache - loopUnit cache (u:uxs) = do + loopUnit :: HscEnv -> Map.Map NodeKey ModuleGraphNode -> [UnitId] -> Map.Map NodeKey ModuleGraphNode + loopUnit _ cache [] = cache + loopUnit lcl_hsc_env cache (u:uxs) = do let nk = (NodeKey_ExternalUnit u) case Map.lookup nk cache of - Just {} -> loopUnit cache uxs - Nothing -> case unitDepends <$> lookupUnitId (hsc_units hsc_env) u of - Just us -> loopUnit (loopUnit (Map.insert nk (PackageNode us u) cache) us) uxs + Just {} -> loopUnit lcl_hsc_env cache uxs + Nothing -> case unitDepends <$> lookupUnitId (hsc_units lcl_hsc_env) u of + Just us -> loopUnit lcl_hsc_env (loopUnit lcl_hsc_env (Map.insert nk (PackageNode us u) cache) us) uxs Nothing -> pprPanic "loopUnit" (text "Malformed package database, missing " <+> ppr u) getRootSummary :: ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -25,7 +25,7 @@ module GHC.Iface.Load ( -- IfM functions loadInterface, loadSysInterface, loadUserInterface, loadPluginInterface, - loadHomePackageInterfacesBelow, + loadExternalGraphBelow, findAndReadIface, readIface, writeIface, flagsToIfCompression, moduleFreeHolesPrecise, @@ -423,44 +423,96 @@ loadInterfaceWithException doc mod_name where_from -- For convenience, reads the module graph out of the EPS after having loaded -- all the modules and returns it. It would be harder to get the updated module -- graph in 'getLinkDeps' another way. -loadHomePackageInterfacesBelow :: (Module -> SDoc) -> Maybe HomeUnit {-^ The current home unit -} - -> [Module] -> IfM lcl () -loadHomePackageInterfacesBelow _ Nothing _ = panic "loadHomePackageInterfacesBelow: No home unit" -loadHomePackageInterfacesBelow msg (Just home_unit) mods = do +loadExternalGraphBelow :: (Module -> SDoc) -> Maybe HomeUnit {-^ The current home unit -} + -> Set.Set ExternalKey -> [Module] -> IfM lcl (Set.Set ExternalKey) +loadExternalGraphBelow _ Nothing _ _ = panic "loadHomePackageInterfacesBelow: No home unit" +loadExternalGraphBelow msg (Just home_unit) init_loaded mods = + foldM (loadExternalGraphModule msg home_unit) init_loaded mods + +loadExternalGraphModule :: (Module -> SDoc) -> HomeUnit + -> Set.Set ExternalKey -> Module -> IfM lcl (Set.Set ExternalKey) +loadExternalGraphModule msg home_unit init_loaded mod + | homeUnitId home_unit /= moduleUnitId mod = do + loadExternalPackageBelow init_loaded (moduleUnitId mod) + | otherwise = do + + let key = ExternalModuleKey $ ModNodeKeyWithUid (GWIB (moduleName mod) NotBoot) (moduleUnitId mod) + let new_cache = Set.insert key init_loaded + graph <- eps_module_graph <$> getEps + + if (not (isFullyLoadedModule key graph || Set.member key init_loaded)) + then actuallyLoadExternalGraphModule msg home_unit new_cache key mod + else + return init_loaded + +actuallyLoadExternalGraphModule + :: (Module -> SDoc) + -> HomeUnit + -> Set.Set ExternalKey + -> ExternalKey + -> Module + -> IOEnv (Env IfGblEnv lcl) (Set.Set ExternalKey) +actuallyLoadExternalGraphModule msg home_unit new_cache key mod = do dflags <- getDynFlags let ctx = initSDocContext dflags defaultUserStyle + iface <- withIfaceErr ctx $ + loadInterface (msg mod) mod (ImportByUser NotBoot) + + -- RM:TODO: THINGS WE ARE NOT DOING + -- + -- The ModIface contains the transitive closure of the module dependencies + -- within the current package, *except* for boot modules: if we encounter + -- a boot module, we have to find its real interface and discover the + -- dependencies of that. Hence we need to traverse the dependency + -- tree recursively. See bug #936, testcase ghci/prog007. + + let deps = mi_deps iface + mod_deps = dep_direct_mods deps + pkg_deps = dep_direct_pkgs deps + + -- Load all direct dependencies that are in the home package + cache_mods <- loadExternalGraphBelow msg (Just home_unit) new_cache + $ map (\(uid, GWIB mn _) -> mkModule (RealUnit (Definite uid)) mn) + $ Set.toList mod_deps + + cache_pkgs <- foldM loadExternalPackageBelow cache_mods (Set.toList pkg_deps) + + registerFullyLoaded key + return cache_pkgs + +registerFullyLoaded :: ExternalKey -> IfM lcl () +registerFullyLoaded key = do + -- Update the external graph with this module being fully loaded. + logger <- getLogger + liftIO $ trace_if logger (text "Fully loaded:" <+> ppr key) + updateEps_ $ \eps -> + eps{eps_module_graph = setFullyLoadedModule key (eps_module_graph eps)} - forM_ mods $ \mod -> do - +loadExternalPackageBelow :: Set.Set ExternalKey -> UnitId -> IfM lcl (Set.Set ExternalKey) +loadExternalPackageBelow cache uid = do graph <- eps_module_graph <$> getEps - let key = ExternalModuleKey $ ModNodeKeyWithUid (GWIB (moduleName mod) NotBoot) (moduleUnitId mod) - - if isFullyLoadedModule key graph - then return () - else do - iface <- withIfaceErr ctx $ - loadInterface (msg mod) mod (ImportByUser NotBoot) + us <- hsc_units <$> getTopEnv + let key = ExternalPackageKey uid + let cache' = Set.insert key cache + if not (isFullyLoadedModule key graph || Set.member key cache) + then do + case unitDepends <$> lookupUnitId us uid of + Just dep_uids -> do + loadPackageIntoEPSGraph uid dep_uids + final_cache <- foldM loadExternalPackageBelow cache' dep_uids + registerFullyLoaded key + return final_cache + Nothing -> pprPanic "loadExternalPackagesBelow: missing" (ppr uid) + else + return cache - -- RM:TODO: THINGS WE ARE NOT DOING - -- - -- The ModIface contains the transitive closure of the module dependencies - -- within the current package, *except* for boot modules: if we encounter - -- a boot module, we have to find its real interface and discover the - -- dependencies of that. Hence we need to traverse the dependency - -- tree recursively. See bug #936, testcase ghci/prog007. - let deps = mi_deps iface - mod_deps = dep_direct_mods deps - -- Load all direct dependencies that are in the home package - loadHomePackageInterfacesBelow msg (Just home_unit) - $ map (\(uid, GWIB mn _) -> mkModule (RealUnit (Definite uid)) mn) - $ filter ((==) (homeUnitId home_unit) . fst) - $ Set.toList mod_deps +loadPackageIntoEPSGraph :: UnitId -> [UnitId] -> IfM lcl () +loadPackageIntoEPSGraph uid dep_uids = + updateEps_ $ \eps -> + eps { eps_module_graph = extendExternalModuleGraph (NodeExternalPackage uid (Set.fromList dep_uids)) (eps_module_graph eps) } - -- Update the external graph with this module being fully loaded. - updateEps_ $ \eps -> - eps{eps_module_graph = setFullyLoadedModule key (eps_module_graph eps)} ------------------ loadInterface :: SDoc -> Module -> WhereFrom @@ -571,24 +623,13 @@ loadInterface doc_str mod from ; purged_hsc_env <- getTopEnv ; let direct_deps = map (uncurry (flip ModNodeKeyWithUid)) $ (Set.toList (dep_direct_mods $ mi_deps iface)) - ; let direct_pkg_deps = dep_direct_pkgs $ mi_deps iface + ; let direct_pkg_deps = Set.toList $ dep_direct_pkgs $ mi_deps iface ; let !module_graph_key = -- pprTrace "module_graph_on_load" (ppr (eps_module_graph eps)) $ if moduleUnitId mod `elem` hsc_all_home_unit_ids hsc_env --- ^ home unit mods in eps can only happen in oneshot mode - then Just $ NodeHomePackage (miKey iface) (map ExternalModuleKey direct_deps) + then Just $ NodeHomePackage (miKey iface) (map ExternalModuleKey direct_deps + ++ map ExternalPackageKey direct_pkg_deps) else Nothing - ; let !module_graph_pkg_key = - -- ROMES:TODO: This doesn't work as expected. Insertions on the - -- graph don't override previous nodes, they just create new - -- ones. We get multiple duplicate nodes with incomplete dependencies each. - let pkg_key = toUnitId $ moduleUnit (mi_module iface) - in case emgLookupKey (ExternalPackageKey pkg_key) (eps_module_graph eps) of - Nothing -> NodeExternalPackage pkg_key direct_pkg_deps - Just pkg_node -> case pkg_node of - NodeHomePackage{} -> panic "ExternalPackageKey lookup should never return a NodeHomePackage node" - NodeExternalPackage _ deps_uids -> - NodeExternalPackage pkg_key (deps_uids `Set.union` direct_pkg_deps) - ; let final_iface = iface & set_mi_decls (panic "No mi_decls in PIT") @@ -634,8 +675,7 @@ loadInterface doc_str mod from let eps_graph' = case module_graph_key of Just k -> extendExternalModuleGraph k (eps_module_graph eps) Nothing -> eps_module_graph eps - eps_graph'' = extendExternalModuleGraph module_graph_pkg_key eps_graph' - in eps_graph'', + in eps_graph', eps_complete_matches = eps_complete_matches eps ++ new_eps_complete_matches, eps_inst_env = extendInstEnvList (eps_inst_env eps) ===================================== compiler/GHC/Linker/Deps.hs ===================================== @@ -233,10 +233,12 @@ get_reachable_nodes opts mods | otherwise = return Nothing - go (ExternalModuleKey . mkModuleNk) emgNodeKey (emgReachableMany emg) (map emgProject) get_mod_info_eps - --romes:todo:^ do we need to make sure we only get non-boot files out of - --this. perhaps as easy as filtering them out by ModNodeKeyWithUid with is - --boot information? + get_mod_key m + | moduleUnitId m == homeUnitId (ue_unsafeHomeUnit unit_env) + = ExternalModuleKey (mkModuleNk m) + | otherwise = ExternalPackageKey (moduleUnitId m) + + go get_mod_key emgNodeKey (emgReachableMany emg) (map emgProject) get_mod_info_eps -- Reachability on 'ModuleGraph' (for --make mode) | otherwise ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -610,7 +610,7 @@ initLinkDepsOpts hsc_env = opts ldLoadHomeIfacesBelow msg hu mods = do initIfaceCheck (text "loader") hsc_env - $ loadHomePackageInterfacesBelow msg hu mods + $ void $ loadExternalGraphBelow msg hu Set.empty mods -- Read the EPS only after `loadHomePackageInterfacesBelow` hscEPS hsc_env ===================================== compiler/GHC/Unit/Module/Graph.hs ===================================== @@ -87,6 +87,7 @@ module GHC.Unit.Module.Graph , ModNodeKey , ModNodeKeyWithUid(..) , msKey + , miKey -- ** Internal node representation -- @@ -116,6 +117,7 @@ import GHC.Types.SourceFile ( hscSourceString ) import GHC.Unit.Module.ModSummary import GHC.Unit.Types import GHC.Utils.Outputable +import GHC.Unit.Module.ModIface import GHC.Utils.Misc ( partitionWith ) import System.FilePath @@ -124,6 +126,7 @@ import GHC.Types.Unique.DSet import qualified Data.Set as Set import Data.Set (Set) import GHC.Unit.Module +import GHC.Unit.Module.ModNodeKey import GHC.Linker.Static.Utils import Data.Bifunctor @@ -480,16 +483,14 @@ nodeKeyModName :: NodeKey -> Maybe ModuleName nodeKeyModName (NodeKey_Module mk) = Just (gwib_mod $ mnkModuleName mk) nodeKeyModName _ = Nothing -type ModNodeKey = ModuleNameWithIsBoot -data ModNodeKeyWithUid = ModNodeKeyWithUid { mnkModuleName :: !ModuleNameWithIsBoot - , mnkUnitId :: !UnitId } deriving (Eq, Ord) - -instance Outputable ModNodeKeyWithUid where - ppr (ModNodeKeyWithUid mnwib uid) = ppr uid <> colon <> ppr mnwib - msKey :: ModSummary -> ModNodeKeyWithUid msKey ms = ModNodeKeyWithUid (ms_mnwib ms) (ms_unitid ms) +miKey :: ModIface -> ModNodeKeyWithUid +miKey hmi = ModNodeKeyWithUid (mi_mnwib hmi) ((toUnitId $ moduleUnit (mi_module hmi))) + +type ModNodeKey = ModuleNameWithIsBoot + -------------------------------------------------------------------------------- -- ** Internal node representation (exposed) -------------------------------------------------------------------------------- ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -82,7 +82,6 @@ module GHC.Unit.Module.ModIface , IfaceImport(..) , mi_boot , mi_fix - , miKey , mi_semantic_module , mi_free_holes , mi_mnwib @@ -126,7 +125,6 @@ import GHC.Utils.Binary import Control.DeepSeq import Control.Exception -import GHC.Unit.Module.Graph (ModNodeKeyWithUid(..)) {- Note [Interface file stages] @@ -364,8 +362,6 @@ data ModIface_ (phase :: ModIfacePhase) -- See Note [Sharing of ModIface]. } -miKey :: ModIface -> ModNodeKeyWithUid -miKey hmi = ModNodeKeyWithUid (mi_mnwib hmi) ((toUnitId $ moduleUnit (mi_module hmi))) -- Enough information to reconstruct the top level environment for a module data IfaceTopEnv ===================================== compiler/GHC/Unit/Module/ModNodeKey.hs ===================================== @@ -0,0 +1,12 @@ +module GHC.Unit.Module.ModNodeKey ( ModNodeKeyWithUid(..) ) where + +import GHC.Prelude +import GHC.Utils.Outputable +import GHC.Unit.Types + +data ModNodeKeyWithUid = ModNodeKeyWithUid { mnkModuleName :: !ModuleNameWithIsBoot + , mnkUnitId :: !UnitId } deriving (Eq, Ord) + +instance Outputable ModNodeKeyWithUid where + ppr (ModNodeKeyWithUid mnwib uid) = ppr uid <> colon <> ppr mnwib + ===================================== compiler/ghc.cabal.in ===================================== @@ -941,6 +941,7 @@ Library GHC.Unit.Module.Deps GHC.Unit.Module.Env GHC.Unit.Module.Graph + GHC.Unit.Module.ModNodeKey GHC.Unit.Module.External.Graph GHC.Unit.Module.Imported GHC.Unit.Module.Location ===================================== testsuite/tests/count-deps/CountDepsAst.stdout ===================================== @@ -199,6 +199,7 @@ GHC.Unit.Module.Env GHC.Unit.Module.Imported GHC.Unit.Module.Location GHC.Unit.Module.ModIface +GHC.Unit.Module.ModNodeKey GHC.Unit.Module.Warnings GHC.Unit.Module.WholeCoreBindings GHC.Unit.Parser View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c220dfed4f7279e19aec4ae68624590f5e051083...d29af41ae2f249ee403f5307300c83c4a5615607 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c220dfed4f7279e19aec4ae68624590f5e051083...d29af41ae2f249ee403f5307300c83c4a5615607 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 3 17:54:07 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 03 Jan 2025 12:54:07 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] 2 commits: Drop outdated note Message-ID: <6778243f54398_29547a15d53894382@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 7a3cc49c by Rodrigo Mesquita at 2025-01-03T16:27:14+00:00 Drop outdated note - - - - - 63b6ebb5 by Rodrigo Mesquita at 2025-01-03T17:53:53+00:00 Rename UnitEnv functions with ue_ - - - - - 18 changed files: - compiler/GHC.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Types/Name/Ppr.hs - compiler/GHC/Unit/Env.hs - compiler/GHC/Unit/Finder.hs Changes: ===================================== compiler/GHC.hs ===================================== @@ -734,7 +734,7 @@ setTopSessionDynFlags dflags = do wasmInterpTargetPlatform = targetPlatform dflags, wasmInterpProfiled = profiled, wasmInterpHsSoSuffix = way_tag ++ dynLibSuffix (ghcNameVersion dflags), - wasmInterpUnitState = homeUnitState $ hsc_unit_env hsc_env + wasmInterpUnitState = ue_homeUnitState $ hsc_unit_env hsc_env } pure $ Just $ Interp (ExternalInterp $ ExtWasm $ ExtInterpState cfg s) loader lookup_cache @@ -822,7 +822,7 @@ setProgramDynFlags_ invalidate_needed dflags = do if changed then do -- additionally, set checked dflags so we don't lose fixes - old_unit_env <- UnitEnv.setFlags dflags0 . hsc_unit_env <$> getSession + old_unit_env <- ue_setFlags dflags0 . hsc_unit_env <$> getSession home_unit_graph <- forM (ue_home_unit_graph old_unit_env) $ \homeUnitEnv -> do let cached_unit_dbs = homeUnitEnv_unit_dbs homeUnitEnv ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -433,7 +433,7 @@ addUnit u = do logger <- getLogger let dflags0 = hsc_dflags hsc_env let old_unit_env = hsc_unit_env hsc_env - newdbs <- case homeUnitDbs old_unit_env of + newdbs <- case ue_homeUnitDbs old_unit_env of Nothing -> panic "addUnit: called too early" Just dbs -> let newdb = UnitDatabase ===================================== compiler/GHC/Driver/Env.hs ===================================== @@ -113,10 +113,10 @@ hsc_home_unit :: HscEnv -> HomeUnit hsc_home_unit = unsafeGetHomeUnit . hsc_unit_env hsc_home_unit_maybe :: HscEnv -> Maybe HomeUnit -hsc_home_unit_maybe = homeUnit . hsc_unit_env +hsc_home_unit_maybe = ue_homeUnit . hsc_unit_env hsc_units :: HasDebugCallStack => HscEnv -> UnitState -hsc_units = homeUnitState . hsc_unit_env +hsc_units = ue_homeUnitState . hsc_unit_env hsc_HPT :: HscEnv -> HomePackageTable hsc_HPT = ue_hpt . hsc_unit_env @@ -421,7 +421,7 @@ hscUpdateFlags f h = hscSetFlags (f (hsc_dflags h)) h hscSetFlags :: HasDebugCallStack => DynFlags -> HscEnv -> HscEnv hscSetFlags dflags h = hscUpdateLoggerFlags $ h { hsc_dflags = dflags - , hsc_unit_env = setFlags dflags (hsc_unit_env h) } + , hsc_unit_env = ue_setFlags dflags (hsc_unit_env h) } -- See Note [Multiple Home Units] hscSetActiveHomeUnit :: HasDebugCallStack => HomeUnit -> HscEnv -> HscEnv @@ -430,7 +430,7 @@ hscSetActiveHomeUnit home_unit = hscSetActiveUnitId (homeUnitId home_unit) hscSetActiveUnitId :: HasDebugCallStack => UnitId -> HscEnv -> HscEnv hscSetActiveUnitId uid e = e { hsc_unit_env = ue_setActiveUnit uid (hsc_unit_env e) - , hsc_dflags = UnitEnv.unitFlags uid (hsc_unit_env e) } + , hsc_dflags = ue_unitFlags uid (hsc_unit_env e) } hscActiveUnitId :: HscEnv -> UnitId hscActiveUnitId e = ue_currentUnit (hsc_unit_env e) ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1898,7 +1898,7 @@ enableCodeGenWhen enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = do mgMapM enable_code_gen mg where - defaultBackendOf ms = platformDefaultBackend (targetPlatform $ unitFlags (ms_unitid ms) unit_env) + defaultBackendOf ms = platformDefaultBackend (targetPlatform $ ue_unitFlags (ms_unitid ms) unit_env) enable_code_gen :: ModSummary -> IO ModSummary enable_code_gen ms | ModSummary @@ -2848,39 +2848,6 @@ executeLinkNode hug kn uid deps = do Failed -> fail "Link Failed" Succeeded -> return () -{- -Note [ModuleNameSet, efficiency and space leaks] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -During upsweep, the results of compiling modules are placed into a MVar. When we need -to compute the right compilation environment for a module, we consult this MVar and -set the HomeUnitGraph accordingly. This is done to avoid having to precisely track -module dependencies and recreating the HUG from scratch each time, which is very expensive. - -In serial mode (-j1), this all works out fine: a module can only be compiled -after its dependencies have finished compiling, and compilation can't be -interleaved with the compilation of other module loops. This ensures that -the HUG only ever contains finalised interfaces. - -In parallel mode, we have to be more careful: the HUG variable can contain non-finalised -interfaces, which have been started by another thread. In order to avoid a space leak -in which a finalised interface is compiled against a HPT which contains a non-finalised -interface, we have to restrict the HUG to only contain the visible modules. - -The collection of visible modules explains which transitive modules are visible -from a certain point. It is recorded in the ModuleNameSet. -Before a module is compiled, we use this set to restrict the HUG to the visible -modules only, avoiding this tricky space leak. - -Efficiency of the ModuleNameSet is of utmost importance, because a union occurs for -each edge in the module graph. To achieve this, the set is represented directly as an IntSet, -which provides suitable performance – even using a UniqSet (which is backed by an IntMap) is -too slow. The crucial test of performance here is the time taken to a do a no-op build in --make mode. - -See test "jspace" for an example which used to trigger this problem. - --} - -- | Wait for dependencies to finish, and then return their results. wait_deps :: [BuildResult] -> RunMakeM [HomeModInfo] wait_deps [] = return [] @@ -3073,6 +3040,4 @@ which can be checked easily using ghc-debug. 5. At the end of a successful upsweep, the number of live ModDetails equals the number of non-boot Modules. Why? Each module has a HomeModInfo which contains a ModDetails from that module. - Where? See Note [ModuleNameSet, efficiency and space leaks], a variety of places - in the driver are responsible. -} ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -469,7 +469,7 @@ linkingNeeded logger dflags unit_env staticLink linkables pkg_deps = do -- modification times on all of the objects and libraries, then omit -- linking (unless the -fforce-recomp flag was given). let platform = ue_platform unit_env - unit_state = homeUnitState unit_env + unit_state = ue_homeUnitState unit_env arch_os = platformArchOS platform exe_file = exeFileName arch_os staticLink (outputFile_ dflags) e_exe_time <- tryIO $ getModificationUTCTime exe_file ===================================== compiler/GHC/Iface/Errors.hs ===================================== @@ -87,7 +87,7 @@ cannotFindModule hsc_env = cannotFindModule' cannotFindModule' :: UnitEnv -> Profile -> ModuleName -> FindResult -> MissingInterfaceError cannotFindModule' unit_env profile mod res = - CantFindErr (homeUnitState unit_env) FindingModule $ + CantFindErr (ue_homeUnitState unit_env) FindingModule $ cantFindErr unit_env profile mod @@ -105,7 +105,7 @@ cantFindErr _ _ mod_name (FoundMultiple mods) cantFindErr unit_env profile mod_name find_result = CantFindInstalled mod_name more_info where - mhome_unit = homeUnit unit_env + mhome_unit = ue_homeUnit unit_env more_info = case find_result of NoPackage pkg @@ -131,7 +131,7 @@ cantFindErr unit_env profile mod_name find_result | otherwise -> GenericMissing - (map ((\uid -> (uid, lookupUnit (homeUnitState unit_env) uid))) pkg_hiddens) + (map ((\uid -> (uid, lookupUnit (ue_homeUnitState unit_env) uid))) pkg_hiddens) mod_hiddens unusables files _ -> panic "cantFindErr" ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -445,7 +445,7 @@ loadInterface doc_str mod from -- Check whether we have the interface already ; hsc_env <- getTopEnv - ; let mhome_unit = homeUnit (hsc_unit_env hsc_env) + ; let mhome_unit = ue_homeUnit (hsc_unit_env hsc_env) ; liftIO (lookupIfaceByModule hug (eps_PIT eps) mod) >>= \case { Just iface -> return (Succeeded iface) ; -- Already loaded ===================================== compiler/GHC/Linker/Deps.hs ===================================== @@ -228,15 +228,15 @@ get_link_deps opts pls maybe_normal_osuf span mods = do (_, GWIB m IsBoot) -> Left m (_, GWIB m NotBoot) -> Right m - mod_deps' = case homeUnit unit_env of + mod_deps' = case ue_homeUnit unit_env of Nothing -> [] Just home_unit -> filter (not . (`elementOfUniqDSet` acc_mods)) (map (mkHomeModule home_unit) $ (boot_deps ++ mod_deps)) - acc_mods' = case homeUnit unit_env of + acc_mods' = case ue_homeUnit unit_env of Nothing -> acc_mods Just home_unit -> addListToUniqDSet acc_mods (mod : map (mkHomeModule home_unit) mod_deps) acc_pkgs' = addListToUniqDSet acc_pkgs (Set.toList pkg_deps) - case homeUnit unit_env of + case ue_homeUnit unit_env of Just home_unit | isHomeUnit home_unit pkg -> follow_deps (mod_deps' ++ mods) acc_mods' acc_pkgs' _ -> follow_deps mods acc_mods (addOneToUniqDSet acc_pkgs' (toUnitId pkg)) @@ -273,7 +273,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do Nothing -> do -- It's not in the HPT because we are in one shot mode, -- so use the Finder to get a ModLocation... - case homeUnit unit_env of + case ue_homeUnit unit_env of Nothing -> no_obj mod Just home_unit -> do from_bc <- ldLoadByteCode opts mod ===================================== compiler/GHC/Linker/ExtraObj.hs ===================================== @@ -159,7 +159,7 @@ mkNoteObjsToLinkIntoBinary logger tmpfs dflags unit_env dep_packages = do else return [] where - unit_state = homeUnitState unit_env + unit_state = ue_homeUnitState unit_env platform = ue_platform unit_env link_opts info = hcat [ -- "link info" section (see Note [LinkInfo section]) ===================================== compiler/GHC/Linker/Static.hs ===================================== @@ -71,7 +71,7 @@ linkBinary = linkBinary' False linkBinary' :: Bool -> Logger -> TmpFs -> DynFlags -> UnitEnv -> [FilePath] -> [UnitId] -> IO () linkBinary' staticLink logger tmpfs dflags unit_env o_files dep_units = do let platform = ue_platform unit_env - unit_state = homeUnitState unit_env + unit_state = ue_homeUnitState unit_env toolSettings' = toolSettings dflags verbFlags = getVerbFlags dflags arch_os = platformArchOS platform ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -452,14 +452,14 @@ renamePkgQual :: UnitEnv -> ModuleName -> Maybe FastString -> PkgQual renamePkgQual unit_env mn mb_pkg = case mb_pkg of Nothing -> NoPkgQual Just pkg_fs - | Just uid <- homeUnitId <$> homeUnit unit_env + | Just uid <- homeUnitId <$> ue_homeUnit unit_env , pkg_fs == fsLit "this" -> ThisPkg uid | Just (uid, _) <- find (fromMaybe False . fmap (== pkg_fs) . snd) home_names -> ThisPkg uid - | Just uid <- resolvePackageImport units mn (PackageName pkg_fs) + | Just uid <- resolvePackageImport unit_state mn (PackageName pkg_fs) -> OtherPkg uid | otherwise @@ -469,10 +469,10 @@ renamePkgQual unit_env mn mb_pkg = case mb_pkg of where home_names = map (\uid -> (uid, mkFastString <$> thisPackageName (homeUnitEnv_dflags (ue_findHomeUnitEnv uid unit_env)))) hpt_deps - units = homeUnitState unit_env + unit_state = ue_homeUnitState unit_env hpt_deps :: [UnitId] - hpt_deps = homeUnitDepends units + hpt_deps = homeUnitDepends unit_state -- | Calculate the 'ImportAvails' induced by an import of a particular ===================================== compiler/GHC/Runtime/Interpreter/JS.hs ===================================== @@ -166,7 +166,7 @@ spawnJSInterp cfg = do -- get the unit-id of the ghci package. We need this to load the -- interpreter code. - ghci_unit_id <- case lookupPackageName (homeUnitState unit_env) (PackageName (fsLit "ghci")) of + ghci_unit_id <- case lookupPackageName (ue_homeUnitState unit_env) (PackageName (fsLit "ghci")) of Nothing -> cmdLineErrorIO "JS interpreter: couldn't find \"ghci\" package" Just i -> pure i @@ -265,7 +265,7 @@ jsLinkInterp logger tmpfs tmp_dir cfg unit_env inst = do let ghci_unit_id = instGhciUnitId (instExtra inst) -- compute unit dependencies of ghc_unit_id - let unit_map = unitInfoMap (homeUnitState unit_env) + let unit_map = unitInfoMap (ue_homeUnitState unit_env) dep_units <- mayThrowUnitErr $ closeUnitDeps unit_map [(ghci_unit_id,Nothing)] let units = dep_units ++ [ghci_unit_id] @@ -304,7 +304,7 @@ jsLinkObjects logger tmpfs tmp_dir cfg unit_env inst objs is_root = do , lcLinkCsources = True -- enable C sources, if any } - let units = preloadUnits (homeUnitState unit_env) + let units = preloadUnits (ue_homeUnitState unit_env) -- compute dependencies let link_spec = LinkSpec ===================================== compiler/GHC/Runtime/Loader.hs ===================================== @@ -215,7 +215,7 @@ loadPlugin' occ_name plugin_name hsc_env mod_name ; case eith_plugin of Left actual_type -> throwGhcExceptionIO (CmdLineError $ - showSDocForUser dflags (homeUnitState (hsc_unit_env hsc_env)) + showSDocForUser dflags (ue_homeUnitState (hsc_unit_env hsc_env)) alwaysQualify $ hsep [ text "The value", ppr name , text "with type", ppr actual_type @@ -346,7 +346,7 @@ lookupRdrNameInModuleForPlugins hsc_env mod_name rdr_name = do let fopts = initFinderOpts dflags let fc = hsc_FC hsc_env let unit_env = hsc_unit_env hsc_env - let unit_state = homeUnitState unit_env + let unit_state = ue_homeUnitState unit_env let mhome_unit = hsc_home_unit_maybe hsc_env -- First find the unit the module resides in by searching exposed units and home modules found_module <- findPluginModule fc fopts unit_state mhome_unit mod_name ===================================== compiler/GHC/StgToJS/Linker/Linker.hs ===================================== @@ -486,7 +486,7 @@ computeLinkDependencies cfg unit_env link_spec finder_opts finder_cache ar_cache Nothing -> -- It's not in the HPT because we are in one shot mode, -- so use the Finder to get a ModLocation... - case homeUnit unit_env of + case ue_homeUnit unit_env of Nothing -> pprPanic "getDeps: No home-unit: " (pprModule mod) Just home_unit -> do mb_stuff <- findHomeModule finder_cache finder_opts home_unit (moduleName mod) @@ -670,7 +670,7 @@ getPackageArchives cfg unit_env units = , l <- getInstalledPackageHsLibs ue_state u ] where - ue_state = homeUnitState unit_env + ue_state = ue_homeUnitState unit_env -- XXX the profiling library name is probably wrong now profSuff | csProf cfg = "_p" ===================================== compiler/GHC/SysTools/Cpp.hs ===================================== @@ -113,7 +113,7 @@ doCpp :: Logger -> TmpFs -> DynFlags -> UnitEnv -> CppOpts -> FilePath -> FilePa doCpp logger tmpfs dflags unit_env opts input_fn output_fn = do let hscpp_opts = picPOpts dflags let cmdline_include_paths = offsetIncludePaths dflags (includePaths dflags) - let unit_state = homeUnitState unit_env + let unit_state = ue_homeUnitState unit_env pkg_include_dirs <- mayThrowUnitErr (collectIncludeDirs <$> preloadUnitsInfo unit_env) -- MP: This is not quite right, the headers which are supposed to be installed in @@ -121,7 +121,7 @@ doCpp logger tmpfs dflags unit_env opts input_fn output_fn = do -- enough approximation for things to work. A proper solution would be to have to declare which paths should -- be propagated to dependent packages. let home_pkg_deps = - [homeUnitEnv_dflags . ue_findHomeUnitEnv uid $ unit_env | uid <- UnitEnv.transitiveHomeDeps (ue_currentUnit unit_env) unit_env] + [homeUnitEnv_dflags . ue_findHomeUnitEnv uid $ unit_env | uid <- ue_transitiveHomeDeps (ue_currentUnit unit_env) unit_env] dep_pkg_extra_inputs = [offsetIncludePaths fs (includePaths fs) | fs <- home_pkg_deps] let include_paths_global = foldr (\ x xs -> ("-I" ++ x) : xs) [] @@ -274,7 +274,7 @@ getGhcVersionPathName dflags unit_env = do -- use a wrong file. See #25106 where a globally installed -- /usr/include/ghcversion.h file was used instead of the one provided -- by the rts. - Nothing -> case lookupUnitId (homeUnitState unit_env) rtsUnitId of + Nothing -> case lookupUnitId (ue_homeUnitState unit_env) rtsUnitId of Nothing -> [] Just info -> ( "ghcversion.h") <$> collectIncludeDirs [info] ===================================== compiler/GHC/Types/Name/Ppr.hs ===================================== @@ -76,8 +76,8 @@ mkNamePprCtx ptc unit_env env (mkQualPackage unit_state) (mkPromTick ptc env) where - unit_state = homeUnitState unit_env - home_unit = homeUnit unit_env + unit_state = ue_homeUnitState unit_env + home_unit = ue_homeUnit unit_env mkQualName :: Outputable info => GlobalRdrEnvX info -> QueryQualifyName mkQualName env = qual_name where ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -10,11 +10,11 @@ -- -- Querying... -- --- This module is meant to be imported qualified as @UnitEnv@: +-- This module is meant to be imported as @UnitEnv@ when calling @insertHpt@: -- -- @ -- import GHC.Unit.Env (UnitEnv, HomeUnitGraph, HomeUnitEnv) --- import qualified GHC.Unit.Env as UnitEnv +-- import GHC.Unit.Env as UnitEnv -- @ -- -- Here is an overview of how the UnitEnv, ModuleGraph, HUG, HPT, and EPS interact: @@ -75,18 +75,18 @@ module GHC.Unit.Env -- ** Modifying the current active home unit , insertHpt - , setFlags + , ue_setFlags -- * Queries -- ** Queries on the current active home unit - , homeUnitState - , homeUnitDbs - , homeUnit - , unitFlags + , ue_homeUnitState + , ue_homeUnitDbs + , ue_homeUnit + , ue_unitFlags -- ** Reachability - , transitiveHomeDeps + , ue_transitiveHomeDeps -------------------------------------------------------------------------------- -- Harder queries for the whole UnitEnv @@ -217,7 +217,7 @@ preloadUnitsInfo' unit_env ids0 = all_infos where unit_state = HUG.homeUnitEnv_units (ue_currentHomeUnitEnv unit_env) ids = ids0 ++ inst_ids - inst_ids = case homeUnit unit_env of + inst_ids = case ue_homeUnit unit_env of Nothing -> [] Just home_unit -- An indefinite package will have insts to HOLE, @@ -258,11 +258,11 @@ ue_findHomeUnitEnv uid e = case HUG.lookupHugUnit uid (ue_home_unit_graph e) of -- Query and modify UnitState of active unit in HomeUnitEnv -- ------------------------------------------------------- -homeUnitState :: HasDebugCallStack => UnitEnv -> UnitState -homeUnitState = HUG.homeUnitEnv_units . ue_currentHomeUnitEnv +ue_homeUnitState :: HasDebugCallStack => UnitEnv -> UnitState +ue_homeUnitState = HUG.homeUnitEnv_units . ue_currentHomeUnitEnv -homeUnitDbs :: UnitEnv -> Maybe [UnitDatabase UnitId] -homeUnitDbs = HUG.homeUnitEnv_unit_dbs . ue_currentHomeUnitEnv +ue_homeUnitDbs :: UnitEnv -> Maybe [UnitDatabase UnitId] +ue_homeUnitDbs = HUG.homeUnitEnv_unit_dbs . ue_currentHomeUnitEnv -- ------------------------------------------------------- -- Query and modify Home Package Table in HomeUnitEnv @@ -288,12 +288,12 @@ ue_updateUnitHUG f ue_env = ue_env { ue_home_unit_graph = f (ue_home_unit_graph -- Query and modify DynFlags in HomeUnitEnv -- ------------------------------------------------------- -unitFlags :: HasDebugCallStack => UnitId -> UnitEnv -> DynFlags -unitFlags uid ue_env = HUG.homeUnitEnv_dflags $ ue_findHomeUnitEnv uid ue_env +ue_unitFlags :: HasDebugCallStack => UnitId -> UnitEnv -> DynFlags +ue_unitFlags uid ue_env = HUG.homeUnitEnv_dflags $ ue_findHomeUnitEnv uid ue_env -- | Sets the 'DynFlags' of the /current unit/ being compiled to the given ones -setFlags :: HasDebugCallStack => DynFlags -> UnitEnv -> UnitEnv -setFlags dflags env = +ue_setFlags :: HasDebugCallStack => DynFlags -> UnitEnv -> UnitEnv +ue_setFlags dflags env = env { ue_home_unit_graph = HUG.updateUnitFlags (ue_currentUnit env) @@ -305,11 +305,11 @@ setFlags dflags env = -- Query and modify home units in HomeUnitEnv -- ------------------------------------------------------- -homeUnit :: UnitEnv -> Maybe HomeUnit -homeUnit = HUG.homeUnitEnv_home_unit . ue_currentHomeUnitEnv +ue_homeUnit :: UnitEnv -> Maybe HomeUnit +ue_homeUnit = HUG.homeUnitEnv_home_unit . ue_currentHomeUnitEnv ue_unsafeHomeUnit :: UnitEnv -> HomeUnit -ue_unsafeHomeUnit ue = case homeUnit ue of +ue_unsafeHomeUnit ue = case ue_homeUnit ue of Nothing -> panic "unsafeGetHomeUnit: No home unit" Just h -> h @@ -375,8 +375,8 @@ renameUnitId oldUnit newUnit unitEnv = -- Transitive closure -- --------------------------------------------- -transitiveHomeDeps :: UnitId -> UnitEnv -> [UnitId] -transitiveHomeDeps uid e = +ue_transitiveHomeDeps :: UnitId -> UnitEnv -> [UnitId] +ue_transitiveHomeDeps uid e = case HUG.transitiveHomeDeps uid (ue_home_unit_graph e) of Nothing -> pprPanic "Unit unknown to the internal unit environment" $ text "unit (" <> ppr uid <> text ")" @@ -461,7 +461,7 @@ in order to allow users to offset their own relative paths. -- * Legacy API -------------------------------------------------------------------------------- -{-# DEPRECATED ue_units "Renamed to homeUnitState" #-} +{-# DEPRECATED ue_units "Renamed to ue_homeUnitState because of confusion between units(tate) and unit(s) plural" #-} ue_units :: HasDebugCallStack => UnitEnv -> UnitState -ue_units = homeUnitState +ue_units = ue_homeUnitState ===================================== compiler/GHC/Unit/Finder.hs ===================================== @@ -215,7 +215,7 @@ findImportedModuleNoHsc fc fopts ue mhome_unit mod_name mb_pkg = findExposedPackageModule fc fopts units mod_name NoPkgQual units = case mhome_unit of - Nothing -> homeUnitState ue + Nothing -> ue_homeUnitState ue Just home_unit -> HUG.homeUnitEnv_units $ ue_findHomeUnitEnv (homeUnitId home_unit) ue hpt_deps :: [UnitId] hpt_deps = homeUnitDepends units View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4d40680b3a75ff89a8496a4d429dfdbc34ad029e...63b6ebb568afc829f495ce5be5759a7a40ffb6ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4d40680b3a75ff89a8496a4d429dfdbc34ad029e...63b6ebb568afc829f495ce5be5759a7a40ffb6ce You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 3 17:57:33 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 03 Jan 2025 12:57:33 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] Good metric decrease Message-ID: <6778250dac940_29547a1f098c9495a@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 9e4e74f9 by Rodrigo Mesquita at 2025-01-03T17:57:09+00:00 Good metric decrease ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 0 changed files: Changes: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e4e74f90d4f568a4e3deddcf8a0671c12dd8a72 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e4e74f90d4f568a4e3deddcf8a0671c12dd8a72 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 3 18:45:26 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Fri, 03 Jan 2025 13:45:26 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] fixup! Rename UnitEnv functions with ue_ Message-ID: <67783046661e2_29547a86a9d41050b4@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 811d5756 by Rodrigo Mesquita at 2025-01-03T18:45:09+00:00 fixup! Rename UnitEnv functions with ue_ - - - - - 1 changed file: - utils/haddock/haddock-api/src/Haddock/Interface/AttachInstances.hs Changes: ===================================== utils/haddock/haddock-api/src/Haddock/Interface/AttachInstances.hs ===================================== @@ -78,7 +78,7 @@ attachInstances expInfo ifaces instIfaceMap isOneShot = do -- -- See https://github.com/haskell/haddock/issues/469. env <- getSession - let mod_to_pkg_conf = moduleNameProvidersMap $ homeUnitState $ hsc_unit_env env + let mod_to_pkg_conf = moduleNameProvidersMap $ ue_homeUnitState $ hsc_unit_env env mods = mkModuleSet [ m View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/811d5756a23b49faf5c7e6a82f02be631eb72496 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/811d5756a23b49faf5c7e6a82f02be631eb72496 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 04:05:33 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 03 Jan 2025 23:05:33 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] add test case for T25611 Message-ID: <6778b38d9fad6_1064361f938cc912fc@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 7737c8ef by Patrick at 2025-01-04T12:05:19+08:00 add test case for T25611 - - - - - 2 changed files: - + testsuite/tests/indexed-types/should_compile/T25611.hs - testsuite/tests/indexed-types/should_compile/all.T Changes: ===================================== testsuite/tests/indexed-types/should_compile/T25611.hs ===================================== @@ -0,0 +1,9 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611 where + +import Data.Kind + +data family Fix :: (k -> Type) -> k +newtype instance Fix f = In { out :: f (Fix f) } ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,4 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('T25611', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7737c8ef1ae0b12270e9d147285f841cb6a1d153 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7737c8ef1ae0b12270e9d147285f841cb6a1d153 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 05:26:56 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 04 Jan 2025 00:26:56 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] add test for T25593 Message-ID: <6778c6a0c4659_9229d7d35fc5639e@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 6a87294c by Patrick at 2025-01-04T13:26:24+08:00 add test for T25593 - - - - - 2 changed files: - + testsuite/tests/indexed-types/should_fail/T25593.hs - + testsuite/tests/indexed-types/should_fail/T25593.stderr Changes: ===================================== testsuite/tests/indexed-types/should_fail/T25593.hs ===================================== @@ -0,0 +1,6 @@ +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +import GHC.Exts + +data family A s a :: UnliftedType +newtype instance A s Int = A_Int (MutVar# s Int) ===================================== testsuite/tests/indexed-types/should_fail/T25593.stderr ===================================== @@ -0,0 +1,5 @@ +T25593.hs:6:1: [GHC-55233] + Newtype instance has non-* return kind ‘UnliftedType’ + In the newtype instance declaration for ‘A’ + Suggested fix: + Perhaps you intended to use the ‘UnliftedNewtypes’ extension \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a87294c0de8c1649d41d3677764a9d0e81d0362 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a87294c0de8c1649d41d3677764a9d0e81d0362 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 05:27:22 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 04 Jan 2025 00:27:22 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] add test for T25593 Message-ID: <6778c6ba57fb7_9229d7ffff856723@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 1f280bd4 by Patrick at 2025-01-04T13:27:14+08:00 add test for T25593 - - - - - 1 changed file: - testsuite/tests/indexed-types/should_fail/all.T Changes: ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -172,3 +172,4 @@ test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T25593', normal, compile_fail, ['']) \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f280bd47e7bdf6a80ea92516efc9245910390e1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f280bd47e7bdf6a80ea92516efc9245910390e1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 05:34:10 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 04 Jan 2025 00:34:10 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Fix T25593 Message-ID: <6778c8526b596_9229d768c705711a@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 578f5c56 by Patrick at 2025-01-04T13:33:56+08:00 Fix T25593 - - - - - 2 changed files: - testsuite/tests/indexed-types/should_fail/T25593.hs - testsuite/tests/indexed-types/should_fail/T25593.stderr Changes: ===================================== testsuite/tests/indexed-types/should_fail/T25593.hs ===================================== @@ -4,3 +4,5 @@ import GHC.Exts data family A s a :: UnliftedType newtype instance A s Int = A_Int (MutVar# s Int) + +newtype B s = B (MutVar# s Int) ===================================== testsuite/tests/indexed-types/should_fail/T25593.stderr ===================================== @@ -1,5 +1,11 @@ -T25593.hs:6:1: [GHC-55233] - Newtype instance has non-* return kind ‘UnliftedType’ - In the newtype instance declaration for ‘A’ - Suggested fix: +T25593.hs:6:1: error: [GHC-55233] + • Newtype instance has non-* return kind ‘UnliftedType’ + • In the newtype instance declaration for ‘A’ + Suggested fix: + Perhaps you intended to use the ‘UnliftedNewtypes’ extension + +T25593.hs:8:1: error: [GHC-55233] + • Newtype has non-* return kind ‘UnliftedType’ + • In the newtype declaration for ‘B’ + Suggested fix: Perhaps you intended to use the ‘UnliftedNewtypes’ extension \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/578f5c565f8b7377be6bc8df163b1b6bd8b85e9d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/578f5c565f8b7377be6bc8df163b1b6bd8b85e9d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 17:39:50 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 04 Jan 2025 12:39:50 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] add test to ensure kind specialization is working as Note [Kind inference for... Message-ID: <6779726685dcb_1f9f592158c3410817f@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 888319b8 by Patrick at 2025-01-05T01:39:36+08:00 add test to ensure kind specialization is working as Note [Kind inference for data family instances] - - - - - 2 changed files: - + testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +-- {-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE GADTs #-} + +module InstanceConKindSpecializationDataFamily where + +import GHC.Prim (Int#) + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the gadt style data instance +-- see Note [Kind inference for data family instances] +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -932,3 +932,4 @@ test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) test('T25597', normal, compile, ['']) +test('InstanceConKindSpecializationDataFamily', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/888319b875a81796cfa9fff4d8d0cd62b386a185 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/888319b875a81796cfa9fff4d8d0cd62b386a185 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 17:43:17 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 04 Jan 2025 12:43:17 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update test InstanceConKindSpecializationDataFamily Message-ID: <67797335884e6_1f9f5922ee6481085f2@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 09abb602 by Patrick at 2025-01-05T01:42:56+08:00 update test InstanceConKindSpecializationDataFamily - - - - - 1 changed file: - testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs Changes: ===================================== testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs ===================================== @@ -10,8 +10,9 @@ import GHC.Prim (Int#) -- | A data family with a kind signature data family T :: forall k. (k->v) -> k -> v --- ensure the kind specialization is correctly handled in the gadt style data instance +-- ensure the kind specialization is correctly handled in the GADT-style data instance -- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors data instance T p q where MkkT :: forall r. r Int -> T r Int MkkV :: forall l. l Int# -> T l Int# View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/09abb6024c317f5c1994aeaac024d8ef7a275a73 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/09abb6024c317f5c1994aeaac024d8ef7a275a73 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 17:44:33 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 04 Jan 2025 12:44:33 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update test InstanceConKindSpecializationDataFamily Message-ID: <677973818c774_1f9f59244c5e41089e0@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 52aa517d by Patrick at 2025-01-05T01:44:24+08:00 update test InstanceConKindSpecializationDataFamily - - - - - 1 changed file: - testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs Changes: ===================================== testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs ===================================== @@ -1,8 +1,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} --- {-# LANGUAGE PolyKinds #-} {-# LANGUAGE MagicHash #-} -{-# LANGUAGE GADTs #-} module InstanceConKindSpecializationDataFamily where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/52aa517d8c9633107ce6684b0b440f16817a8410 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/52aa517d8c9633107ce6684b0b440f16817a8410 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 19:19:47 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sat, 04 Jan 2025 14:19:47 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25623 Message-ID: <677989d37c1da_1f9f592ee12981167f7@gitlab.mail> Brandon Chinn pushed new branch wip/T25623 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25623 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 19:48:55 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sat, 04 Jan 2025 14:48:55 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <677990a7a4269_1f9f593063ff81205b6@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: dfb8b735 by Brandon Chinn at 2025-01-04T11:48:28-08:00 Require alex >= 3.5.2 (#25623) - - - - - 1 changed file: - compiler/ghc.cabal.in Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dfb8b7355a0eb74e24af1f78a2850967427227e7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dfb8b7355a0eb74e24af1f78a2850967427227e7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 19:50:52 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sat, 04 Jan 2025 14:50:52 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <6779911c49f68_1f9f5931d5774121687@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: edb77435 by Brandon Chinn at 2025-01-04T11:50:41-08:00 Require alex >= 3.5.2 (#25623) - - - - - 2 changed files: - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edb77435a2c589aeb4e73b05beaba418192db52f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edb77435a2c589aeb4e73b05beaba418192db52f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 4 22:34:27 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sat, 04 Jan 2025 17:34:27 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <6779b7731fa7b_1a5b326bd85c4024a@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 2182e044 by Brandon Chinn at 2025-01-04T14:34:00-08:00 Require alex >= 3.5.2 (#25623) - - - - - 4 changed files: - .gitlab/ci.sh - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in - hadrian/cabal.project Changes: ===================================== .gitlab/ci.sh ===================================== @@ -8,9 +8,9 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-04T21:29:42Z" MIN_HAPPY_VERSION="1.20" -MIN_ALEX_VERSION="3.2.6" +MIN_ALEX_VERSION="3.5.2.0" TOP="$(pwd)" if [ ! -d "$TOP/.gitlab" ]; then ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-04T21:29:42Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2182e0446e0d93ae8e611f201b767b020e01bcb0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2182e0446e0d93ae8e611f201b767b020e01bcb0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 5 04:01:29 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 04 Jan 2025 23:01:29 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Update Note [Implementation of UnliftedNewtypes] Message-ID: <677a041988aca_2fa4d510f84c852be@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: f81233c6 by Patrick at 2025-01-05T12:01:13+08:00 Update Note [Implementation of UnliftedNewtypes] - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2423,7 +2423,7 @@ There are also some changes for dealing with families: UnliftedNewtypes is on. This allows us to write things like: data family Foo :: TYPE 'IntRep -2. In a newtype instance (with -XUnliftedNewtypes), if the user does +2. In a newtype instance, if the user does not write a kind signature, we want to allow the possibility that the kind is not Type, so we use newOpenTypeKind instead of liftedTypeKind. This is done in tcDataFamInstHeader in GHC.Tc.TyCl.Instance. Example: @@ -2463,7 +2463,16 @@ If we expect the argument to MkA to have kind Type, then we get a kind-mismatch error. The problem is that there is no way to connect this mismatch error to -XUnliftedNewtypes, and suggest enabling the extension. So, instead, we allow the A to type-check, but then find the problem when doing validity checking (and -where we get make a suitable error message). One potential worry is +where we get make a suitable error message). + +The same handling, is done for newtype data instances, resolving #25593. +So the following example would be suggested to enable UnliftedNewtypes: + + -- no UnliftedNewtypes + data family D :: UnliftedType + newtype instance D = MkD Any + +One potential worry is {-# LANGUAGE PolyKinds #-} newtype B a = MkB a @@ -2482,16 +2491,6 @@ the validity checker), that will not happen. But I cannot think of a non-contriv example that will notice this lack of inference, so it seems better to improve error messages than be able to infer this instantiation. -Another place to imrpove the error messages with the same handling is in the case -of a newtype instance, - - -- no UnliftedNewtypes - - data family D :: UnliftedType - newtype instance D = MkD Any - -Here we also want to be suggesting to enable UnliftedNewtypes. So we allow the -possibility that the kind is not Type regardless of whether UnliftedNewtypes is enabled. Note [Implementation of UnliftedDatatypes] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f81233c60e1d9c75ccb9085ba3336054f955720f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f81233c60e1d9c75ccb9085ba3336054f955720f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 5 04:09:25 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 04 Jan 2025 23:09:25 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] format Message-ID: <677a05f59e622_2fa4d54311888562e@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 81bc3068 by Patrick at 2025-01-05T12:09:03+08:00 format - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2491,7 +2491,6 @@ the validity checker), that will not happen. But I cannot think of a non-contriv example that will notice this lack of inference, so it seems better to improve error messages than be able to infer this instantiation. - Note [Implementation of UnliftedDatatypes] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expected behavior of UnliftedDatatypes: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/81bc3068f516585b5fd05b514c998dceb856483a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/81bc3068f516585b5fd05b514c998dceb856483a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 5 07:20:43 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sun, 05 Jan 2025 02:20:43 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update Test `UnliftedNewtypesFamilyKindFail2`, `UnliftedNewtypesInstanceFail`... Message-ID: <677a32cad358c_2fa4d5164235490265@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: ef44934c by Patrick at 2025-01-05T15:20:28+08:00 update Test `UnliftedNewtypesFamilyKindFail2`, `UnliftedNewtypesInstanceFail` for additional warning introduced by reintroduce datafam decls in kind check. - - - - - 2 changed files: - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr Changes: ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef44934cc8de1b5ff84e63e8eaa3085c8620463f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ef44934cc8de1b5ff84e63e8eaa3085c8620463f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 5 09:10:23 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sun, 05 Jan 2025 04:10:23 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] 2 commits: update comment Message-ID: <677a4c7f7f1c7_2fa4d51f2843c94917@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 6ff397a2 by Patrick at 2025-01-05T16:30:00+08:00 update comment - - - - - 4c83df3b by Patrick at 2025-01-05T17:09:56+08:00 Change UnliftedNewtypesUnassociatedFamilyFail to UnliftedNewtypesUnassociatedFamilyInfer. - - - - - 4 changed files: - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/typecheck/should_compile/UnliftedNewtypesUnassociatedFamilyInfer.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -945,10 +945,11 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Add constraints from the result signature ; res_kind <- tc_kind_sig m_ksig - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] - -- Add constraints from the data constructors + -- Fix #25611 + -- But becareful about the GADT style case, + -- do not unify LHS's kind with RHS's kind, + -- See Note [Kind inference for data family instances] ; kcConDecls new_or_data res_kind hs_cons ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesUnassociatedFamilyInfer.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module UnliftedNewtypesUnassociatedFamily where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -696,6 +696,7 @@ test('T505', normal, compile, ['']) test('T12928', normal, compile, ['']) test('UnliftedNewtypesGnd', normal, compile, ['']) test('UnliftedNewtypesUnassociatedFamily', normal, compile, ['']) +test('UnliftedNewtypesUnassociatedFamilyInfer', normal, compile, ['']) test('UnliftedNewtypesUnifySig', normal, compile, ['']) test('UnliftedNewtypesForall', normal, compile, ['']) test('UnlifNewUnify', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ef44934cc8de1b5ff84e63e8eaa3085c8620463f...4c83df3b0f784d27afcef9ccc28a9e3ef461f129 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ef44934cc8de1b5ff84e63e8eaa3085c8620463f...4c83df3b0f784d27afcef9ccc28a9e3ef461f129 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 5 09:10:38 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sun, 05 Jan 2025 04:10:38 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] cleanup Message-ID: <677a4c8e2cbd1_2fa4d52080e74953b5@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 1a850961 by Patrick at 2025-01-05T17:10:25+08:00 cleanup - - - - - 1 changed file: - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr Changes: ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a8509615a9763a5a1169e069c09c94e07530c59 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a8509615a9763a5a1169e069c09c94e07530c59 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 5 16:46:45 2025 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 05 Jan 2025 11:46:45 -0500 Subject: [Git][ghc/ghc][wip/supersven/libdw-test] --enable-dwarf-unwind on CI Message-ID: <677ab775bfc5f_20fc72ea4944838e5@gitlab.mail> Sven Tennie pushed to branch wip/supersven/libdw-test at Glasgow Haskell Compiler / GHC Commits: 82fd1ece by Sven Tennie at 2025-01-05T17:46:35+01:00 --enable-dwarf-unwind on CI Enable it for GHC DWARF builds as the required tools should be around there. - - - - - 2 changed files: - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml Changes: ===================================== .gitlab/generate-ci/gen_ci.hs ===================================== @@ -170,6 +170,7 @@ configureArgsStr bc = unwords $ ++ ["--with-system-libffi" | crossTarget bc == Just "wasm32-wasi" ] ++ ["--enable-ipe-data-compression" | withZstd bc ] ++ ["--enable-strict-ghc-toolchain-check"] + ++ ["--enable-dwarf-unwind" | withDwarf bc] -- Compute the hadrian flavour from the BuildConfig mkJobFlavour :: BuildConfig -> Flavour ===================================== .gitlab/jobs.yaml ===================================== @@ -1780,7 +1780,7 @@ "BIGNUM_BACKEND": "gmp", "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate+debug_info", "BUILD_FLAVOUR": "validate+debug_info", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check --enable-dwarf-unwind", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", "TEST_ENV": "x86_64-linux-deb10-validate+debug_info", @@ -2929,7 +2929,7 @@ "BIGNUM_BACKEND": "gmp", "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-validate+debug_info", "BUILD_FLAVOUR": "validate+debug_info", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check --enable-dwarf-unwind", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "LLC": "/bin/false", "OPT": "/bin/false", @@ -4429,7 +4429,7 @@ "BIGNUM_BACKEND": "gmp", "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-release+debug_info", "BUILD_FLAVOUR": "release+debug_info", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check --enable-dwarf-unwind", "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", @@ -4756,7 +4756,7 @@ "BIGNUM_BACKEND": "gmp", "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-release+debug_info", "BUILD_FLAVOUR": "release+debug_info", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check --enable-dwarf-unwind", "HADRIAN_ARGS": "--hash-unit-ids", "IGNORE_PERF_FAILURES": "all", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", @@ -6046,7 +6046,7 @@ "BIGNUM_BACKEND": "gmp", "BIN_DIST_NAME": "ghc-x86_64-linux-deb10-validate+debug_info", "BUILD_FLAVOUR": "validate+debug_info", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check --enable-dwarf-unwind", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "RUNTEST_ARGS": "", "TEST_ENV": "x86_64-linux-deb10-validate+debug_info" @@ -7179,7 +7179,7 @@ "BIGNUM_BACKEND": "gmp", "BIN_DIST_NAME": "ghc-x86_64-linux-fedora33-validate+debug_info", "BUILD_FLAVOUR": "validate+debug_info", - "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", + "CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check --enable-dwarf-unwind", "INSTALL_CONFIGURE_ARGS": "--enable-strict-ghc-toolchain-check", "LLC": "/bin/false", "OPT": "/bin/false", View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/82fd1ece3b2f10e1120ec8cbc4e4682a2a69d74f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/82fd1ece3b2f10e1120ec8cbc4e4682a2a69d74f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 5 17:29:55 2025 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sun, 05 Jan 2025 12:29:55 -0500 Subject: [Git][ghc/ghc][wip/supersven/riscv-vectors] 6 commits: Add documentation Message-ID: <677ac1936de30_1fc74924de0c8602d@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-vectors at Glasgow Haskell Compiler / GHC Commits: 33e480c7 by Sven Tennie at 2024-12-31T11:23:06+01:00 Add documentation - - - - - 828b3660 by Sven Tennie at 2024-12-31T17:37:13+01:00 Cleanup CodeGen - - - - - a6edfc38 by Sven Tennie at 2024-12-31T18:03:39+01:00 Add TODOs - - - - - 3a426a77 by Sven Tennie at 2025-01-05T18:05:59+01:00 Add comment about freeReg for [X,Y,Z]MM - - - - - 97755f41 by Sven Tennie at 2025-01-05T18:07:32+01:00 Define MAX_REAL_YMM_REG and MAX_REAL_ZMM_REG - - - - - 91169343 by Sven Tennie at 2025-01-05T18:28:30+01:00 VID needs only one register; fix MO_V_Broadcast; refactor MO_V_Insert and MO_V_Insert - - - - - 6 changed files: - compiler/CodeGen.Platform.h - compiler/GHC/CmmToAsm/RV64/CodeGen.hs - compiler/GHC/CmmToAsm/RV64/Instr.hs - compiler/GHC/CmmToAsm/RV64/Ppr.hs - docs/users_guide/using.rst - rts/include/stg/MachRegs.h Changes: ===================================== compiler/CodeGen.Platform.h ===================================== @@ -1253,6 +1253,8 @@ freeReg REG_D5 = False freeReg REG_D6 = False # endif +-- N.B. XMM* YMM* and ZMM* refer to the same registers on RISCV64. Thus, +-- defining freeReg for one vector register size is good enough. # if defined(REG_XMM1) freeReg REG_XMM1 = False # endif ===================================== compiler/GHC/CmmToAsm/RV64/CodeGen.hs ===================================== @@ -660,14 +660,16 @@ getRegister' config plat expr = Amode addr addr_code <- getAmode plat width mem case (width, format) of (_w, f) - | VecFormat l vf <- f -> + | isVecFormat f -> + -- TODO: Check for configured vectorMinBits pure ( Any format ( \dst -> - unitOL (COMMENT (text "XXX here")) `appOL` addr_code `snocOL` annExpr expr + -- We pattern match on the format in the pretty-printer. + -- So, we can here simply emit LDRU for all vectors. (LDRU format (OpReg width dst) (OpAddr addr)) ) ) @@ -682,22 +684,7 @@ getRegister' config plat expr = `snocOL` LDRU format (OpReg width dst) (OpAddr addr) ) ) - -- TODO: Load vector - instructions VLW, VLB, VLH, ... Encode in ppr of LDRU? - -- riscv64-unknown-linux-gnu-ghc: panic! (the 'impossible' happened) - -- GHC version 9.13.20241013: - -- Width too big! Cannot load: W128 - -- Fx2V128[Sp + 8] - -- Call stack: - -- CallStack (from HasCallStack): - -- callStackDoc, called at compiler/GHC/Utils/Panic.hs:190:37 in ghc-9.13-inplace:GHC.Utils.Panic - -- pprPanic, called at compiler/GHC/CmmToAsm/RV64/CodeGen.hs:678:11 in ghc-9.13-inplace:GHC.CmmToAsm.RV64.CodeGen - -- CallStack (from HasCallStack): - -- panic, called at compiler/GHC/Utils/Error.hs:507:29 in ghc-9.13-inplace:GHC.Utils.Error - - -- Fx2V128 -> cat= Float, length = 2, widthInBits = 128 - - _ -> - pprPanic ("Width too big! Cannot load: " ++ show width) (pdoc plat expr) + _ -> pprPanic ("Width too big! Cannot load: " ++ show width) (pdoc plat expr) CmmStackSlot _ _ -> pprPanic "getRegister' (CmmStackSlot): " (pdoc plat expr) CmmReg reg -> @@ -839,7 +826,7 @@ getRegister' config plat expr = MO_V_Broadcast length w -> do (reg_val, format_val, code_val) <- getSomeReg e let w_val = formatToWidth format_val - pure $ Any (vecFormat (cmmVec length (cmmFloat w))) $ \dst -> + pure $ Any (vecFormat (cmmVec length (cmmBits w))) $ \dst -> code_val `snocOL` annExpr expr (VMV (VecFormat length (intScalarFormat w)) (OpReg w dst) (OpReg w_val reg_val)) @@ -1324,53 +1311,9 @@ getRegister' config plat expr = -- ret -- -- https://godbolt.org/z/sEG8MrM8P - MO_VF_Insert length w -> - do - (reg_v, format_v, code_v) <- getSomeReg x - (reg_f, format_f, code_f) <- getFloatReg y - (reg_idx, format_idx, code_idx) <- getSomeReg z - (reg_l, format_l, code_l) <- getSomeReg (CmmLit (CmmInt (toInteger length) W64)) - tmp <- getNewRegNat (VecFormat length (floatScalarFormat w)) - let targetFormat = VecFormat length (floatScalarFormat w) - pure $ Any targetFormat $ \dst -> - code_v `appOL` - code_f `appOL` - code_idx `appOL` - code_l `snocOL` - annExpr expr - -- Build mask for index - -- 1. fill elements with index numbers - -- TODO: The Width is made up - (VID (VecFormat length (intScalarFormat w)) (OpReg W8 v0Reg) (OpReg (formatToWidth format_l) reg_l)) `snocOL` - -- 2. Splat value into tmp vector - VMV (VecFormat length (floatScalarFormat w)) (OpReg w tmp) (OpReg (formatToWidth format_f) reg_f) `snocOL` - -- 3. Merge with mask -> set element at index - VMSEQ (VecFormat length (floatScalarFormat w)) (OpReg W8 v0Reg) (OpReg W8 v0Reg) (OpReg (formatToWidth format_idx) reg_idx) `snocOL` - VMERGE (VecFormat length (floatScalarFormat w)) (OpReg w dst) (OpReg (formatToWidth format_v) reg_v) (OpReg w tmp) (OpReg W8 v0Reg) - -- TODO: Duplication with MO_VF_Insert - MO_V_Insert length w -> - do - (reg_v, format_v, code_v) <- getSomeReg x - (reg_f, format_f, code_f) <- getSomeReg y - (reg_idx, format_idx, code_idx) <- getSomeReg z - (reg_l, format_l, code_l) <- getSomeReg (CmmLit (CmmInt (toInteger length) W64)) - tmp <- getNewRegNat (VecFormat length (intScalarFormat w)) - let targetFormat = VecFormat length (intScalarFormat w) - pure $ Any targetFormat $ \dst -> - code_v `appOL` - code_f `appOL` - code_idx `appOL` - code_l `snocOL` - annExpr expr - -- Build mask for index - -- 1. fill elements with index numbers - -- TODO: The Width is made up - (VID (VecFormat length (intScalarFormat w)) (OpReg W8 v0Reg) (OpReg (formatToWidth format_l) reg_l)) `snocOL` - -- 2. Splat value into tmp vector - VMV (VecFormat length (intScalarFormat w)) (OpReg w tmp) (OpReg (formatToWidth format_f) reg_f) `snocOL` - -- 3. Merge with mask -> set element at index - VMSEQ (VecFormat length (intScalarFormat w)) (OpReg W8 v0Reg) (OpReg W8 v0Reg) (OpReg (formatToWidth format_idx) reg_idx) `snocOL` - VMERGE (VecFormat length (intScalarFormat w)) (OpReg w dst) (OpReg (formatToWidth format_v) reg_v) (OpReg w tmp) (OpReg W8 v0Reg) + MO_VF_Insert length width ->vecInsert floatScalarFormat length width + + MO_V_Insert length width -> vecInsert intScalarFormat length width _ -> pprPanic "getRegister' (unhandled ternary CmmMachOp): " @@ -1378,6 +1321,31 @@ getRegister' config plat expr = <+> text "in" <+> pdoc plat expr where + vecInsert :: (Width -> ScalarFormat) -> Int -> Width -> NatM Register + vecInsert widthToScalarFormat length width = + do + let targetVecFormat = VecFormat length (widthToScalarFormat width) + (reg_v, format_v, code_v) <- getSomeReg x + (reg_f, format_f, code_f) <- getSomeReg y + (reg_idx, format_idx, code_idx) <- getSomeReg z + tmp <- getNewRegNat targetVecFormat + pure $ Any targetVecFormat $ \dst -> + code_v `appOL` + code_f `appOL` + code_idx `snocOL` + annExpr expr + -- 1. fill elements with index numbers + -- TODO: The Width is made up + -- TODO: Is it safe to use v0 (default mask register) here? Instructions may be shuffled around... + -- Can we use an explicitly fetched register as mask (depends on instructions)? + (VID targetVecFormat (OpReg W8 v0Reg)) `snocOL` + -- 2. Build mask + VMSEQ targetVecFormat(OpReg W8 v0Reg) (OpReg W8 v0Reg) (OpReg (formatToWidth format_idx) reg_idx) `snocOL` + -- 3. Splat value into tmp vector + VMV targetVecFormat (OpReg width tmp) (OpReg (formatToWidth format_f) reg_f) `snocOL` + -- 4. Merge with mask -> set element at index + VMERGE targetVecFormat (OpReg width dst) (OpReg (formatToWidth format_v) reg_v) (OpReg width tmp) (OpReg W8 v0Reg) + float3Op w op = do (reg_fx, format_x, code_fx) <- getFloatReg x (reg_fy, format_y, code_fy) <- getFloatReg y @@ -1474,6 +1442,18 @@ getRegister' config plat expr = unitOL $ annExpr expr (ADD (OpReg w dst) zero (OpImm (ImmInt 1))) ) +-- TODO: Missing MachOps: +-- - MO_V_Add +-- - MO_V_Sub +-- - MO_V_Mul +-- - MO_VS_Quot +-- - MO_VS_Rem +-- - MO_VS_Neg +-- - MO_VU_Quot +-- - MO_VU_Rem +-- - MO_V_Shuffle +-- - MO_VF_Shuffle + -- | Instructions to sign-extend the value in the given register from width @w@ -- up to width @w'@. signExtendReg :: Width -> Width -> Reg -> NatM (Reg, OrdList Instr) ===================================== compiler/GHC/CmmToAsm/RV64/Instr.hs ===================================== @@ -110,7 +110,7 @@ regUsageOfInstr platform instr = case instr of FMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) FMAX dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) VMV fmt dst src1 -> usage (regOp src1, regOp dst) - VID fmt dst src1 -> usage (regOp src1, regOp dst) + VID fmt dst -> usage ([], regOp dst) VMSEQ fmt dst src op -> usage (regOp src ++ regOp op, regOp dst) VMERGE fmt dst op1 op2 opm -> usage (regOp op1 ++ regOp op2 ++ regOp opm, regOp dst) VSLIDEDOWN fmt dst op1 op2 -> usage (regOp op1 ++ regOp op2, regOp dst) @@ -231,7 +231,7 @@ patchRegsOfInstr instr env = case instr of FMIN o1 o2 o3 -> FMIN (patchOp o1) (patchOp o2) (patchOp o3) FMAX o1 o2 o3 -> FMAX (patchOp o1) (patchOp o2) (patchOp o3) VMV fmt o1 o2 -> VMV fmt (patchOp o1) (patchOp o2) - VID fmt o1 o2 -> VID fmt (patchOp o1) (patchOp o2) + VID fmt o1 -> VID fmt (patchOp o1) VMSEQ fmt o1 o2 o3 -> VMSEQ fmt (patchOp o1) (patchOp o2) (patchOp o3) VMERGE fmt o1 o2 o3 o4 -> VMERGE fmt (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) VSLIDEDOWN fmt o1 o2 o3 -> VSLIDEDOWN fmt (patchOp o1) (patchOp o2) (patchOp o3) @@ -676,7 +676,7 @@ data Instr -- TODO: Care about the variants (.x.y) -> sum type | VMV Format Operand Operand - | VID Format Operand Operand + | VID Format Operand | VMSEQ Format Operand Operand Operand | VMERGE Format Operand Operand Operand Operand | VSLIDEDOWN Format Operand Operand Operand ===================================== compiler/GHC/CmmToAsm/RV64/Ppr.hs ===================================== @@ -750,7 +750,7 @@ pprInstr platform instr = case instr of | isVectorRegOp o1 && isVectorRegOp o2 -> configVec fmt $$ op2 (text "\tvmv" <> dot <> opToVInstrSuffix o1 <> dot <> text "v") o1 o2 | True -> pprPanic "RV64.pprInstr - impossible vector move (VMV)" (pprOp platform o1 <+> pprOp platform o2 <+> text "fmt" <> colon <> (text . show) fmt) -- TODO: Remove o2 from constructor - VID fmt o1 _o2 -> configVec fmt $$ op1 (text "\tvid.v") o1 + VID fmt o1 -> configVec fmt $$ op1 (text "\tvid.v") o1 -- TODO: This expects int register as third operand: Generalize by calculating -- the instruction suffix (".vx") VMSEQ fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvmseq.vx") o1 o2 o3 ===================================== docs/users_guide/using.rst ===================================== @@ -1743,6 +1743,37 @@ Some flags only make sense for particular target platforms. multiply-add, which might perform non-IEEE-compliant software emulation on some platforms (depending on the implementation of the C standard library). +.. ghc-flag:: -mvector-min-width-bits + :shortdesc: (RISC-V NCG only) Minimal width of vector registers in bits + :type: dynamic + :category: platform-options + + :default: Not set, which implies that no vector registers are used. + + :since: 9.12.2 + + Though the RISC-V ISA supports dynamic configuration of vector registers via + "grouping", the GHC register allocators need to know what they can manage. + In RISC-V terms the value is the smallest VLEN of the machines the program + should be executed on. + + Possible values are ``128``, ``256`` and ``512`` (these values are due to + internal alignment with other architectures.) + + The question of "How big are my vector registers?" frequently appears in + other architectures as well. So, it could be that this parameter will be + useful for other architectures in future GHC versions. Right now, it is only + used by the native code generator (NCG) of RISC-V 64. + + GHC only supports the "'V' Standard Extension for Vector Operations, Version + 1.0" as defined in "The RISC-V Instruction Set - Manual Volume I". Vendor + specific extensions and older standards are not supported. (There are still + many machines with older standard implementations around. If in doubt, check + your machine specification.) + + This flag also enables vector operation support in the RISC-V NCG. Some + programs with vector specific code cannot be compiled without it. + Haddock ------- ===================================== rts/include/stg/MachRegs.h ===================================== @@ -219,6 +219,42 @@ # endif #endif +#if !defined(MAX_REAL_YMM_REG) +# if defined(REG_YMM6) +# define MAX_REAL_YMM_REG 6 +# elif defined(REG_YMM5) +# define MAX_REAL_YMM_REG 5 +# elif defined(REG_YMM4) +# define MAX_REAL_YMM_REG 4 +# elif defined(REG_YMM3) +# define MAX_REAL_YMM_REG 3 +# elif defined(REG_YMM2) +# define MAX_REAL_YMM_REG 2 +# elif defined(REG_YMM1) +# define MAX_REAL_YMM_REG 1 +# else +# define MAX_REAL_YMM_REG 0 +# endif +#endif + +#if !defined(MAX_REAL_ZMM_REG) +# if defined(REG_ZMM6) +# define MAX_REAL_ZMM_REG 6 +# elif defined(REG_ZMM5) +# define MAX_REAL_ZMM_REG 5 +# elif defined(REG_ZMM4) +# define MAX_REAL_ZMM_REG 4 +# elif defined(REG_ZMM3) +# define MAX_REAL_ZMM_REG 3 +# elif defined(REG_ZMM2) +# define MAX_REAL_ZMM_REG 2 +# elif defined(REG_ZMM1) +# define MAX_REAL_ZMM_REG 1 +# else +# define MAX_REAL_ZMM_REG 0 +# endif +#endif + /* define NO_ARG_REGS if we have no argument registers at all (we can * optimise certain code paths using this predicate). */ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/158c705ba6815789b47819ce3df93d5240758d94...91169343d138c1afd81ee9aaa04711b9659d731b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/158c705ba6815789b47819ce3df93d5240758d94...91169343d138c1afd81ee9aaa04711b9659d731b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 5 23:45:22 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Sun, 05 Jan 2025 18:45:22 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25630 Message-ID: <677b1992a2612_1fc74925a475c949c6@gitlab.mail> Simon Peyton Jones pushed new branch wip/T25630 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25630 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 01:15:44 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sun, 05 Jan 2025 20:15:44 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <677b2ec0485bb_de0dd72621c1009ee@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 140f9d22 by Brandon Chinn at 2025-01-05T17:15:27-08:00 Require alex >= 3.5.2 (#25623) - - - - - 5 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in - hadrian/cabal.project Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: eb4d3389fd62e4f7321a0c8799014ec1f4da0708 + DOCKER_REV: f8b8b8910097a88185835e0c929b8bb03fadfe61 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/ci.sh ===================================== @@ -8,9 +8,9 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-04T21:29:42Z" MIN_HAPPY_VERSION="1.20" -MIN_ALEX_VERSION="3.2.6" +MIN_ALEX_VERSION="3.5.2.0" TOP="$(pwd)" if [ ! -d "$TOP/.gitlab" ]; then ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-04T21:29:42Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/140f9d2208cd6b15a9af55996016bb2f8aa99591 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/140f9d2208cd6b15a9af55996016bb2f8aa99591 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 10:19:29 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Mon, 06 Jan 2025 05:19:29 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/bump-xxhash Message-ID: <677bae313b86_18a55d212e60637aa@gitlab.mail> Cheng Shao pushed new branch wip/bump-xxhash at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bump-xxhash You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 12:32:28 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 06 Jan 2025 07:32:28 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] Ordering of graph Message-ID: <677bcd5c83ce2_3c9538694589454@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: 1d910b5e by Matthew Pickering at 2025-01-06T12:19:34+00:00 Ordering of graph - - - - - 20 changed files: - compiler/GHC/Data/Graph/Directed/Reachability.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Unit/Module/Graph.hs - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr - testsuite/tests/backpack/should_fail/bkpfail07.stderr - testsuite/tests/backpack/should_fail/bkpfail12.stderr - testsuite/tests/backpack/should_fail/bkpfail13.stderr - testsuite/tests/backpack/should_fail/bkpfail14.stderr - testsuite/tests/backpack/should_fail/bkpfail15.stderr - testsuite/tests/backpack/should_fail/bkpfail21.stderr - testsuite/tests/count-deps/CountDepsAst.stdout - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits002.stdout - testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits003.stdout Changes: ===================================== compiler/GHC/Data/Graph/Directed/Reachability.hs ===================================== @@ -7,7 +7,7 @@ module GHC.Data.Graph.Directed.Reachability , graphReachability, cyclicGraphReachability -- * Reachability queries - , allReachable, allReachableMany, allReachableManyWithRoots + , allReachable, allReachableMany , isReachable, isReachableMany ) where @@ -132,23 +132,6 @@ allReachableMany (ReachabilityIndex index from to) roots = map from (IS.toList h hits = {-# SCC "allReachableMany" #-} IS.unions $ map (expectJust "reachablesG" . flip IM.lookup index) roots_i --- | 'allReachableManyWithRoots' returns all nodes reachable from the many given @roots at . --- --- Properties: --- * The list of nodes includes the @roots@ node! --- * The list of nodes is deterministically ordered, but according to an --- internal order determined by the indices attributed to graph nodes. --- * This function has $O(n)$ complexity where $n$ is the number of @roots at . --- --- If you need a topologically sorted list, consider using the functions --- exposed from 'GHC.Data.Graph.Directed' on 'Graph' instead ('reachableG'). -allReachableManyWithRoots :: ReachabilityIndex node -> [node] {-^ The @roots@ -} -> [node] {-^ All nodes reachable from all @roots@ -} -allReachableManyWithRoots (ReachabilityIndex index from to) roots = map from (IS.toList hits) - where roots_i = [ v | Just v <- map to roots ] - hits = IS.union (IS.fromList roots_i) - (IS.unions $ map (expectJust "reachablesG" . flip IM.lookup index) roots_i) - - -- | Fast reachability query. -- -- On graph @g@ with nodes @a@ and @b@, @isReachable g a b@ ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -750,8 +750,11 @@ hsunitModuleGraph do_link unit = do if Set.member mod_name hsig_set then return Nothing else fmap Just $ summariseRequirement pn mod_name - - let graph_nodes = nodes ++ req_nodes ++ (instantiationNodes (homeUnitId $ hsc_home_unit hsc_env) (hsc_units hsc_env)) + let inodes = instantiationNodes (homeUnitId $ hsc_home_unit hsc_env) (hsc_units hsc_env) + -- TODO: Backpack mode does not properly support ExternalPackage nodes yet + -- Module nodes do not get given package dependencies (see hsModuleToModSummary). + let pkg_nodes = ordNub $ map (\(_, iud) -> PackageNode [] (instUnitInstanceOf iud)) inodes + let graph_nodes = nodes ++ req_nodes ++ (map (uncurry InstantiationNode) $ inodes) ++ pkg_nodes key_nodes = map mkNodeKey graph_nodes all_nodes = graph_nodes ++ [LinkNode key_nodes (homeUnitId $ hsc_home_unit hsc_env) | do_link] -- This error message is not very good but .bkp mode is just for testing so ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -264,8 +264,8 @@ depanalPartial diag_wrapper msg excluded_mods allow_dup_roots = do -- In the future, perhaps more of the work of instantiation could be moved here, -- instead of shoved in with the module compilation nodes. That could simplify -- backpack, and maybe hs-boot too. -instantiationNodes :: UnitId -> UnitState -> [ModuleGraphNode] -instantiationNodes uid unit_state = InstantiationNode uid <$> iuids_to_check +instantiationNodes :: UnitId -> UnitState -> [(UnitId, InstantiatedUnit)] +instantiationNodes uid unit_state = map (uid,) iuids_to_check where iuids_to_check :: [InstantiatedUnit] iuids_to_check = @@ -1500,16 +1500,21 @@ topSortModuleGraph drop_hs_boot_nodes module_graph mb_root_mod = -- Module nodes must be in reverse lexigraphic order. -- All modules nodes must appear before package nodes or link nodes. -- + -- MP: This is just the ordering which the tests needed in Jan 2025, it does + -- not arise from nature. + -- -- Given the current implementation of scc, the result is in -- The order is sensitive to the internal implementation in Data.Graph, -- if it changes in future then this ordering will need to be modified. - cmpModuleGraphNodes (NodeKey_Module k1) (NodeKey_Module k2) = compare k2 k1 - cmpModuleGraphNodes (NodeKey_Link uid1) (NodeKey_Link uid2) = compare uid2 uid1 - cmpModuleGraphNodes (NodeKey_Link {}) _ = LT - cmpModuleGraphNodes _ (NodeKey_Link {}) = GT - cmpModuleGraphNodes (NodeKey_Module {}) _ = LT - cmpModuleGraphNodes _ (NodeKey_Module {}) = GT - cmpModuleGraphNodes n1 n2 = compare n2 n1 + moduleGraphNodeRank k = + case k of + NodeKey_Unit {} -> 0 + NodeKey_Module {} -> 1 + NodeKey_Link {} -> 2 + NodeKey_ExternalUnit {} -> 3 + + cmpModuleGraphNodes k1 k2 = compare (moduleGraphNodeRank k1) (moduleGraphNodeRank k2) + `mappend` compare k2 k1 topSortModules :: Bool -> [ModuleGraphNode] -> Maybe HomeUnitModule -> [SCC ModuleGraphNode] topSortModules drop_hs_boot_nodes summaries mb_root_mod @@ -1632,12 +1637,14 @@ downsweep_imports hsc_env old_summaries excl_mods allow_dup_roots (root_errs, ro let root_map = mkRootMap rootSummariesOk checkDuplicates root_map (deps, map0) <- loopSummaries rootSummariesOk (M.empty, root_map) + let all_instantiations = getHomeUnitInstantiations hsc_env + let deps' = loopInstantiations all_instantiations deps let closure_errs = checkHomeUnitsClosed unit_env unit_env = hsc_unit_env hsc_env tmpfs = hsc_tmpfs hsc_env downsweep_errs = lefts $ concat $ M.elems map0 - downsweep_nodes = M.elems deps + downsweep_nodes = M.elems deps' (other_errs, unit_nodes) = partitionEithers $ unitEnv_foldWithKey (\nodes uid hue -> nodes ++ unitModuleNodes downsweep_nodes uid hue) [] (hsc_HUG hsc_env) all_nodes = downsweep_nodes ++ unit_nodes @@ -1653,12 +1660,13 @@ downsweep_imports hsc_env old_summaries excl_mods allow_dup_roots (root_errs, ro then return (all_errs, th_enabled_nodes) else pure $ (all_root_errs, emptyMG) where + getHomeUnitInstantiations :: HscEnv -> [(UnitId, InstantiatedUnit)] + getHomeUnitInstantiations hsc_env = unitEnv_foldWithKey (\nodes uid hue -> nodes ++ instantiationNodes uid (homeUnitEnv_units hue)) [] (hsc_HUG hsc_env) + -- Dependencies arising on a unit (backpack and module linking deps) unitModuleNodes :: [ModuleGraphNode] -> UnitId -> HomeUnitEnv -> [Either (Messages DriverMessage) ModuleGraphNode] unitModuleNodes summaries uid hue = - let instantiation_nodes = instantiationNodes uid (homeUnitEnv_units hue) - in map Right instantiation_nodes - ++ maybeToList (linkNodes (instantiation_nodes ++ summaries) uid hue) + maybeToList (linkNodes summaries uid hue) calcDeps ms = -- Add a dependency on the HsBoot file if it exists @@ -1684,6 +1692,20 @@ downsweep_imports hsc_env old_summaries excl_mods allow_dup_roots (root_errs, ro dup_roots :: [[ModSummary]] -- Each at least of length 2 dup_roots = filterOut isSingleton $ map rights (M.elems root_map) + loopInstantiations :: [(UnitId, InstantiatedUnit)] + -> M.Map NodeKey ModuleGraphNode + -> M.Map NodeKey ModuleGraphNode + loopInstantiations [] done = done + loopInstantiations ((home_uid, iud) :xs) done = + let hsc_env' = hscSetActiveHomeUnit home_unit hsc_env + done' = loopUnit hsc_env' done [instUnitInstanceOf iud] + payload = InstantiationNode home_uid iud + in loopInstantiations xs (M.insert (mkNodeKey payload) payload done') + + where + home_unit = ue_unitHomeUnit home_uid (hsc_unit_env hsc_env) + + -- This loops over all the mod summaries in the dependency graph, accumulates the actual dependencies for each module/unit loopSummaries :: [ModSummary] -> (M.Map NodeKey ModuleGraphNode, ===================================== compiler/GHC/Unit/Module/Graph.hs ===================================== @@ -206,7 +206,8 @@ mgNodeDependencies :: Bool -> ModuleGraphNode -> [NodeKey] mgNodeDependencies drop_hs_boot_nodes = \case LinkNode deps _uid -> deps InstantiationNode uid iuid -> - NodeKey_Module . (\mod -> ModNodeKeyWithUid (GWIB mod NotBoot) uid) <$> uniqDSetToList (instUnitHoles iuid) + [ NodeKey_Module (ModNodeKeyWithUid (GWIB mod NotBoot) uid) | mod <- uniqDSetToList (instUnitHoles iuid) ] + ++ [ NodeKey_ExternalUnit (instUnitInstanceOf iuid) ] ModuleNode deps _ms -> map drop_hs_boot deps PackageNode deps _ -> map NodeKey_ExternalUnit deps ===================================== testsuite/tests/backpack/reexport/bkpreex02.stderr ===================================== @@ -23,8 +23,8 @@ Instantiating p[H=r-impl:H,T=r-impl:T] [1 of 2] Compiling T[sig] ( p/T.hsig, nothing ) [2 of 2] Compiling H[sig] ( p/H.hsig, nothing ) - [1 of 4] Compiling T[sig] ( q/T.hsig, nothing ) - [2 of 4] Compiling H[sig] ( q/H.hsig, nothing ) - [3 of 4] Compiling A ( q/A.hs, nothing ) + [1 of 4] Compiling H[sig] ( q/H.hsig, nothing ) + [2 of 4] Compiling A ( q/A.hs, nothing ) + [3 of 4] Compiling T[sig] ( q/T.hsig, nothing ) [4 of 4] Instantiating p [1 of 1] Instantiating q ===================================== testsuite/tests/backpack/reexport/bkpreex03.stdout ===================================== @@ -1,6 +1,6 @@ [1 of 1] Processing p [1 of 3] Compiling M1 - [2 of 3] Compiling M2 - [3 of 3] Compiling A[sig] + [2 of 3] Compiling A[sig] + [3 of 3] Compiling M2 [1 of 1] Processing p [3 of 3] Compiling A[sig] [M2 added] ===================================== testsuite/tests/backpack/should_compile/bkp14.stderr ===================================== @@ -1,7 +1,7 @@ [1 of 3] Processing p [1 of 3] Compiling H[sig] ( p/H.hsig, nothing ) - [2 of 3] Compiling Y[sig] ( p/Y.hsig, nothing ) - [3 of 3] Compiling M ( p/M.hs, nothing ) + [2 of 3] Compiling M ( p/M.hs, nothing ) + [3 of 3] Compiling Y[sig] ( p/Y.hsig, nothing ) [2 of 3] Processing impl Instantiating impl [1 of 2] Compiling F ( impl/F.hs, bkp14.out/impl/F.o ) ===================================== testsuite/tests/backpack/should_compile/bkp31.stderr ===================================== @@ -2,8 +2,8 @@ [1 of 2] Compiling A[sig] ( ab-sigs/A.hsig, nothing ) [2 of 2] Compiling B[sig] ( ab-sigs/B.hsig, nothing ) [2 of 2] Processing abcd-holes - [1 of 5] Compiling C ( abcd-holes/C.hs, nothing ) + [1 of 5] Compiling A[sig] ( abcd-holes/A.hsig, nothing ) [2 of 5] Compiling B[sig] ( abcd-holes/B.hsig, nothing ) - [3 of 5] Compiling A[sig] ( abcd-holes/A.hsig, nothing ) + [3 of 5] Compiling C ( abcd-holes/C.hs, nothing ) [4 of 5] Compiling D ( abcd-holes/D.hs, nothing ) [5 of 5] Instantiating ab-sigs ===================================== testsuite/tests/backpack/should_compile/bkp32.stderr ===================================== @@ -8,8 +8,8 @@ [1 of 6] Compiling Prel[sig] ( structures/Prel.hsig, nothing ) [2 of 6] Compiling Array[sig] ( structures/Array.hsig, nothing ) [3 of 6] Compiling Graph ( structures/Graph.hs, nothing ) - [4 of 6] Compiling Tree ( structures/Tree.hs, nothing ) - [5 of 6] Compiling Set ( structures/Set.hs, nothing ) + [4 of 6] Compiling Set ( structures/Set.hs, nothing ) + [5 of 6] Compiling Tree ( structures/Tree.hs, nothing ) [6 of 6] Instantiating arrays-sig [ 4 of 11] Processing arrays-a [1 of 3] Compiling Prel[sig] ( arrays-a/Prel.hsig, nothing ) ===================================== testsuite/tests/backpack/should_compile/bkp51.stderr ===================================== @@ -5,12 +5,12 @@ [3 of 3] Compiling AA ( p/AA.hs, bkp51.out/p/AA.o ) [2 of 6] Processing q [1 of 3] Compiling B[sig] ( q/B.hsig, nothing ) - [2 of 3] Compiling H[sig] ( q/H.hsig, nothing ) - [3 of 3] Compiling C ( q/C.hs, nothing ) + [2 of 3] Compiling C ( q/C.hs, nothing ) + [3 of 3] Compiling H[sig] ( q/H.hsig, nothing ) [3 of 6] Processing r - [1 of 4] Compiling H[sig] ( r/H.hsig, nothing ) - [2 of 4] Compiling B[sig] ( r/B.hsig, nothing ) - [3 of 4] Compiling D ( r/D.hs, nothing ) + [1 of 4] Compiling B[sig] ( r/B.hsig, nothing ) + [2 of 4] Compiling D ( r/D.hs, nothing ) + [3 of 4] Compiling H[sig] ( r/H.hsig, nothing ) [4 of 4] Instantiating q [4 of 6] Processing s [1 of 3] Compiling H[sig] ( s/H.hsig, nothing ) ===================================== testsuite/tests/backpack/should_fail/bkpfail07.stderr ===================================== @@ -1,14 +1,13 @@ [1 of 3] Processing p - [1 of 1] Compiling H[sig] ( p\H.hsig, nothing ) + [1 of 1] Compiling H[sig] ( p/H.hsig, nothing ) [2 of 3] Processing h - [1 of 3] Compiling T ( h\T.hs, nothing ) - [2 of 3] Compiling H ( h\H.hs, nothing ) - [3 of 3] Compiling A[sig] ( h\A.hsig, nothing ) + [1 of 3] Compiling A[sig] ( h/A.hsig, nothing ) + [2 of 3] Compiling T ( h/T.hs, nothing ) + [3 of 3] Compiling H ( h/H.hs, nothing ) [3 of 3] Processing q - [1 of 3] Compiling A[sig] ( q\A.hsig, nothing ) + [1 of 3] Compiling A[sig] ( q/A.hsig, nothing ) [2 of 3] Instantiating h [3 of 3] Instantiating p - bkpfail07.bkp:6:9: error: [GHC-15843] • Type constructor ‘T’ has conflicting definitions in the module and its hsig file. @@ -18,3 +17,4 @@ bkpfail07.bkp:6:9: error: [GHC-15843] data T = T GHC.Types.Int The constructors do not match: The types for ‘T’ differ. • While checking that ‘h[A=]:H’ implements signature ‘H’ in ‘p[H=h[A=]:H]’. + ===================================== testsuite/tests/backpack/should_fail/bkpfail12.stderr ===================================== @@ -1,13 +1,12 @@ [1 of 3] Processing p - [1 of 2] Compiling Q[sig] ( p\Q.hsig, nothing ) - [2 of 2] Compiling P ( p\P.hs, nothing ) + [1 of 2] Compiling P ( p/P.hs, nothing ) + [2 of 2] Compiling Q[sig] ( p/Q.hsig, nothing ) [2 of 3] Processing q Instantiating q - [1 of 1] Compiling Q ( q\Q.hs, bkpfail12.out\q\Q.o ) + [1 of 1] Compiling Q ( q/Q.hs, bkpfail12.out/q/Q.o ) [3 of 3] Processing r - [1 of 3] Compiling H[sig] ( r\H.hsig, nothing ) + [1 of 3] Compiling H[sig] ( r/H.hsig, nothing ) [2 of 3] Instantiating p - bkpfail12.bkp:8:9: error: [GHC-11890] • Identifier ‘f’ has conflicting definitions in the module and its hsig file. @@ -15,3 +14,4 @@ bkpfail12.bkp:8:9: error: [GHC-11890] Hsig file: f :: GHC.Types.Int The two types are different. • While checking that ‘Q’ implements signature ‘Q’ in ‘p[Q=Q]’. + ===================================== testsuite/tests/backpack/should_fail/bkpfail13.stderr ===================================== @@ -1,13 +1,12 @@ [1 of 3] Processing p - [1 of 2] Compiling Q[sig] ( p\Q.hsig, nothing ) - [2 of 2] Compiling P ( p\P.hs, nothing ) + [1 of 2] Compiling P ( p/P.hs, nothing ) + [2 of 2] Compiling Q[sig] ( p/Q.hsig, nothing ) [2 of 3] Processing q Instantiating q - [1 of 1] Compiling QMe ( q\QMe.hs, bkpfail13.out\q\QMe.o ) + [1 of 1] Compiling QMe ( q/QMe.hs, bkpfail13.out/q/QMe.o ) [3 of 3] Processing r - [1 of 3] Compiling H[sig] ( r\H.hsig, nothing ) + [1 of 3] Compiling H[sig] ( r/H.hsig, nothing ) [2 of 3] Instantiating p - bkpfail13.bkp:8:9: error: [GHC-11890] • Identifier ‘f’ has conflicting definitions in the module and its hsig file. @@ -15,3 +14,4 @@ bkpfail13.bkp:8:9: error: [GHC-11890] Hsig file: f :: GHC.Types.Int The two types are different. • While checking that ‘q:QMe’ implements signature ‘Q’ in ‘p[Q=q:QMe]’. + ===================================== testsuite/tests/backpack/should_fail/bkpfail14.stderr ===================================== @@ -1,16 +1,15 @@ [1 of 3] Processing p - [1 of 3] Compiling Q[sig] ( p\Q.hsig, nothing ) - [2 of 3] Compiling Q2[sig] ( p\Q2.hsig, nothing ) - [3 of 3] Compiling P ( p\P.hs, nothing ) + [1 of 3] Compiling P ( p/P.hs, nothing ) + [2 of 3] Compiling Q[sig] ( p/Q.hsig, nothing ) + [3 of 3] Compiling Q2[sig] ( p/Q2.hsig, nothing ) [2 of 3] Processing q Instantiating q - [1 of 3] Compiling QMe ( q\QMe.hs, bkpfail14.out\q\QMe.o ) - [2 of 3] Compiling Q ( q\Q.hs, bkpfail14.out\q\Q.o ) - [3 of 3] Compiling Q2 ( q\Q2.hs, bkpfail14.out\q\Q2.o ) + [1 of 3] Compiling Q ( q/Q.hs, bkpfail14.out/q/Q.o ) + [2 of 3] Compiling Q2 ( q/Q2.hs, bkpfail14.out/q/Q2.o ) + [3 of 3] Compiling QMe ( q/QMe.hs, bkpfail14.out/q/QMe.o ) [3 of 3] Processing r - [1 of 3] Compiling H[sig] ( r\H.hsig, nothing ) + [1 of 3] Compiling H[sig] ( r/H.hsig, nothing ) [2 of 3] Instantiating p - bkpfail14.bkp:9:9: error: [GHC-11890] • Identifier ‘f’ has conflicting definitions in the module and its hsig file. @@ -18,3 +17,4 @@ bkpfail14.bkp:9:9: error: [GHC-11890] Hsig file: f :: GHC.Types.Int The two types are different. • While checking that ‘QMe’ implements signature ‘Q’ in ‘p[Q=QMe,Q2=Q2]’. + ===================================== testsuite/tests/backpack/should_fail/bkpfail15.stderr ===================================== @@ -1,14 +1,13 @@ [1 of 3] Processing p - [1 of 3] Compiling A[sig] ( p\A.hsig, nothing ) - [2 of 3] Compiling Q[sig] ( p\Q.hsig, nothing ) - [3 of 3] Compiling P ( p\P.hs, nothing ) + [1 of 3] Compiling A[sig] ( p/A.hsig, nothing ) + [2 of 3] Compiling P ( p/P.hs, nothing ) + [3 of 3] Compiling Q[sig] ( p/Q.hsig, nothing ) [2 of 3] Processing q Instantiating q - [1 of 1] Compiling Q ( q\Q.hs, bkpfail15.out\q\Q.o ) + [1 of 1] Compiling Q ( q/Q.hs, bkpfail15.out/q/Q.o ) [3 of 3] Processing r - [1 of 2] Compiling A[sig] ( r\A.hsig, nothing ) + [1 of 2] Compiling A[sig] ( r/A.hsig, nothing ) [2 of 2] Instantiating p - bkpfail15.bkp:8:9: error: [GHC-11890] • Identifier ‘f’ has conflicting definitions in the module and its hsig file. @@ -16,3 +15,4 @@ bkpfail15.bkp:8:9: error: [GHC-11890] Hsig file: f :: GHC.Types.Int The two types are different. • While checking that ‘q:Q’ implements signature ‘Q’ in ‘p[A=,Q=q:Q]’. + ===================================== testsuite/tests/backpack/should_fail/bkpfail21.stderr ===================================== @@ -5,10 +5,9 @@ [1 of 2] Compiling B[sig] ( q/B.hsig, nothing ) [2 of 2] Compiling C[sig] ( q/C.hsig, nothing ) [3 of 3] Processing r - [1 of 5] Compiling H2[sig] ( r/H2.hsig, nothing ) - [2 of 5] Compiling H1[sig] ( r/H1.hsig, nothing ) + [1 of 5] Compiling H1[sig] ( r/H1.hsig, nothing ) + [2 of 5] Compiling H2[sig] ( r/H2.hsig, nothing ) [3 of 5] Compiling H3[sig] ( r/H3.hsig, nothing ) - bkpfail21.bkp:1:1: error: [GHC-93009] • While merging export lists, could not unify {H1.T} with {H2.T} Neither name variable originates from the current signature. @@ -16,3 +15,4 @@ bkpfail21.bkp:1:1: error: [GHC-93009] • p[A=

,C=

]:C • q[B=

,C=

]:C • ...and the local signature for H3 + ===================================== testsuite/tests/count-deps/CountDepsAst.stdout ===================================== @@ -199,7 +199,6 @@ GHC.Unit.Module.Env GHC.Unit.Module.Imported GHC.Unit.Module.Location GHC.Unit.Module.ModIface -GHC.Unit.Module.ModNodeKey GHC.Unit.Module.Warnings GHC.Unit.Module.WholeCoreBindings GHC.Unit.Parser ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -223,6 +223,7 @@ GHC.Unit.Module.Graph GHC.Unit.Module.Imported GHC.Unit.Module.Location GHC.Unit.Module.ModIface +GHC.Unit.Module.ModNodeKey GHC.Unit.Module.ModSummary GHC.Unit.Module.Warnings GHC.Unit.Module.WholeCoreBindings ===================================== testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits002.stdout ===================================== @@ -1,6 +1,6 @@ [1 of 4] Compiling Main[c] -[2 of 4] Compiling Main[d] -[3 of 4] Linking ./c/C[c] +[2 of 4] Linking ./c/C[c] +[3 of 4] Compiling Main[d] [4 of 4] Linking ./d/D[d] unit C compiled successfully unit D compiled successfully ===================================== testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits003.stdout ===================================== @@ -1,8 +1,8 @@ [1 of 6] Compiling A[a] [2 of 6] Compiling B[b] [3 of 6] Compiling Main[c] -[4 of 6] Compiling Main[d] -[5 of 6] Linking ./c/C[c] +[4 of 6] Linking ./c/C[c] +[5 of 6] Compiling Main[d] [6 of 6] Linking ./d/D[d] unit C compiled successfully unit D compiled successfully View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d910b5e856f75d7c8f916cca58d2a97586ceeb7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d910b5e856f75d7c8f916cca58d2a97586ceeb7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 14:51:25 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 06 Jan 2025 09:51:25 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] Cleanup Message-ID: <677beded4dd66_3fb2c5bcf98234d8@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: d2cc0047 by Matthew Pickering at 2025-01-06T14:51:11+00:00 Cleanup - - - - - 11 changed files: - compiler/GHC/Driver/Make.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/ModIface.hs - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp61.stderr - testsuite/tests/backpack/should_fail/bkpfail09.stderr Changes: ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -260,10 +260,6 @@ depanalPartial diag_wrapper msg excluded_mods allow_dup_roots = do -- These are used to represent the type checking that is done after -- all the free holes (sigs in current package) relevant to that instantiation -- are compiled. This is necessary to catch some instantiation errors. --- --- In the future, perhaps more of the work of instantiation could be moved here, --- instead of shoved in with the module compilation nodes. That could simplify --- backpack, and maybe hs-boot too. instantiationNodes :: UnitId -> UnitState -> [(UnitId, InstantiatedUnit)] instantiationNodes uid unit_state = map (uid,) iuids_to_check where @@ -1490,15 +1486,15 @@ topSortModuleGraph -- the a source-import of Foo is an import of Foo -- The resulting graph has no hi-boot nodes, but can be cyclic topSortModuleGraph drop_hs_boot_nodes module_graph mb_root_mod = - -- stronglyConnCompG flips the original order, so if we reverse - -- the summaries we get a stable topological sort. - topSortModules drop_hs_boot_nodes (sortBy (cmpModuleGraphNodes `on` mkNodeKey) $ mgModSummaries' module_graph) mb_root_mod + topSortModules drop_hs_boot_nodes + (sortBy (cmpModuleGraphNodes `on` mkNodeKey) $ mgModSummaries' module_graph) + mb_root_mod where -- In order to get the "right" ordering -- Module nodes must be in reverse lexigraphic order. - -- All modules nodes must appear before package nodes or link nodes. + -- All modules nodes must appear before package nodes. -- -- MP: This is just the ordering which the tests needed in Jan 2025, it does -- not arise from nature. @@ -1506,6 +1502,12 @@ topSortModuleGraph drop_hs_boot_nodes module_graph mb_root_mod = -- Given the current implementation of scc, the result is in -- The order is sensitive to the internal implementation in Data.Graph, -- if it changes in future then this ordering will need to be modified. + -- + -- The SCC algorithm firstly transposes the input graph and then + -- performs dfs on the vertices in the order which they are originally given. + -- Therefore, if `ExternalUnit` nodes are first, the order returned will + -- be determined by the order the dependencies are stored in the transposed graph. + moduleGraphNodeRank :: NodeKey -> Int moduleGraphNodeRank k = case k of NodeKey_Unit {} -> 0 ===================================== compiler/GHC/Iface/Load.hs ===================================== @@ -411,18 +411,13 @@ loadInterfaceWithException doc mod_name where_from let ctx = initSDocContext dflags defaultUserStyle withIfaceErr ctx (loadInterface doc mod_name where_from) --- | Load all interfaces from the home package that are transitively reachable --- from the given modules -- presumes that this operation can be completed by --- traversing from the already loaded home packages. +-- | Load the part of the external module graph which is transitively reachable +-- from the given modules. -- -- This operation is used just before TH splices are run (in 'getLinkDeps'). -- -- A field in the EPS tracks which home modules are already fully loaded, which we use -- here to avoid trying to load them a second time. --- --- For convenience, reads the module graph out of the EPS after having loaded --- all the modules and returns it. It would be harder to get the updated module --- graph in 'getLinkDeps' another way. loadExternalGraphBelow :: (Module -> SDoc) -> Maybe HomeUnit {-^ The current home unit -} -> Set.Set ExternalKey -> [Module] -> IfM lcl (Set.Set ExternalKey) loadExternalGraphBelow _ Nothing _ _ = panic "loadHomePackageInterfacesBelow: No home unit" @@ -430,7 +425,9 @@ loadExternalGraphBelow msg (Just home_unit) init_loaded mods = foldM (loadExternalGraphModule msg home_unit) init_loaded mods loadExternalGraphModule :: (Module -> SDoc) -> HomeUnit - -> Set.Set ExternalKey -> Module -> IfM lcl (Set.Set ExternalKey) + -> Set.Set ExternalKey + -> Module + -> IfM lcl (Set.Set ExternalKey) loadExternalGraphModule msg home_unit init_loaded mod | homeUnitId home_unit /= moduleUnitId mod = do loadExternalPackageBelow init_loaded (moduleUnitId mod) @@ -458,14 +455,6 @@ actuallyLoadExternalGraphModule msg home_unit new_cache key mod = do iface <- withIfaceErr ctx $ loadInterface (msg mod) mod (ImportByUser NotBoot) - -- RM:TODO: THINGS WE ARE NOT DOING - -- - -- The ModIface contains the transitive closure of the module dependencies - -- within the current package, *except* for boot modules: if we encounter - -- a boot module, we have to find its real interface and discover the - -- dependencies of that. Hence we need to traverse the dependency - -- tree recursively. See bug #936, testcase ghci/prog007. - let deps = mi_deps iface mod_deps = dep_direct_mods deps pkg_deps = dep_direct_pkgs deps @@ -511,7 +500,9 @@ loadExternalPackageBelow cache uid = do loadPackageIntoEPSGraph :: UnitId -> [UnitId] -> IfM lcl () loadPackageIntoEPSGraph uid dep_uids = updateEps_ $ \eps -> - eps { eps_module_graph = extendExternalModuleGraph (NodeExternalPackage uid (Set.fromList dep_uids)) (eps_module_graph eps) } + eps { eps_module_graph = + extendExternalModuleGraph (NodeExternalPackage uid + (Set.fromList dep_uids)) (eps_module_graph eps) } ------------------ @@ -624,7 +615,7 @@ loadInterface doc_str mod from ; let direct_deps = map (uncurry (flip ModNodeKeyWithUid)) $ (Set.toList (dep_direct_mods $ mi_deps iface)) ; let direct_pkg_deps = Set.toList $ dep_direct_pkgs $ mi_deps iface - ; let !module_graph_key = -- pprTrace "module_graph_on_load" (ppr (eps_module_graph eps)) $ + ; let !module_graph_key = if moduleUnitId mod `elem` hsc_all_home_unit_ids hsc_env --- ^ home unit mods in eps can only happen in oneshot mode then Just $ NodeHomePackage (miKey iface) (map ExternalModuleKey direct_deps ===================================== compiler/GHC/Linker/Deps.hs ===================================== @@ -60,8 +60,6 @@ import Control.Monad (forM) data LinkDepsOpts = LinkDepsOpts { ldObjSuffix :: !String -- ^ Suffix of .o files , ldForceDyn :: !Bool -- ^ Always use .dyn_o? - , ldOneShotMode :: !Bool -- ^ Is the driver in one-shot mode? - , ldModuleGraph :: !ModuleGraph , ldUnitEnv :: !UnitEnv , ldPprOpts :: !SDocContext -- ^ Rendering options for error messages , ldUseByteCode :: !Bool -- ^ Use bytecode rather than objects @@ -70,8 +68,7 @@ data LinkDepsOpts = LinkDepsOpts , ldFinderCache :: !FinderCache , ldFinderOpts :: !FinderOpts , ldLoadByteCode :: !(Module -> IO (Maybe Linkable)) - , ldLoadHomeIfacesBelow :: !((Module -> SDoc) -> Maybe HomeUnit {- current home unit -} - -> [Module] -> IO ExternalPackageState {- EPS after loading -}) + , ldGetDependencies :: !([Module] -> IO ([Module], UniqDSet UnitId)) } data LinkDeps = LinkDeps @@ -117,7 +114,7 @@ get_link_deps opts pls maybe_normal_osuf span mods = do -- 1. Find the dependent home-pkg-modules/packages from each iface -- (omitting modules from the interactive package, which is already linked) - (mods_s, pkgs_s) <- get_reachable_nodes opts relevant_mods + (mods_s, pkgs_s) <- ldGetDependencies opts relevant_mods let -- 2. Exclude ones already linked @@ -215,88 +212,6 @@ get_link_deps opts pls maybe_normal_osuf span mods = do CoreBindings WholeCoreBindings {wcb_module} -> pprPanic "Unhydrated core bindings" (ppr wcb_module) --- See Note [Reachability in One-shot mode vs Make mode] -get_reachable_nodes :: LinkDepsOpts -> [Module] -> IO ([Module], UniqDSet UnitId) -get_reachable_nodes opts mods - - -- Reachability on 'ExternalModuleGraph' (for one shot mode) - | ldOneShotMode opts - = do - eps <- ldLoadHomeIfacesBelow opts msg (ue_homeUnit (ldUnitEnv opts)) mods - let - emg = eps_module_graph eps - get_mod_info_eps (ModNodeKeyWithUid gwib uid) - | uid == homeUnitId (ue_unsafeHomeUnit unit_env) - = case lookupModuleEnv (eps_PIT eps) (Module (RealUnit $ Definite uid) (gwib_mod gwib)) of - Just iface -> return $ Just iface - Nothing -> moduleNotLoaded "(in EPS)" gwib uid - | otherwise - = return Nothing - - get_mod_key m - | moduleUnitId m == homeUnitId (ue_unsafeHomeUnit unit_env) - = ExternalModuleKey (mkModuleNk m) - | otherwise = ExternalPackageKey (moduleUnitId m) - - go get_mod_key emgNodeKey (emgReachableMany emg) (map emgProject) get_mod_info_eps - - -- Reachability on 'ModuleGraph' (for --make mode) - | otherwise - = go hmgModKey mkNodeKey (mgReachableLoop hmGraph) (catMaybes . map hmgProject) get_mod_info_hug - - where - unit_env = ldUnitEnv opts - mkModuleNk m = ModNodeKeyWithUid (GWIB (moduleName m) NotBoot) (moduleUnitId m) - msg mod = - text "need to link module" <+> ppr mod <+> - text "and the modules below it, due to use of Template Haskell" - - hmGraph = ldModuleGraph opts - - hmgModKey m - | let k = NodeKey_Module (mkModuleNk m) - , mgMember hmGraph k = k - | otherwise = NodeKey_ExternalUnit (moduleUnitId m) - - hmgProject = \case - NodeKey_Module with_uid -> Just $ Left with_uid - NodeKey_ExternalUnit uid -> Just $ Right uid - _ -> Nothing - - emgProject = \case - ExternalModuleKey with_uid -> Left with_uid - ExternalPackageKey uid -> Right uid - - -- The main driver for getting dependencies, which calls the given - -- functions to compute the reachable nodes. - go :: (Module -> key) - -> (node -> key) - -> ([key] -> [node]) - -> ([key] -> [Either ModNodeKeyWithUid UnitId]) - -> (ModNodeKeyWithUid -> IO (Maybe ModIface)) - -> IO ([Module], UniqDSet UnitId) - go modKey nodeKey manyReachable project get_mod_info - | let mod_keys = map modKey mods - = do - let (all_home_mods, pkgs_s) = partitionEithers $ project $ mod_keys ++ map nodeKey (manyReachable mod_keys) - ifaces <- mapMaybeM get_mod_info all_home_mods - mods_s <- forM ifaces $ \iface -> case mi_hsc_src iface of - HsBootFile -> link_boot_mod_error (mi_module iface) - _ -> return $ mi_module iface - return (mods_s, mkUniqDSet pkgs_s) - - get_mod_info_hug (ModNodeKeyWithUid gwib uid) - | Just hmi <- lookupHug (ue_home_unit_graph unit_env) uid (gwib_mod gwib) - = return $ Just (hm_iface hmi) - | otherwise - = moduleNotLoaded "(in HUG)" gwib uid - - moduleNotLoaded m gwib uid = throwProgramError opts $ - text "getLinkDeps: Home module not loaded" <+> text m <+> ppr (gwib_mod gwib) <+> ppr uid - - link_boot_mod_error mod = throwProgramError opts $ - text "module" <+> ppr mod <+> - text "cannot be linked; it is only available as a boot module" {- ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -76,8 +76,14 @@ import GHC.Utils.Logger import GHC.Utils.TmpFs import GHC.Unit.Env -import GHC.Unit.External (ExternalPackageState (EPS, eps_iface_bytecode)) +import GHC.Unit.Home +import GHC.Unit.Home.ModInfo +import GHC.Unit.External (ExternalPackageState (..)) import GHC.Unit.Module +import GHC.Unit.Module.ModNodeKey +import GHC.Unit.Module.External.Graph +import GHC.Unit.Module.Graph +import GHC.Unit.Module.ModIface import GHC.Unit.State as Packages import qualified GHC.Data.ShortText as ST @@ -97,6 +103,7 @@ import qualified Data.Foldable as Foldable import Data.IORef import Data.List (intercalate, isPrefixOf, nub, partition) import Data.Maybe +import Data.Either import Control.Concurrent.MVar import qualified Control.Monad.Catch as MC import qualified Data.List.NonEmpty as NE @@ -594,8 +601,6 @@ initLinkDepsOpts hsc_env = opts opts = LinkDepsOpts { ldObjSuffix = objectSuf dflags , ldForceDyn = sTargetRTSLinkerOnlySupportsSharedLibs $ settings dflags - , ldOneShotMode = isOneShot (ghcMode dflags) - , ldModuleGraph = hsc_mod_graph hsc_env , ldUnitEnv = hsc_unit_env hsc_env , ldPprOpts = initSDocContext dflags defaultUserStyle , ldFinderCache = hsc_FC hsc_env @@ -603,22 +608,96 @@ initLinkDepsOpts hsc_env = opts , ldUseByteCode = gopt Opt_UseBytecodeRatherThanObjects dflags , ldMsgOpts = initIfaceMessageOpts dflags , ldWays = ways dflags - , ldLoadHomeIfacesBelow + , ldGetDependencies = get_reachable_nodes hsc_env , ldLoadByteCode } dflags = hsc_dflags hsc_env - ldLoadHomeIfacesBelow msg hu mods - = do - initIfaceCheck (text "loader") hsc_env - $ void $ loadExternalGraphBelow msg hu Set.empty mods - -- Read the EPS only after `loadHomePackageInterfacesBelow` - hscEPS hsc_env ldLoadByteCode mod = do EPS {eps_iface_bytecode} <- hscEPS hsc_env sequence (lookupModuleEnv eps_iface_bytecode mod) +-- See Note [Reachability in One-shot mode vs Make mode] +get_reachable_nodes :: HscEnv -> [Module] -> IO ([Module], UniqDSet UnitId) +get_reachable_nodes hsc_env mods + + -- Reachability on 'ExternalModuleGraph' (for one shot mode) + | isOneShot (ghcMode dflags) + = do + initIfaceCheck (text "loader") hsc_env + $ void $ loadExternalGraphBelow msg (hsc_home_unit_maybe hsc_env) Set.empty mods + -- Read the EPS only after `loadHomePackageInterfacesBelow` + eps <- hscEPS hsc_env + let + emg = eps_module_graph eps + get_mod_info_eps (ModNodeKeyWithUid gwib uid) + | uid == homeUnitId (ue_unsafeHomeUnit unit_env) + = case lookupModuleEnv (eps_PIT eps) (Module (RealUnit $ Definite uid) (gwib_mod gwib)) of + Just iface -> return $ Just iface + Nothing -> moduleNotLoaded "(in EPS)" gwib uid + | otherwise + = return Nothing + + get_mod_key m + | moduleUnitId m == homeUnitId (ue_unsafeHomeUnit unit_env) + = ExternalModuleKey (mkModuleNk m) + | otherwise = ExternalPackageKey (moduleUnitId m) + + go get_mod_key emgNodeKey (emgReachableLoopMany emg) (map emgProject) get_mod_info_eps + + -- Reachability on 'ModuleGraph' (for --make mode) + | otherwise + = go hmgModKey mkNodeKey (mgReachableLoop hmGraph) (catMaybes . map hmgProject) get_mod_info_hug + + where + dflags = hsc_dflags hsc_env + unit_env = hsc_unit_env hsc_env + mkModuleNk m = ModNodeKeyWithUid (GWIB (moduleName m) NotBoot) (moduleUnitId m) + msg mod = + text "need to link module" <+> ppr mod <+> + text "and the modules below it, due to use of Template Haskell" + + hmGraph = hsc_mod_graph hsc_env + + hmgModKey m + | let k = NodeKey_Module (mkModuleNk m) + , mgMember hmGraph k = k + | otherwise = NodeKey_ExternalUnit (moduleUnitId m) + + hmgProject = \case + NodeKey_Module with_uid -> Just $ Left with_uid + NodeKey_ExternalUnit uid -> Just $ Right uid + _ -> Nothing + + emgProject = \case + ExternalModuleKey with_uid -> Left with_uid + ExternalPackageKey uid -> Right uid + + -- The main driver for getting dependencies, which calls the given + -- functions to compute the reachable nodes. + go :: (Module -> key) + -> (node -> key) + -> ([key] -> [node]) + -> ([key] -> [Either ModNodeKeyWithUid UnitId]) + -> (ModNodeKeyWithUid -> IO (Maybe ModIface)) + -> IO ([Module], UniqDSet UnitId) + go modKey nodeKey manyReachable project get_mod_info + | let mod_keys = map modKey mods + = do + let (all_home_mods, pkgs_s) = partitionEithers $ project $ mod_keys ++ map nodeKey (manyReachable mod_keys) + ifaces <- mapMaybeM get_mod_info all_home_mods + let mods_s = map mi_module ifaces + return (mods_s, mkUniqDSet pkgs_s) + + get_mod_info_hug (ModNodeKeyWithUid gwib uid) + | Just hmi <- lookupHug (ue_home_unit_graph unit_env) uid (gwib_mod gwib) + = return $ Just (hm_iface hmi) + | otherwise + = moduleNotLoaded "(in HUG)" gwib uid + + moduleNotLoaded m gwib uid = throwGhcExceptionIO $ ProgramError $ showSDoc dflags $ + text "getLinkDeps: Home module not loaded" <+> text m <+> ppr (gwib_mod gwib) <+> ppr uid {- ********************************************************************** ===================================== compiler/GHC/Unit/Module/External/Graph.hs ===================================== @@ -50,8 +50,8 @@ module GHC.Unit.Module.External.Graph -- -- | Fast reachability queries on the external module graph. Similar to -- reachability queries on 'GHC.Unit.Module.Graph'. - , emgReachable - , emgReachableMany + , emgReachableLoop + , emgReachableLoopMany ) where import GHC.Prelude @@ -60,10 +60,12 @@ import GHC.Data.Graph.Directed.Reachability import GHC.Data.Graph.Directed import qualified Data.Map as M import qualified Data.Set as S -import Data.Bifunctor (first) +import Data.Bifunctor (first, bimap) import Data.Maybe import GHC.Utils.Outputable -import GHC.Unit.Types (UnitId) +import GHC.Unit.Types (UnitId, GenWithIsBoot(..), IsBootInterface(..), mkModule) +import GHC.Utils.Misc + -------------------------------------------------------------------------------- -- * Main @@ -71,6 +73,7 @@ import GHC.Unit.Types (UnitId) data ExternalModuleGraph = ExternalModuleGraph { external_nodes :: [ExternalGraphNode] + -- This transitive dependency query does not contain hs-boot nodes. , external_trans :: (ReachabilityIndex ExternalNode, ExternalKey -> Maybe ExternalNode) , external_fully_loaded :: !(S.Set ExternalKey) } @@ -103,10 +106,17 @@ emptyExternalModuleGraph :: ExternalModuleGraph emptyExternalModuleGraph = ExternalModuleGraph [] (graphReachability emptyGraph, const Nothing) S.empty -- | Get the dependencies of an 'ExternalNode' -emgNodeDeps :: ExternalGraphNode -> [ExternalKey] -emgNodeDeps = \case - NodeHomePackage _ dps -> dps +emgNodeDeps :: Bool -> ExternalGraphNode -> [ExternalKey] +emgNodeDeps drop_hs_boot_nodes = \case + NodeHomePackage _ dps -> map drop_hs_boot dps NodeExternalPackage _ dps -> map ExternalPackageKey $ S.toList dps + where + -- Drop hs-boot nodes by using HsSrcFile as the key + hs_boot_key | drop_hs_boot_nodes = NotBoot -- is regular mod or signature + | otherwise = IsBoot + + drop_hs_boot (ExternalModuleKey (ModNodeKeyWithUid (GWIB mn IsBoot) uid)) = (ExternalModuleKey (ModNodeKeyWithUid (GWIB mn hs_boot_key) uid)) + drop_hs_boot x = x -- | The graph key for a given node emgNodeKey :: ExternalGraphNode -> ExternalKey @@ -126,11 +136,10 @@ extendExternalModuleGraph node ExternalModuleGraph{..} = ExternalModuleGraph { external_fully_loaded = external_fully_loaded , external_nodes = node : external_nodes - , external_trans = first graphReachability $ - externalGraphNodes (node : external_nodes) + , external_trans = first cyclicGraphReachability $ + externalGraphNodes True (node : external_nodes) } - -------------------------------------------------------------------------------- -- * Loading -------------------------------------------------------------------------------- @@ -149,15 +158,15 @@ setFullyLoadedModule key graph = graph { external_fully_loaded = S.insert key (e -- transitive closure. -- -- @Nothing@ if the key couldn't be found in the graph. -emgReachable :: ExternalModuleGraph -> ExternalKey -> Maybe [ExternalGraphNode] -emgReachable mg nk = map node_payload <$> modules_below where +emgReachableLoop :: ExternalModuleGraph -> ExternalKey -> Maybe [ExternalGraphNode] +emgReachableLoop mg nk = map node_payload <$> modules_below where (td_map, lookup_node) = external_trans mg modules_below = allReachable td_map <$> lookup_node nk -- | Return all nodes reachable from all of the given keys. -emgReachableMany :: ExternalModuleGraph -> [ExternalKey] -> [ExternalGraphNode] -emgReachableMany mg nk = map node_payload modules_below where +emgReachableLoopMany :: ExternalModuleGraph -> [ExternalKey] -> [ExternalGraphNode] +emgReachableLoopMany mg nk = map node_payload modules_below where (td_map, lookup_node) = external_trans mg modules_below = allReachableMany td_map (mapMaybe lookup_node nk) @@ -167,18 +176,38 @@ emgReachableMany mg nk = map node_payload modules_below where -------------------------------------------------------------------------------- -- | Turn a list of graph nodes into an efficient queriable graph. -externalGraphNodes :: - [ExternalGraphNode] +-- The first boolean parameter indicates whether nodes corresponding to hs-boot files +-- should be collapsed into their relevant hs nodes. +externalGraphNodes :: Bool + -> [ExternalGraphNode] -> (Graph ExternalNode, ExternalKey -> Maybe ExternalNode) -externalGraphNodes summaries = +externalGraphNodes drop_hs_boot_nodes summaries = (graphFromEdgedVerticesUniq nodes, lookup_node) where -- Map from module to extra boot summary dependencies which need to be merged in - nodes = map go numbered_summaries + (boot_summaries, nodes) = bimap M.fromList id $ partitionWith go numbered_summaries where - go (s, key) = DigraphNode s key $ out_edge_keys $ - (emgNodeDeps s) + go (s, key) = + case s of + NodeHomePackage (ModNodeKeyWithUid (GWIB mn IsBoot) uid) _deps | drop_hs_boot_nodes + -- Using emgNodeDeps here converts dependencies on other + -- boot files to dependencies on dependencies on non-boot files. + -> Left (mkModule uid mn, emgNodeDeps drop_hs_boot_nodes s) + _ -> normal_case + where + normal_case = + let lkup_key = + case s of + NodeHomePackage (ModNodeKeyWithUid (GWIB mn IsBoot) uid) _deps + -> Just $ mkModule uid mn + _ -> Nothing + + extra = (lkup_key >>= \key -> M.lookup key boot_summaries) + + in Right $ DigraphNode s key $ out_edge_keys $ + (fromMaybe [] extra + ++ emgNodeDeps drop_hs_boot_nodes s) numbered_summaries = zip summaries [1..] @@ -191,12 +220,14 @@ externalGraphNodes summaries = node_map :: M.Map ExternalKey ExternalNode node_map = M.fromList [ (emgNodeKey s, node) - | node <- nodes - , let s = node_payload node - ] + | node <- nodes + , let s = node_payload node + ] out_edge_keys :: [ExternalKey] -> [Int] out_edge_keys = mapMaybe lookup_key + -- If we want keep_hi_boot_nodes, then we do lookup_key with + -- IsBoot; else False instance Outputable ExternalGraphNode where ppr = \case ===================================== compiler/GHC/Unit/Module/ModIface.hs ===================================== @@ -362,7 +362,6 @@ data ModIface_ (phase :: ModIfacePhase) -- See Note [Sharing of ModIface]. } - -- Enough information to reconstruct the top level environment for a module data IfaceTopEnv = IfaceTopEnv ===================================== testsuite/tests/backpack/should_compile/bkp09.stderr ===================================== @@ -1,6 +1,6 @@ - bkp09.bkp:1:26: warning: [GHC-53692] [-Wdeprecated-flags (in -Wdefault)] -XDatatypeContexts is deprecated: It was widely considered a misfeature, and has been removed from the Haskell language. + [1 of 5] Processing p [1 of 1] Compiling H[sig] ( p/H.hsig, nothing ) [2 of 5] Processing q ===================================== testsuite/tests/backpack/should_compile/bkp15.stderr ===================================== @@ -1,6 +1,6 @@ - bkp15.bkp:1:26: warning: [GHC-53692] [-Wdeprecated-flags (in -Wdefault)] -XDatatypeContexts is deprecated: It was widely considered a misfeature, and has been removed from the Haskell language. + [1 of 5] Processing p [1 of 1] Compiling H[sig] ( p/H.hsig, nothing ) [2 of 5] Processing q ===================================== testsuite/tests/backpack/should_compile/bkp47.stderr ===================================== @@ -5,10 +5,10 @@ [3 of 3] Processing r [1 of 4] Compiling A[sig] ( r/A.hsig, nothing ) [2 of 4] Compiling B ( r/B.hs, nothing ) - bkp47.bkp:19:18: warning: [GHC-06201] [-Wmissing-methods (in -Wdefault)] • No explicit implementation for either ‘f’ or ‘g’ • In the instance declaration for ‘C Int’ + [3 of 4] Instantiating p [4 of 4] Instantiating q ===================================== testsuite/tests/backpack/should_compile/bkp61.stderr ===================================== @@ -1,15 +1,15 @@ [1 of 3] Processing p - [1 of 2] Compiling H[sig] ( p\H.hsig, nothing ) - [2 of 2] Compiling A ( p\A.hs, nothing ) + [1 of 2] Compiling H[sig] ( p/H.hsig, nothing ) + [2 of 2] Compiling A ( p/A.hs, nothing ) [2 of 3] Processing q Instantiating q - [1 of 1] Compiling H ( q\H.hs, bkp61.out\q\H.o ) + [1 of 1] Compiling H ( q/H.hs, bkp61.out/q/H.o ) [3 of 3] Processing r Instantiating r [1 of 2] Including q [2 of 2] Including p[H=q:H] Instantiating p[H=q:H] - [1 of 2] Compiling H[sig] ( p\H.hsig, bkp61.out\p\p-D5Mg3foBSCrDbQDKH4WGSG\H.o ) - [2 of 2] Compiling A ( p\A.hs, bkp61.out\p\p-D5Mg3foBSCrDbQDKH4WGSG\A.o ) - [1 of 2] Compiling N ( r\N.hs, bkp61.out\r\N.o ) + [1 of 2] Compiling H[sig] ( p/H.hsig, bkp61.out/p/p-D5Mg3foBSCrDbQDKH4WGSG/H.o ) + [2 of 2] Compiling A ( p/A.hs, bkp61.out/p/p-D5Mg3foBSCrDbQDKH4WGSG/A.o ) + [1 of 2] Compiling N ( r/N.hs, bkp61.out/r/N.o ) [2 of 2] Instantiating p ===================================== testsuite/tests/backpack/should_fail/bkpfail09.stderr ===================================== @@ -1,13 +1,12 @@ [1 of 3] Processing p - [1 of 2] Compiling H[sig] ( p\H.hsig, nothing ) - [2 of 2] Compiling A ( p\A.hs, nothing ) + [1 of 2] Compiling H[sig] ( p/H.hsig, nothing ) + [2 of 2] Compiling A ( p/A.hs, nothing ) [2 of 3] Processing q Instantiating q - [1 of 1] Compiling H ( q\H.hs, bkpfail09.out\q\H.o ) + [1 of 1] Compiling H ( q/H.hs, bkpfail09.out/q/H.o ) [3 of 3] Processing r - [1 of 3] Compiling H2[sig] ( r\H2.hsig, nothing ) + [1 of 3] Compiling H2[sig] ( r/H2.hsig, nothing ) [2 of 3] Instantiating p - Command line argument: -unit-id p[H=H]:0:0: error: [GHC-93011] • ‘H’ is exported by the hsig file, but not exported by the implementing module ‘q:H’ • While checking that ‘q:H’ implements signature ‘H’ in ‘p[H=q:H]’. @@ -15,3 +14,4 @@ Command line argument: -unit-id p[H=H]:0:0: error: [GHC-93011] Command line argument: -unit-id p[H=H]:0:0: error: [GHC-93011] • ‘H’ is exported by the hsig file, but not exported by the implementing module ‘q:H’ • While checking that ‘q:H’ implements signature ‘H’ in ‘p[H=q:H]’. + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2cc0047fd79f9833ec42d27b9a27583c7745ed2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2cc0047fd79f9833ec42d27b9a27583c7745ed2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 15:29:44 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 06 Jan 2025 10:29:44 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] driver: Store an ExternalModuleGraph in the EPS Message-ID: <677bf6e894707_2ab83510c9a82931@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: d7e582e3 by Matthew Pickering at 2025-01-06T15:28:25+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- - - - - - 30 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Unit/External.hs - + compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/Graph.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr - testsuite/tests/backpack/should_compile/bkp61.stderr - testsuite/tests/backpack/should_fail/bkpfail07.stderr - testsuite/tests/backpack/should_fail/bkpfail09.stderr - testsuite/tests/backpack/should_fail/bkpfail12.stderr - testsuite/tests/backpack/should_fail/bkpfail13.stderr - testsuite/tests/backpack/should_fail/bkpfail14.stderr - testsuite/tests/backpack/should_fail/bkpfail15.stderr - testsuite/tests/backpack/should_fail/bkpfail21.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7e582e355926ae61d597bc7244daed447dfc435 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7e582e355926ae61d597bc7244daed447dfc435 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 15:33:12 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 06 Jan 2025 10:33:12 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] 30 commits: testsuite: Use math.inf instead of division-by-zero Message-ID: <677bf7b8bbb13_2ab835d1eac345a@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - 08d489d2 by Matthew Pickering at 2025-01-06T15:32:55+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/upload.sh - .gitmodules - compiler/GHC/Builtin/Names.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Utils/Env.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d7e582e355926ae61d597bc7244daed447dfc435...08d489d2226921fc28c0521fe3fd87fca5cc5f93 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d7e582e355926ae61d597bc7244daed447dfc435...08d489d2226921fc28c0521fe3fd87fca5cc5f93 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 15:35:48 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 06 Jan 2025 10:35:48 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] driver: Store an ExternalModuleGraph in the EPS Message-ID: <677bf854b320f_2ab835bcf0c39bd@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: 8ab9a68e by Matthew Pickering at 2025-01-06T15:35:12+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Unit/External.hs - + compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/Graph.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr - testsuite/tests/backpack/should_compile/bkp61.stderr - testsuite/tests/backpack/should_fail/bkpfail07.stderr - testsuite/tests/backpack/should_fail/bkpfail09.stderr - testsuite/tests/backpack/should_fail/bkpfail12.stderr - testsuite/tests/backpack/should_fail/bkpfail13.stderr - testsuite/tests/backpack/should_fail/bkpfail14.stderr - testsuite/tests/backpack/should_fail/bkpfail15.stderr - testsuite/tests/backpack/should_fail/bkpfail21.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8ab9a68ec913ffcc1a86da66c3f7977c9e3b99ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8ab9a68ec913ffcc1a86da66c3f7977c9e3b99ea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 16:07:45 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Mon, 06 Jan 2025 11:07:45 -0500 Subject: [Git][ghc/ghc][wip/T18462] 111 commits: Clarify INLINE unfolding optimization docs. Message-ID: <677bffd162730_18d04213df1c85338@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: fcc3ae6e by Andreas Klebinger at 2024-11-26T08:24:58-05:00 Clarify INLINE unfolding optimization docs. Fixes #24660 - - - - - 88c4fe1d by Cheng Shao at 2024-11-26T08:25:34-05:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. - - - - - 53f978c0 by doyougnu at 2024-11-26T16:07:26-05:00 ghc-experimental: expose GHC.RTS.Flags, GHC.Stats See this CLC proposal: - https://github.com/haskell/core-libraries-committee/issues/289 and this CLC proposal for background: - https://github.com/haskell/core-libraries-committee/issues/288 Metric Decrease: MultiLayerModulesTH_OneShot - - - - - e70d4140 by Wang Xin at 2024-11-26T16:08:10-05:00 Add -mcmodel=medium moduleflag to generated LLVM IR on LoongArch platform With the Medium code model, the jump range of the generated jump instruction is larger than that of the Small code model. It's a temporary fix of the problem descriped in https://gitlab.haskell .org/ghc/ghc/-/issues/25495. This commit requires that the LLVM used contains the code of commit 9dd1d451d9719aa91b3bdd59c0c6679 83e1baf05, i.e., version 8.0 and later. Actually we should not rely on LLVM, so the only way to solve this problem is to implement the LoongArch backend. Add new type for codemodel - - - - - df42ba16 by Andreas Klebinger at 2024-11-27T11:40:49-05:00 Cmm constant folding: Narrow results to operations bitwidth. When constant folding ensure the result is still within bounds for the given type by explicitly narrowing the results. Not doing so results in a lot of spurious assembler warnings especially when testing primops. - - - - - bf3db97e by Ben Gamari at 2024-11-27T11:41:26-05:00 ghc-toolchain: Introduce basic flag validation We verify that required flags (currently `--output` and `--triple`) are provided. The implementation is truly awful, but so is getopt. Begins to address #25500. - - - - - a104508d by Ben Gamari at 2024-11-27T11:42:03-05:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. - - - - - c3fc9b86 by Ben Gamari at 2024-11-27T11:42:39-05:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. - - - - - a362b943 by sheaf at 2024-11-27T23:44:28-05:00 Add checkExact to toolTargets This change means that the Hadrian multi target will include exactprint. In particular, this means that HLS will work on exactprint inside the GHC tree. - - - - - e6c957e4 by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Add test for #25428 - - - - - 52d97f4e by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Don't bypass MonoLocalBind in empty patterns Fixes #25428 - - - - - 7890f2d8 by Ben Gamari at 2024-11-28T10:26:46-05:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. - - - - - 0fd43ea6 by Adam Sandberg Ericsson at 2024-11-28T10:27:22-05:00 mention -Iw in +RTS -? - - - - - 6cf579b9 by Ben Gamari at 2024-11-28T10:27:59-05:00 gitlab-ci: Set GIT_SUBMODULE_FORCE_HTTPS GitLab recommends using `https://` to clone submodules and provides the `GIT_SUBMODULE_FORCE_HTTPS` variable to force this. Fixes #25528. - - - - - 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - ca1bbb73 by Sjoerd Visscher at 2025-01-06T17:07:32+01:00 Multiplicity annotation on records - - - - - 25 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .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 - .gitlab/rel_eng/upload.sh - .gitmodules - compiler/GHC/Builtin/Names.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cab98bfba7ce8eeb1c0854a7ed118bf3a03ad107...ca1bbb738612ef1dd0bf25bbf2b8e18ada29476e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cab98bfba7ce8eeb1c0854a7ed118bf3a03ad107...ca1bbb738612ef1dd0bf25bbf2b8e18ada29476e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 16:18:33 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Mon, 06 Jan 2025 11:18:33 -0500 Subject: [Git][ghc/ghc][wip/T18462] Multiplicity annotation on records Message-ID: <677c02595684c_18d04238bdc887137@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 86930fad by Sjoerd Visscher at 2025-01-06T17:18:21+01:00 Multiplicity annotation on records - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - docs/users_guide/9.14.1-notes.rst - docs/users_guide/exts/linear_types.rst - testsuite/tests/ghc-api/exactprint/Test20239.stderr - 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/linear/should_compile/NonLinearRecord.hs - testsuite/tests/linear/should_compile/all.T - + testsuite/tests/linear/should_fail/LinearRecFieldMany.hs - + testsuite/tests/linear/should_fail/LinearRecFieldMany.stderr - testsuite/tests/linear/should_fail/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/86930fadb1583c222bf47765f426cd9f0d9a651d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/86930fadb1583c222bf47765f426cd9f0d9a651d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 16:34:58 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 06 Jan 2025 11:34:58 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] driver: Store an ExternalModuleGraph in the EPS Message-ID: <677c06323b111_18d0427151c493753@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: c79ea412 by Matthew Pickering at 2025-01-06T16:34:46+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Unit/External.hs - + compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/Graph.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr - testsuite/tests/backpack/should_compile/bkp61.stderr - testsuite/tests/backpack/should_fail/bkpfail07.stderr - testsuite/tests/backpack/should_fail/bkpfail09.stderr - testsuite/tests/backpack/should_fail/bkpfail12.stderr - testsuite/tests/backpack/should_fail/bkpfail13.stderr - testsuite/tests/backpack/should_fail/bkpfail14.stderr - testsuite/tests/backpack/should_fail/bkpfail15.stderr - testsuite/tests/backpack/should_fail/bkpfail21.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c79ea4127fae8fbc2f355d0480c4a528c2920ecc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c79ea4127fae8fbc2f355d0480c4a528c2920ecc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 16:46:03 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 06 Jan 2025 11:46:03 -0500 Subject: [Git][ghc/ghc][wip/T25630] Tidy up kcConDecls Message-ID: <677c08cbe9079_18d042a4559c1044b8@gitlab.mail> Simon Peyton Jones pushed to branch wip/T25630 at Glasgow Haskell Compiler / GHC Commits: e0ab8fe1 by Simon Peyton Jones at 2025-01-06T16:44:28+00:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1759,7 +1759,9 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- - In this function, those TcTyVars are unified with other kind variables during -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) -kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) tycon +kcTyClDecl (DataDecl { tcdLName = (L _ _name) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no -- harm. For GADTs, each data con brings its own tyvars into scope, @@ -1767,7 +1769,7 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (dataDefnConsNewOrData cons) (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1799,67 +1801,70 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM () -kcConArgTys new_or_data res_kind arg_tys = do - { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) +kcConArgTys :: ConArgKind -- Expected kind of the argument(s) + -> [HsScaled GhcRn (LHsType GhcRn)] -- User-written argument types + -> TcM () +kcConArgTys exp_kind arg_tys + = forM_ arg_tys $ \(HsScaled mult ty) -> + do { _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + ; tcMult mult } -- See Note [Implementation of UnliftedNewtypes], STEP 2 - } -- Kind-check the types of arguments to a Haskell98 data constructor. -kcConH98Args :: NewOrData -> TcKind -> HsConDeclH98Details GhcRn -> TcM () -kcConH98Args new_or_data res_kind con_args = case con_args of - PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys - InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] - RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConH98Args :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclH98Details GhcRn + -> TcM () +kcConH98Args exp_kind con_args = case con_args of + PrefixCon _ tys -> kcConArgTys exp_kind tys + InfixCon ty1 ty2 -> kcConArgTys exp_kind [ty1, ty2] + RecCon (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. -kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () -kcConGADTArgs new_or_data res_kind con_args = case con_args of - PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys - RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConGADTArgs :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclGADTDetails GhcRn + -> TcM () +kcConGADTArgs exp_kind con_args = case con_args of + PrefixConGADT _ tys -> kcConArgTys exp_kind tys + RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -kcConDecls :: Foldable f - => NewOrData - -> TcKind -- The result kind signature - -- Used only in H98 case - -> f (LConDecl GhcRn) -- The data constructors - -> TcM () +kcConDecls :: TcKind -- Result kind of tycon + -- Used only in H98 case + -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls new_or_data tc_res_kind = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) +kcConDecls tc_res_kind cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons + where + new_or_data = dataDefnConsNewOrData cons -- Kind check a data constructor. In additional to the data constructor, -- we also need to know about whether or not its corresponding type was -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData - -> TcKind -- Result kind of the type constructor - -- Usually Type but can be TYPE UnliftedRep - -- or even TYPE r, in the case of unlifted newtype - -- Used only in H98 case - -> ConDecl GhcRn - -> TcM () -kcConDecl new_or_data tc_res_kind (ConDeclH98 - { con_name = name, con_ex_tvs = ex_tvs - , con_mb_cxt = ex_ctxt, con_args = args }) +kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data tc_res_kind + (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs + , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (dataConCtxt (NE.singleton name)) $ discardResult $ bindExplicitTKBndrs_Tv ex_tvs $ do { _ <- tcHsContext ex_ctxt - ; kcConH98Args new_or_data tc_res_kind args + ; let arg_exp_kind = getArgExpKind new_or_data tc_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same as the tc_res_kind. See (KCD1) + -- in Note [kcConDecls: kind-checking data type decls] + ; kcConH98Args arg_exp_kind args -- We don't need to check the telescope here, -- because that's done in tcConDecl } -kcConDecl new_or_data - _tc_res_kind -- Not used in GADT case (and doesn't make sense) - (ConDeclGADT - { con_names = names, con_bndrs = L _ outer_bndrs, con_mb_cxt = cxt - , con_g_args = args, con_res_ty = res_ty }) +kcConDecl new_or_data _tc_res_kind + -- NB: _tc_res_kind is unused. See (KCD3) in + -- Note [kcConDecls: kind-checking data type decls] + (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs + , con_mb_cxt = cxt, con_g_args = args, con_res_ty = res_ty }) = -- See Note [kcConDecls: kind-checking data type decls] addErrCtxt (dataConCtxt names) $ discardResult $ @@ -1870,45 +1875,80 @@ kcConDecl new_or_data ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) ; con_res_kind <- newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - ; kcConGADTArgs new_or_data con_res_kind args - ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind) + + ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same the kind of `res_ty`, the data con's return type + -- See (KCD2) in Note [kcConDecls: kind-checking data type decls] + ; kcConGADTArgs arg_exp_kind args + + ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr arg_exp_kind) ; return () } {- Note [kcConDecls: kind-checking data type decls] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kcConDecls is used when we are inferring the kind of the type -constructor in a data type declaration. E.g. - data T f a = MkT (f a) -we want to infer the kind of 'f' and 'a'. The basic plan is described -in Note [Inferring kinds for type declarations]; here we are doing Step 2. - -In the GADT case we may have this: - data T f a where - MkT :: forall g b. g b -> T g b - -Notice that the variables f,a, and g,b are quite distinct. -Nevertheless, the type signature for MkT must still influence the kind -T which is (remember Step 1) something like - T :: kappa1 -> kappa2 -> Type -Otherwise we'd infer the bogus kind - T :: forall k1 k2. k1 -> k2 -> Type. - -The type signature for MkT influences the kind of T simply by -kind-checking the result type (T g b), which will force 'f' and 'g' to -have the same kinds. This is the call to - tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) -Because this is the result type of an arrow, we know the kind must be -of form (TYPE rr), and we get better error messages if we enforce that -here (e.g. test gadt10). - -For unlifted newtypes only, we must ensure that the argument kind -and result kind are the same: -* In the H98 case, we need the result kind of the TyCon, to unify with - the argument kind. - -* In GADT syntax, this unification happens via the result kind passed - to kcConGADTArgs. The tycon's result kind is not used at all in the - GADT case. +constructor in a data type declaration. The basic plan is described in +Note [Inferring kinds for type declarations]; here we are doing Step 2. + +We are kind-checking the data constructors /only/ to compute the kind of +the type construtor. For example + data T f a = MkT (f a) +The (f a) in the data construtor constrains the kinds of `f` and `a`, and hence +of `T`. + +There are two cases to consider in `kcConDecl` + +* Haskell 98 data constructors, as above. We simply bring `f` and `a` + into scope and kind-check the data constructors. + +* GADT data type decls e.g. + data S f a where + MkS :: g b -> S g b + Here `f` and `a` don't scope over the data constructor signatures. + Instead, we just kind-check the entire signature (including the result `S g b`), + relying on the fact that `S` is in scope with its initial kind `k1 -> k2 -> Type`; + doing so will constrain `k1` and `k2` appropriately. + +The arguments of each data constructor are always of kind (TYPE r) for some +r :: RuntimeRep. But in the case of a newytype, the argument kind must be +the same as the tycon result kind. Since we are trying to figure out the +tycon kind, kcConDecls must account for this, which is surprisingly tricky. +Again there are two cases to consider in `kcConDecl`: + +* Haskell 98 data type decls, e.g. + data T f a = MkT (f a) + * In the header, all the tycon binders are specified (here `f` and `a`) + and there is no result kind signature. + * The binders from the header scope over the data construtors. + * In the case of unlifted newtypes, the argument kind affects the tycon kind + newtype N = MkN Int# + Here `getInitialKind` will give `N` the result kind `TYPE r`, where `r` is + a unification variable, and `kcConDecls` should unify that `r` with + `IntRep` becuase of the `Int#` + + Solution (KCD1): just check that the argumet type has the same kind as the result + kind of the tycon. + +* GADT data type decls e.g. + data S f :: Type -> Type where + MkS :: g a -> S g a + * In the header, not all the tycon binders are specified (here just `f`), + and there can be a kind signature + * The kind signature may describe some, all, or none of the tycon binders. + Regardless, in the TcTyCon constructed by `getInitialKind`, the tyConResKind + is the signature, not the "ultimate" result type of the tycon (which is + usually Type) + * In the case of unlifted newtypes, we again want the argument kind to be the + same as the result kind of the tycon; but it's not so clear what /is/ the + result kind of the tycon, because of the signature stuff in the previous bullet. + + Solution (KCD2): kind-check the result type of the data constructor (here + `S g a`) and, for newtypes, ensure that the arugment has that same kind. + + (KCD3) The tycon's result kind `tc_res_kind` is not used at all in the GADT + case; rather it is accessed via looking up S's kind in the type environment + when kind-checking the result type of the data constructor. Note [Using TyVarTvs for kind-checking GADTs] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3866,13 +3906,21 @@ nothing wrong with it). We are implicitly requiring tha tcInferLHsTypeKind doesn't any gratuitous top-level casts. -} + +type ConArgKind = ContextKind + -- The expected kind of the argument(s) of a constructor + -- For data types this is always OpenKind + -- For newtypes it is (TheKind ki) + -- where `ki` is the result kind of the newtype + -- With NoUnliftedNewtype, ki=Type, but with UnliftedNewtypes it can be a variable + -- | Produce an "expected kind" for the arguments of a data/newtype. -- If the declaration is indeed for a newtype, -- then this expected kind will be the kind provided. Otherwise, -- it is OpenKind for datatypes and liftedTypeKind. -- Why do we not check for -XUnliftedNewtypes? See point -- in Note [Implementation of UnliftedNewtypes] -getArgExpKind :: NewOrData -> TcKind -> ContextKind +getArgExpKind :: NewOrData -> TcKind -> ConArgKind getArgExpKind NewType res_ki = TheKind res_ki getArgExpKind DataType _ = OpenKind @@ -3898,7 +3946,7 @@ tcConIsInfixGADT con details ; return (con `elemNameEnv` fix_env) } | otherwise -> return False -tcConH98Args :: ContextKind -- expected kind of arguments +tcConH98Args :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclH98Details GhcRn @@ -3912,7 +3960,7 @@ tcConH98Args exp_kind (InfixCon bty1 bty2) tcConH98Args exp_kind (RecCon fields) = tcRecConDeclFields exp_kind fields -tcConGADTArgs :: ContextKind -- expected kind of arguments +tcConGADTArgs :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclGADTDetails GhcRn @@ -3922,7 +3970,7 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (HsScaled w bty) @@ -3932,7 +3980,7 @@ tcConArg exp_kind (HsScaled w bty) ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, getBangStrictness bty) } -tcRecConDeclFields :: ContextKind +tcRecConDeclFields :: ConArgKind -> LocatedL [LConDeclField GhcRn] -> TcM [(Scaled TcType, HsSrcBang)] tcRecConDeclFields exp_kind fields View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e0ab8fe1dcab525680477018ce7f868c6d5d0c0a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e0ab8fe1dcab525680477018ce7f868c6d5d0c0a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 17:16:32 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 06 Jan 2025 12:16:32 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] unsafe counterpart ue_unitHomeUnit_maybe Message-ID: <677c0ff013856_18d042eb1e50115849@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 1920c3ab by Rodrigo Mesquita at 2025-01-06T17:16:20+00:00 unsafe counterpart ue_unitHomeUnit_maybe - - - - - 2 changed files: - compiler/GHC/Driver/Make.hs - compiler/GHC/Unit/Env.hs Changes: ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -1726,7 +1726,7 @@ downsweep_imports hsc_env old_summaries excl_mods allow_dup_roots (root_errs, ro return (NodeKey_Module (msKey s) : other_deps, final_done, final_summarised) where cache_key = (home_uid, mb_pkg, unLoc <$> gwib) - home_unit = expectJust "downsweep_imports" $ ue_unitHomeUnit_maybe home_uid (hsc_unit_env hsc_env) + home_unit = ue_unitHomeUnit home_uid (hsc_unit_env hsc_env) GWIB { gwib_mod = L loc mod, gwib_isBoot = is_boot } = gwib wanted_mod = L loc mod @@ -1759,7 +1759,7 @@ getRootSummary excl_mods old_summary_map hsc_env target _ -> Left (uid, moduleNotFoundErr modl) where Target {targetId, targetContents = maybe_buf, targetUnitId = uid} = target - home_unit = expectJust "getRootSummary" $ ue_unitHomeUnit_maybe uid (hsc_unit_env hsc_env) + home_unit = ue_unitHomeUnit uid (hsc_unit_env hsc_env) rootLoc = mkGeneralSrcSpan (fsLit "") dflags = homeUnitEnv_dflags (ue_findHomeUnitEnv uid (hsc_unit_env hsc_env)) @@ -1970,7 +1970,7 @@ enableCodeGenWhen logger tmpfs staticLife dynLife unit_env mod_graph = do not (backendGeneratesCode (backend dflags)) && -- Don't enable codegen for TH on indefinite packages; we -- can't compile anything anyway! See #16219. - isHomeUnitDefinite (expectJust "enableCodeGenWhen" $ ue_unitHomeUnit_maybe (ms_unitid ms) unit_env) + isHomeUnitDefinite (ue_unitHomeUnit (ms_unitid ms) unit_env) bytecode_and_enable enable_spec ms = -- In the situation where we **would** need to enable dynamic-too ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -51,6 +51,7 @@ module GHC.Unit.Env , ue_setActiveUnit , ue_currentUnit , ue_findHomeUnitEnv + , ue_unitHomeUnit , ue_unitHomeUnit_maybe , ue_updateHomeUnitEnv @@ -313,6 +314,9 @@ ue_unsafeHomeUnit ue = case ue_homeUnit ue of Nothing -> panic "unsafeGetHomeUnit: No home unit" Just h -> h +ue_unitHomeUnit :: UnitId -> UnitEnv -> HomeUnit +ue_unitHomeUnit uid = expectJust "ue_unitHomeUnit" . ue_unitHomeUnit_maybe uid + ue_unitHomeUnit_maybe :: UnitId -> UnitEnv -> Maybe HomeUnit ue_unitHomeUnit_maybe uid ue_env = HUG.homeUnitEnv_home_unit =<< HUG.lookupHugUnit uid (ue_home_unit_graph ue_env) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1920c3abf2542351f1bdcfe53d83c1c84aaa1bf6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1920c3abf2542351f1bdcfe53d83c1c84aaa1bf6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 17:54:55 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 06 Jan 2025 12:54:55 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] move hpt add to branch only Message-ID: <677c18efb756c_3663da2446f450e0@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 45116934 by Rodrigo Mesquita at 2025-01-06T17:54:44+00:00 move hpt add to branch only - - - - - 1 changed file: - compiler/GHC/Driver/Main.hs Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -1083,11 +1083,11 @@ initWholeCoreBindings :: Linkable -> IO Linkable initWholeCoreBindings hsc_env iface details (Linkable utc_time this_mod uls) = do - add_iface_to_hpt iface details hsc_env Linkable utc_time this_mod <$> mapM (go hsc_env) uls where go hsc_env' = \case CoreBindings wcb -> do + add_iface_to_hpt iface details hsc_env ~(bco, fos) <- unsafeInterleaveIO $ compileWholeCoreBindings hsc_env' type_env wcb pure (LazyBCOs bco fos) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/45116934a2ab8afe41c34539da2a9b657d07b383 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/45116934a2ab8afe41c34539da2a9b657d07b383 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 17:58:06 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 06 Jan 2025 12:58:06 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] Landmine after pruning Message-ID: <677c19ae8889_3663da3841f454e3@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 5f6dcccd by Rodrigo Mesquita at 2025-01-06T17:57:07+00:00 Landmine after pruning - - - - - 1 changed file: - compiler/GHC/Driver/Make.hs Changes: ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -774,8 +774,7 @@ load' mhmi_cache how_much diag_wrapper mHscMessage mod_graph = do -- write an empty HPT to allow the old HPT to be GC'd. let pruneHomeUnitEnv hme = do - emptyHPT <- liftIO emptyHomePackageTable - pure $! hme{ homeUnitEnv_hpt = emptyHPT } + pure $! hme{ homeUnitEnv_hpt = panic "after pruning home unit env, the hpt should never ever again be referenced." } hug' <- traverse pruneHomeUnitEnv (ue_home_unit_graph $ hsc_unit_env hsc_env) let ue' = (hsc_unit_env hsc_env){ ue_home_unit_graph = hug' } setSession $ discardIC hsc_env{hsc_unit_env = ue' } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f6dcccd5f29de1838ee0046648a5ff6b4936f49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f6dcccd5f29de1838ee0046648a5ff6b4936f49 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 6 18:09:46 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 06 Jan 2025 13:09:46 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] drop incorrect asymptotics Message-ID: <677c1c6a71a14_3663da3ee608588b@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 2c6b73ea by Rodrigo Mesquita at 2025-01-06T18:09:39+00:00 drop incorrect asymptotics - - - - - 1 changed file: - compiler/GHC/Unit/Home/PackageTable.hs Changes: ===================================== compiler/GHC/Unit/Home/PackageTable.hs ===================================== @@ -35,7 +35,7 @@ -- -- Or, do you really need a function to traverse all modules in the HPT? It is -- often better to keep the computation internal to this module, such as in --- 'hptCollectDependencies'... +-- 'hptCollectObjects'... module GHC.Unit.Home.PackageTable ( HomePackageTable(..) @@ -168,8 +168,6 @@ lookupHptByModule hpt mod -- the HPT is created for that module name. -- When the module already has an entry, inserting a new one entry in the HPT -- will always overwrite the existing entry for that module. --- --- $O(1)$ addHomeModInfoToHpt :: HomeModInfo -> HomePackageTable -> IO () addHomeModInfoToHpt hmi hpt = addToHpt hpt (moduleName (mi_module (hm_iface hmi))) hmi @@ -202,8 +200,6 @@ addListToHpt hpt = mapM_ (uncurry (addToHpt hpt)) -- | Get all 'CompleteMatches' (arising from COMPLETE pragmas) present in all -- modules from this unit's HPT. --- --- $O(n)$ in the number of modules. hptCompleteSigs :: HomePackageTable -> IO CompleteMatches hptCompleteSigs = concatHpt (md_complete_matches . hm_details) @@ -212,8 +208,6 @@ hptCompleteSigs = concatHpt (md_complete_matches . hm_details) -- Used in @tcRnImports@, to select the instances that are in the -- transitive closure of imports from the currently compiled module. -- ROMES:TODO: wait what? --- --- $O(n)$ in the number of modules. hptAllInstances :: HomePackageTable -> IO (InstEnv, [FamInst]) hptAllInstances hpt = do hits <- flip concatHpt hpt $ \mod_info -> do @@ -223,8 +217,6 @@ hptAllInstances hpt = do return (foldl' unionInstEnv emptyInstEnv insts, concat famInsts) -- | Find all the family instance declarations from the HPT --- --- $O(n)$ in the number of modules. hptAllFamInstances :: HomePackageTable -> IO (ModuleEnv FamInstEnv) hptAllFamInstances = fmap mkModuleEnv . concatHpt (\hmi -> [(hmiModule hmi, hmiFamInstEnv hmi)]) where @@ -233,8 +225,6 @@ hptAllFamInstances = fmap mkModuleEnv . concatHpt (\hmi -> [(hmiModule hmi, hmiF . md_fam_insts . hm_details -- | All annotations from the HPT --- --- $O(n)$ in the number of modules. hptAllAnnotations :: HomePackageTable -> IO AnnEnv hptAllAnnotations = fmap mkAnnEnv . concatHpt (md_anns . hm_details) @@ -245,8 +235,6 @@ hptAllAnnotations = fmap mkAnnEnv . concatHpt (md_anns . hm_details) -- | Collect the immediate dependencies of all modules in the HPT into a Set. -- The immediate dependencies are given by the iface as @'dep_direct_pkgs' . 'mi_deps'@. --- --- $O(n)$ in the number of modules in the HPT. hptCollectDependencies :: HomePackageTable -> IO (Set.Set UnitId) hptCollectDependencies HPT{table} = do hpt <- readIORef table View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c6b73ea0ba01c209c82cb517e4f0f22ca6984fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c6b73ea0ba01c209c82cb517e4f0f22ca6984fb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 04:37:01 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 06 Jan 2025 23:37:01 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Only kcConDecls for (A) newtype or (B) H98 style Message-ID: <677caf6de7f36_22e87cd76aa48053a@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 3de22cc8 by Patrick at 2025-01-07T12:36:43+08:00 Only kcConDecls for (A) newtype or (B) H98 style - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -947,11 +948,11 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Add constraints from the data constructors -- Fix #25611 - -- But becareful about the GADT style case, - -- do not unify LHS's kind with RHS's kind, -- See Note [Kind inference for data family instances] - ; kcConDecls new_or_data res_kind hs_cons - + ; case hs_cons of + (NewTypeCon _) -> kcConDecls new_or_data res_kind hs_cons + (DataTypeCons _ cons) | isH98 cons -> kcConDecls new_or_data res_kind hs_cons + _ -> return () -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there @@ -1008,6 +1009,9 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + isH98 cons = flip any (unLoc <$> cons) $ \case + ConDeclH98{} -> True + _ -> False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), -- and Note [Implementation of UnliftedDatatypes]. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3de22cc888fabe933007517be84c89de8a04cea2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3de22cc888fabe933007517be84c89de8a04cea2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 06:23:28 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Tue, 07 Jan 2025 01:23:28 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] add isH98orNewType for clarity Message-ID: <677cc86043d78_22e87c18ca31089817@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: c7f82a95 by Patrick at 2025-01-07T14:23:01+08:00 add isH98orNewType for clarity - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -949,10 +949,7 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Add constraints from the data constructors -- Fix #25611 -- See Note [Kind inference for data family instances] - ; case hs_cons of - (NewTypeCon _) -> kcConDecls new_or_data res_kind hs_cons - (DataTypeCons _ cons) | isH98 cons -> kcConDecls new_or_data res_kind hs_cons - _ -> return () + ; when isH98orNewType $ kcConDecls new_or_data res_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there @@ -1009,6 +1006,9 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + isH98orNewType = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> isH98 cons isH98 cons = flip any (unLoc <$> cons) $ \case ConDeclH98{} -> True _ -> False View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c7f82a95c93813af98ba939f180999bd5e12b6e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c7f82a95c93813af98ba939f180999bd5e12b6e2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 10:28:21 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 07 Jan 2025 05:28:21 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] 2 commits: Revert "Landmine after pruning" Message-ID: <677d01c56a367_239f06ce734942ea@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 432e4bc2 by Rodrigo Mesquita at 2025-01-07T10:25:01+00:00 Revert "Landmine after pruning" This reverts commit 5f6dcccd5f29de1838ee0046648a5ff6b4936f49. - - - - - e54108f2 by Rodrigo Mesquita at 2025-01-07T10:26:43+00:00 small comment - - - - - 1 changed file: - compiler/GHC/Driver/Make.hs Changes: ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -774,7 +774,9 @@ load' mhmi_cache how_much diag_wrapper mHscMessage mod_graph = do -- write an empty HPT to allow the old HPT to be GC'd. let pruneHomeUnitEnv hme = do - pure $! hme{ homeUnitEnv_hpt = panic "after pruning home unit env, the hpt should never ever again be referenced." } + -- set to empty rather than panic because it will be again inserted to during upsweep (below). + emptyHPT <- liftIO emptyHomePackageTable + pure $! hme{ homeUnitEnv_hpt = emptyHPT } hug' <- traverse pruneHomeUnitEnv (ue_home_unit_graph $ hsc_unit_env hsc_env) let ue' = (hsc_unit_env hsc_env){ ue_home_unit_graph = hug' } setSession $ discardIC hsc_env{hsc_unit_env = ue' } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c6b73ea0ba01c209c82cb517e4f0f22ca6984fb...e54108f24510e90f9a054c0e92a1ab2fceae538d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c6b73ea0ba01c209c82cb517e4f0f22ca6984fb...e54108f24510e90f9a054c0e92a1ab2fceae538d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 10:45:01 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 05:45:01 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Add tests for #23883 Message-ID: <677d05ace19a6_239f0623abb899145@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - 0efb7900 by Mike Pilgrem at 2024-12-31T11:41:48+00:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - b17fc06a by Luite Stegeman at 2025-01-07T05:44:45-05:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 06b68f59 by Matthew Pickering at 2025-01-07T05:44:46-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 78c441f0 by Simon Peyton Jones at 2025-01-07T05:44:47-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 30 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/TyCl.hs - docs/users_guide/using-optimisation.rst - libraries/base/changelog.md - libraries/base/src/Data/List/NonEmpty.hs - libraries/base/src/Data/Semigroup.hs - libraries/base/src/GHC/Base.hs - libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/src/GHC/Internal/Base.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs - libraries/ghc-internal/src/GHC/Internal/Data/Data.hs - libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs - libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs - + libraries/ghc-internal/src/GHC/Internal/Data/NonEmpty.hs - libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs - libraries/ghc-internal/src/GHC/Internal/Generics.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs - libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs - libraries/ghc-internal/src/GHC/Internal/Text/ParserCombinators/ReadP.hs - + testsuite/tests/core-to-stg/T25284/A.hs - + testsuite/tests/core-to-stg/T25284/B.hs - + testsuite/tests/core-to-stg/T25284/Cls.hs - + testsuite/tests/core-to-stg/T25284/Main.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/32d0b8ca0f35f35b87403a4cdb1d9d836e46d715...78c441f0ddce190ddcbba94aa03104ea9859c8fa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/32d0b8ca0f35f35b87403a4cdb1d9d836e46d715...78c441f0ddce190ddcbba94aa03104ea9859c8fa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 11:12:20 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 07 Jan 2025 06:12:20 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] 2 commits: revert to ue_unit_dbs Message-ID: <677d0c14707a1_18e40abcd7c66577@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 17d0a0c0 by Rodrigo Mesquita at 2025-01-07T10:36:08+00:00 revert to ue_unit_dbs - - - - - 8c869d92 by Rodrigo Mesquita at 2025-01-07T10:41:32+00:00 cleanup - - - - - 5 changed files: - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Unit/Env.hs Changes: ===================================== compiler/GHC/Core/Opt/Pipeline.hs ===================================== @@ -98,7 +98,7 @@ core2core hsc_env guts@(ModGuts { mg_module = mod dflags = hsc_dflags hsc_env logger = hsc_logger hsc_env extra_vars = interactiveInScope (hsc_IC hsc_env) - home_pkg_rules = rulesBelow hsc_env (moduleUnitId mod) + home_pkg_rules = hugRulesBelow hsc_env (moduleUnitId mod) (GWIB { gwib_mod = moduleName mod, gwib_isBoot = NotBoot }) name_ppr_ctx = mkNamePprCtx ptc (hsc_unit_env hsc_env) rdr_env ptc = initPromotionTickContext dflags ===================================== compiler/GHC/Driver/Backpack.hs ===================================== @@ -433,7 +433,7 @@ addUnit u = do logger <- getLogger let dflags0 = hsc_dflags hsc_env let old_unit_env = hsc_unit_env hsc_env - newdbs <- case ue_homeUnitDbs old_unit_env of + newdbs <- case ue_unit_dbs old_unit_env of Nothing -> panic "addUnit: called too early" Just dbs -> let newdb = UnitDatabase ===================================== compiler/GHC/Driver/Env.hs ===================================== @@ -29,9 +29,9 @@ module GHC.Driver.Env , lookupIfaceByModule , mainModIs - , rulesBelow - , instancesBelow - , annsBelow + , hugRulesBelow + , hugInstancesBelow + , hugAnnsBelow -- * Legacy API , hscUpdateHPT @@ -210,46 +210,9 @@ configured via command-line flags (in `GHC.setSessionDynFlags`). hscEPS :: HscEnv -> IO ExternalPackageState hscEPS hsc_env = readIORef (euc_eps (ue_eps (hsc_unit_env hsc_env))) - --------------------------------------------------------------------------------- --- TODO --------------------------------------------------------------------------------- --- WE MAY WANT TO CACHE SOME OF THESE AS WE BUILD UP THE HPT, to make these --- queries O(1). But it's kind of hard because they wouldn't be rehydrated!!!!! --- Then we'd have the HPT itself rehydrated, but the cached fields with --- bad references. - --- | Get annotations from all modules "below" this one (in the dependency --- sense) within the home units. If the module is @Nothing@, returns /all/ --- annotations in the home units. -annsBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv -annsBelow hsc_env uid mn = hugAnnsBelow hsc_env uid mn - ----- | Get rules from modules "below" this one (in the dependency sense) within ---the home units. -rulesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase -rulesBelow hsc_env uid mn = hugRulesBelow hsc_env uid mn - --- | Find instances visible from the given set of imports -instancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst]) -instancesBelow hsc_env uid mn = hugInstancesBelow hsc_env uid mn - -------------------------------------------------------------------------------- -- * Queries on Transitive Closure -------------------------------------------------------------------------------- --- ROMES:TODO: Something else I want to do here is to receive a ModuleGraph and --- then use the fast reachability queries to determine whether something is --- reachable or not. That means we can very efficiently filter out things which --- are not part of the transitive closure... --- --- So, e.g. it could probably be done faster by filtering out a cached list of --- rules using a 'ReachabilityIndex' as the filter $O(1)$ fast queries. - --- ROMES:TODO: Do something about the --- --- | isOneShot (ghcMode (hsc_dflags hsc_env)) = [] --- --- shortcut that we used when this was a function on HscEnv... -- | Find all rules in modules that are in the transitive closure of the given -- module. @@ -259,13 +222,16 @@ hugRulesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase hugRulesBelow hsc uid mn = foldr (flip extendRuleBaseList) emptyRuleBase <$> hugSomeThingsBelowUs (md_rules . hm_details) False hsc uid mn --- | Get annotations from modules "below" this one (in the dependency sense) +-- | Get annotations from all modules "below" this one (in the dependency +-- sense) within the home units. If the module is @Nothing@, returns /all/ +-- annotations in the home units. -- -- $O(n)$ in the number of dependencies? hugAnnsBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv hugAnnsBelow hsc uid mn = foldr (flip extendAnnEnvList) emptyAnnEnv <$> hugSomeThingsBelowUs (md_anns . hm_details) False hsc uid mn +-- | Find instances visible from the given set of imports hugInstancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst]) hugInstancesBelow hsc_env uid mnwib = do -- ouch... improve ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -462,7 +462,7 @@ tcRnImports hsc_env import_decls -- modules batch (@--make@) compiled before this one, but -- which are not below this one. ; (home_insts, home_fam_insts) <- liftIO $ - instancesBelow hsc_env unitId mnwib + hugInstancesBelow hsc_env unitId mnwib -- Record boot-file info in the EPS, so that it's -- visible to loadHiBootInterface in tcRnSrcDecls, ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -82,7 +82,7 @@ module GHC.Unit.Env -- ** Queries on the current active home unit , ue_homeUnitState - , ue_homeUnitDbs + , ue_unit_dbs , ue_homeUnit , ue_unitFlags @@ -262,8 +262,8 @@ ue_findHomeUnitEnv uid e = case HUG.lookupHugUnit uid (ue_home_unit_graph e) of ue_homeUnitState :: HasDebugCallStack => UnitEnv -> UnitState ue_homeUnitState = HUG.homeUnitEnv_units . ue_currentHomeUnitEnv -ue_homeUnitDbs :: UnitEnv -> Maybe [UnitDatabase UnitId] -ue_homeUnitDbs = HUG.homeUnitEnv_unit_dbs . ue_currentHomeUnitEnv +ue_unit_dbs :: UnitEnv -> Maybe [UnitDatabase UnitId] +ue_unit_dbs = HUG.homeUnitEnv_unit_dbs . ue_currentHomeUnitEnv -- ------------------------------------------------------- -- Query and modify Home Package Table in HomeUnitEnv View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e54108f24510e90f9a054c0e92a1ab2fceae538d...8c869d9278b091ca0bdc15104cd00c39f17ab23b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e54108f24510e90f9a054c0e92a1ab2fceae538d...8c869d9278b091ca0bdc15104cd00c39f17ab23b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 11:43:37 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 07 Jan 2025 06:43:37 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] clean up Message-ID: <677d1369495f2_7fde31d64d847055@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 9e4eb447 by Rodrigo Mesquita at 2025-01-07T11:28:16+00:00 clean up - - - - - 4 changed files: - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Unit/Env.hs - compiler/GHC/Unit/Home/Graph.hs Changes: ===================================== compiler/GHC/Driver/Env.hs ===================================== @@ -216,8 +216,6 @@ hscEPS hsc_env = readIORef (euc_eps (ue_eps (hsc_unit_env hsc_env))) -- | Find all rules in modules that are in the transitive closure of the given -- module. --- --- $O(n)$ in the number of dependencies? hugRulesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO RuleBase hugRulesBelow hsc uid mn = foldr (flip extendRuleBaseList) emptyRuleBase <$> hugSomeThingsBelowUs (md_rules . hm_details) False hsc uid mn @@ -225,8 +223,6 @@ hugRulesBelow hsc uid mn = foldr (flip extendRuleBaseList) emptyRuleBase <$> -- | Get annotations from all modules "below" this one (in the dependency -- sense) within the home units. If the module is @Nothing@, returns /all/ -- annotations in the home units. --- --- $O(n)$ in the number of dependencies? hugAnnsBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO AnnEnv hugAnnsBelow hsc uid mn = foldr (flip extendAnnEnvList) emptyAnnEnv <$> hugSomeThingsBelowUs (md_anns . hm_details) False hsc uid mn @@ -234,7 +230,6 @@ hugAnnsBelow hsc uid mn = foldr (flip extendAnnEnvList) emptyAnnEnv <$> -- | Find instances visible from the given set of imports hugInstancesBelow :: HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO (InstEnv, [FamInst]) hugInstancesBelow hsc_env uid mnwib = do --- ouch... improve let mn = gwib_mod mnwib (insts, famInsts) <- unzip . concat <$> @@ -252,18 +247,7 @@ hugInstancesBelow hsc_env uid mnwib = do -- | Get things from modules in the transitive closure of the given module. -- --- Note: Don't expose this function. We can improve the interface further -- --- let's keep the queries on the HPT contained in this module so we can optimise --- internally without breaking the API to the rest of GHC. This is a footgun if --- exposed! --- --- NOTE: We should be able to import this considerably with the reachability --- index and caching?... --- --- For example, easiest to go through all modules and filter out the ones in the --- hpt via the module graph......... --- --- TODO: This include_hi_boot business is also pretty weird. Do we need it at all? +-- Note: Don't expose this function. This is a footgun if exposed! hugSomeThingsBelowUs :: (HomeModInfo -> [a]) -> Bool -> HscEnv -> UnitId -> ModuleNameWithIsBoot -> IO [[a]] hugSomeThingsBelowUs extract include_hi_boot hsc_env uid mn = let hug = hsc_HUG hsc_env ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -774,7 +774,6 @@ load' mhmi_cache how_much diag_wrapper mHscMessage mod_graph = do -- write an empty HPT to allow the old HPT to be GC'd. let pruneHomeUnitEnv hme = do - -- set to empty rather than panic because it will be again inserted to during upsweep (below). emptyHPT <- liftIO emptyHomePackageTable pure $! hme{ homeUnitEnv_hpt = emptyHPT } hug' <- traverse pruneHomeUnitEnv (ue_home_unit_graph $ hsc_unit_env hsc_env) ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -101,7 +101,6 @@ module GHC.Unit.Env , hugAllInstances , hugAllAnns - -- * Legacy API -- -- | This API is deprecated! ===================================== compiler/GHC/Unit/Home/Graph.hs ===================================== @@ -193,8 +193,6 @@ restrictHug deps hug = unitEnv_foldWithKey (\k uid hue -> restrict_one uid hue > restrict_one uid hue = restrictHpt (homeUnitEnv_hpt hue) (Map.findWithDefault [] uid deps_map) - - -- | Rename a unit id in the 'HomeUnitGraph' -- -- @'renameUnitId' oldUnit newUnit hug@, if @oldUnit@ is not found in @hug@, returns 'Nothing'. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e4eb44726001f1d8d59a7c1773802723ba2b889 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e4eb44726001f1d8d59a7c1773802723ba2b889 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 12:28:57 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Tue, 07 Jan 2025 07:28:57 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/runTcPluginsWanted-typo Message-ID: <677d1e099656e_f493817ff20367a7@gitlab.mail> sheaf pushed new branch wip/runTcPluginsWanted-typo at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/runTcPluginsWanted-typo You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 12:57:42 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Tue, 07 Jan 2025 07:57:42 -0500 Subject: [Git][ghc/ghc][wip/T18462] Multiplicity annotation on records Message-ID: <677d24c6ef68c_f493863a6b4479c5@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 86b8173a by Sjoerd Visscher at 2025-01-07T13:57:30+01:00 Multiplicity annotation on records - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - docs/users_guide/9.14.1-notes.rst - docs/users_guide/exts/linear_types.rst - testsuite/tests/ghc-api/exactprint/Test20239.stderr - 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/linear/should_compile/NonLinearRecord.hs - testsuite/tests/linear/should_compile/all.T - + testsuite/tests/linear/should_fail/LinearRecFieldMany.hs - + testsuite/tests/linear/should_fail/LinearRecFieldMany.stderr - testsuite/tests/linear/should_fail/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/86b8173ab06b9a4c3495a9ce17a5a80a76f443ed -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/86b8173ab06b9a4c3495a9ce17a5a80a76f443ed You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 12:59:07 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 07:59:07 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Add flags for switching off speculative evaluation. Message-ID: <677d251bd91df_f49387032f85002@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5ad1abca by Luite Stegeman at 2025-01-07T04:35:15+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 1d872b38 by Matthew Pickering at 2025-01-07T07:58:47-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 4483a1ef by Simon Peyton Jones at 2025-01-07T07:58:48-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 14 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/TyCl.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/core-to-stg/T25284/A.hs - + testsuite/tests/core-to-stg/T25284/B.hs - + testsuite/tests/core-to-stg/T25284/Cls.hs - + testsuite/tests/core-to-stg/T25284/Main.hs - + testsuite/tests/core-to-stg/T25284/T25284.stdout - + testsuite/tests/core-to-stg/T25284/all.T Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2051,6 +2051,16 @@ conceptually. See also Note [Floats and FloatDecision] for how we maintain whole groups of floats and how far they go. +Note [Controlling Speculative Evaluation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Most of the time, speculative evaluation has a positive effect on performance, +but we have found a case where speculative evaluation of dictionary functions +leads to a performance regression #25284. + +Therefore we have some flags to control it. See the optimization section in +the User's Guide for the description of these flags and when to use them. + Note [Floats and FloatDecision] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We have a special datatype `Floats` for modelling a telescope of `FloatingBind` @@ -2275,7 +2285,15 @@ mkNonRecFloat env lev bndr rhs } is_hnf = exprIsHNF rhs - ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs + cfg = cpe_config env + + ok_for_spec = exprOkForSpecEval call_ok_for_spec rhs + -- See Note [Controlling Speculative Evaluation] + call_ok_for_spec x + | is_rec_call x = False + | not (cp_specEval cfg) = False + | not (cp_specEvalDFun cfg) && isDFunId x = False + | otherwise = True is_rec_call = (`elemUnVarSet` cpe_rec_ids env) -- See Note [Pin evaluatedness on floats] @@ -2517,6 +2535,11 @@ data CorePrepConfig = CorePrepConfig -- ^ Configuration for arity analysis ('exprEtaExpandArity'). -- See Note [Eta expansion of arguments in CorePrep] -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead + , cp_specEval :: !Bool + -- ^ Whether to perform speculative evaluation + -- See Note [Controlling Speculative Evaluation] + , cp_specEvalDFun :: !Bool + -- ^ Whether to perform speculative evaluation on DFuns } data CorePrepEnv ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -24,6 +24,8 @@ initCorePrepConfig hsc_env = do , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags then Just (initArityOpts dflags) else Nothing + , cp_specEval = gopt Opt_SpecEval dflags + , cp_specEvalDFun = gopt Opt_SpecEvalDictFun dflags } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1287,6 +1287,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] -- RegsGraph suffers performance regression. See #7679 -- , ([2], Opt_StaticArgumentTransformation) -- Static Argument Transformation needs investigation. See #9374 + , ([0,1,2], Opt_SpecEval) + , ([0,1,2], Opt_SpecEvalDictFun) ] ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -674,6 +674,9 @@ data GeneralFlag | Opt_NumConstantFolding | Opt_CoreConstantFolding | Opt_FastPAPCalls -- #6084 + | Opt_SpecEval + | Opt_SpecEvalDictFun -- See Note [Controlling Speculative Evaluation] + -- Inference flags | Opt_DoTagInferenceChecks @@ -912,6 +915,8 @@ optimisationFlags = EnumSet.fromList , Opt_WorkerWrapper , Opt_WorkerWrapperUnlift , Opt_SolveConstantDicts + , Opt_SpecEval + , Opt_SpecEvalDictFun ] -- | The set of flags which affect code generation and can change a program's ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2544,6 +2544,8 @@ fFlagsDeps = [ flagSpec "num-constant-folding" Opt_NumConstantFolding, flagSpec "core-constant-folding" Opt_CoreConstantFolding, flagSpec "fast-pap-calls" Opt_FastPAPCalls, + flagSpec "spec-eval" Opt_SpecEval, + flagSpec "spec-eval-dictfun" Opt_SpecEvalDictFun, flagSpec "cmm-control-flow" Opt_CmmControlFlow, flagSpec "show-warning-groups" Opt_ShowWarnGroups, flagSpec "hide-source-paths" Opt_HideSourcePaths, ===================================== compiler/GHC/Rename/Unbound.hs ===================================== @@ -34,10 +34,11 @@ import GHC.Prelude import GHC.Driver.DynFlags import GHC.Driver.Ppr +import GHC.Driver.Env.Types import GHC.Tc.Errors.Types import GHC.Tc.Utils.Monad -import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique) +import GHC.Builtin.Names ( mkUnboundName, isUnboundName ) import GHC.Utils.Misc import GHC.Utils.Panic (panic) @@ -53,16 +54,16 @@ import GHC.Types.Hint import GHC.Types.SrcLoc as SrcLoc import GHC.Types.Name import GHC.Types.Name.Reader -import GHC.Types.Unique.DFM (udfmToList) import GHC.Unit.Module import GHC.Unit.Module.Imported -import GHC.Unit.Home.ModInfo +import GHC.Utils.Outputable +import GHC.Runtime.Context import GHC.Data.Bag -import GHC.Utils.Outputable (empty) +import Language.Haskell.Syntax.ImpExp -import Data.List (sortBy, partition, nub) +import Data.List (sortBy, partition) import Data.List.NonEmpty ( pattern (:|), NonEmpty ) import Data.Function ( on ) import qualified Data.Semigroup as S @@ -146,10 +147,10 @@ unboundNameOrTermInType if_term_in_type looking_for rdr_name hints ; global_env <- getGlobalRdrEnv ; impInfo <- getImports ; currmod <- getModule - ; hpt <- getHpt + ; ic <- hsc_IC <$> getTopEnv ; let (imp_errs, suggs) = unknownNameSuggestions_ looking_for - dflags hpt currmod global_env local_env impInfo + dflags ic currmod global_env local_env impInfo rdr_name ; addErr $ make_error imp_errs (hints ++ suggs) } @@ -179,17 +180,17 @@ notInScopeErr where_look rdr_name unknownNameSuggestions :: LocalRdrEnv -> WhatLooking -> RdrName -> RnM ([ImportError], [GhcHint]) unknownNameSuggestions lcl_env what_look tried_rdr_name = do { dflags <- getDynFlags - ; hpt <- getHpt ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports ; curr_mod <- getModule + ; interactive_context <- hsc_IC <$> getTopEnv ; return $ unknownNameSuggestions_ (LF what_look WL_Anywhere) - dflags hpt curr_mod rdr_env lcl_env imp_info tried_rdr_name } + dflags interactive_context curr_mod rdr_env lcl_env imp_info tried_rdr_name } -unknownNameSuggestions_ :: LookingFor -> DynFlags - -> HomePackageTable -> Module +unknownNameSuggestions_ :: LookingFor -> DynFlags -> InteractiveContext + -> Module -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails -> RdrName -> ([ImportError], [GhcHint]) unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env @@ -201,7 +202,7 @@ unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env , map (ImportSuggestion $ rdrNameOcc tried_rdr_name) imp_suggs , extensionSuggestions tried_rdr_name , fieldSelectorSuggestions global_env tried_rdr_name ] - (imp_errs, imp_suggs) = importSuggestions looking_for global_env hpt curr_mod imports tried_rdr_name + (imp_errs, imp_suggs) = importSuggestions looking_for hpt curr_mod imports tried_rdr_name if_ne :: (NonEmpty a -> b) -> [a] -> [b] if_ne _ [] = [] @@ -308,15 +309,13 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env -- | Generate errors and helpful suggestions if a qualified name Mod.foo is not in scope. importSuggestions :: LookingFor - -> GlobalRdrEnv - -> HomePackageTable -> Module + -> InteractiveContext -> Module -> ImportAvails -> RdrName -> ([ImportError], [ImportSuggestion]) -importSuggestions looking_for global_env hpt currMod imports rdr_name +importSuggestions looking_for ic currMod imports rdr_name | WL_LocalOnly <- lf_where looking_for = ([], []) | WL_LocalTop <- lf_where looking_for = ([], []) | not (isQual rdr_name || isUnqual rdr_name) = ([], []) - | null interesting_imports - , Just name <- mod_name + | Just name <- mod_name , show_not_imported_line name = ([MissingModule name], []) | is_qualified @@ -344,6 +343,17 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name , Just imp <- return $ pick (importedByUser mod_imports) ] + -- Choose the imports from the interactive context which might have provided + -- a module. + interactive_imports = + filter pick_interactive (ic_imports ic) + + pick_interactive :: InteractiveImport -> Bool + pick_interactive (IIDecl d) | mod_name == Just (unLoc (ideclName d)) = True + | mod_name == fmap unLoc (ideclAs d) = True + pick_interactive (IIModule m) | mod_name == Just m = True + pick_interactive _ = False + -- We want to keep only one for each original module; preferably one with an -- explicit import list (for no particularly good reason) pick :: [ImportedModsVal] -> Maybe ImportedModsVal @@ -369,17 +379,10 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name -- See Note [When to show/hide the module-not-imported line] show_not_imported_line :: ModuleName -> Bool -- #15611 show_not_imported_line modnam - | modnam `elem` glob_mods = False -- #14225 -- 1 - | moduleName currMod == modnam = False -- 2.1 - | is_last_loaded_mod modnam hpt_uniques = False -- 2.2 + | not (null interactive_imports) = False -- 1 (interactive context) + | not (null interesting_imports) = False -- 1 (normal module import) + | moduleName currMod == modnam = False -- 2 | otherwise = True - where - hpt_uniques = map fst (udfmToList hpt) - is_last_loaded_mod modnam uniqs = lastMaybe uniqs == Just (getUnique modnam) - glob_mods = nub [ mod - | gre <- globalRdrEnvElts global_env - , (mod, _) <- qualsInScope gre - ] extensionSuggestions :: RdrName -> [GhcHint] extensionSuggestions rdrName @@ -478,13 +481,8 @@ For the error message: Module X does not export Y No module named ‘X’ is imported: there are 2 cases, where we hide the last "no module is imported" line: -1. If the module X has been imported. -2. If the module X is the current module. There are 2 subcases: - 2.1 If the unknown module name is in a input source file, - then we can use the getModule function to get the current module name. - (See test T15611a) - 2.2 If the unknown module name has been entered by the user in GHCi, - then the getModule function returns something like "interactive:Ghci1", - and we have to check the current module in the last added entry of - the HomePackageTable. (See test T15611b) +1. If the module X has been imported (normally or via interactive context). +2. It is the current module we are trying to compile + then we can use the getModule function to get the current module name. + (See test T15611a) -} ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1759,7 +1759,9 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- - In this function, those TcTyVars are unified with other kind variables during -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) -kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) tycon +kcTyClDecl (DataDecl { tcdLName = (L _ _name) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no -- harm. For GADTs, each data con brings its own tyvars into scope, @@ -1767,7 +1769,7 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (dataDefnConsNewOrData cons) (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1799,67 +1801,70 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM () -kcConArgTys new_or_data res_kind arg_tys = do - { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) +kcConArgTys :: ConArgKind -- Expected kind of the argument(s) + -> [HsScaled GhcRn (LHsType GhcRn)] -- User-written argument types + -> TcM () +kcConArgTys exp_kind arg_tys + = forM_ arg_tys $ \(HsScaled mult ty) -> + do { _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + ; tcMult mult } -- See Note [Implementation of UnliftedNewtypes], STEP 2 - } -- Kind-check the types of arguments to a Haskell98 data constructor. -kcConH98Args :: NewOrData -> TcKind -> HsConDeclH98Details GhcRn -> TcM () -kcConH98Args new_or_data res_kind con_args = case con_args of - PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys - InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] - RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConH98Args :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclH98Details GhcRn + -> TcM () +kcConH98Args exp_kind con_args = case con_args of + PrefixCon _ tys -> kcConArgTys exp_kind tys + InfixCon ty1 ty2 -> kcConArgTys exp_kind [ty1, ty2] + RecCon (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. -kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () -kcConGADTArgs new_or_data res_kind con_args = case con_args of - PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys - RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConGADTArgs :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclGADTDetails GhcRn + -> TcM () +kcConGADTArgs exp_kind con_args = case con_args of + PrefixConGADT _ tys -> kcConArgTys exp_kind tys + RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -kcConDecls :: Foldable f - => NewOrData - -> TcKind -- The result kind signature - -- Used only in H98 case - -> f (LConDecl GhcRn) -- The data constructors - -> TcM () +kcConDecls :: TcKind -- Result kind of tycon + -- Used only in H98 case + -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls new_or_data tc_res_kind = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) +kcConDecls tc_res_kind cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons + where + new_or_data = dataDefnConsNewOrData cons -- Kind check a data constructor. In additional to the data constructor, -- we also need to know about whether or not its corresponding type was -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData - -> TcKind -- Result kind of the type constructor - -- Usually Type but can be TYPE UnliftedRep - -- or even TYPE r, in the case of unlifted newtype - -- Used only in H98 case - -> ConDecl GhcRn - -> TcM () -kcConDecl new_or_data tc_res_kind (ConDeclH98 - { con_name = name, con_ex_tvs = ex_tvs - , con_mb_cxt = ex_ctxt, con_args = args }) +kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data tc_res_kind + (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs + , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (dataConCtxt (NE.singleton name)) $ discardResult $ bindExplicitTKBndrs_Tv ex_tvs $ do { _ <- tcHsContext ex_ctxt - ; kcConH98Args new_or_data tc_res_kind args + ; let arg_exp_kind = getArgExpKind new_or_data tc_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same as the tc_res_kind. See (KCD1) + -- in Note [kcConDecls: kind-checking data type decls] + ; kcConH98Args arg_exp_kind args -- We don't need to check the telescope here, -- because that's done in tcConDecl } -kcConDecl new_or_data - _tc_res_kind -- Not used in GADT case (and doesn't make sense) - (ConDeclGADT - { con_names = names, con_bndrs = L _ outer_bndrs, con_mb_cxt = cxt - , con_g_args = args, con_res_ty = res_ty }) +kcConDecl new_or_data _tc_res_kind + -- NB: _tc_res_kind is unused. See (KCD3) in + -- Note [kcConDecls: kind-checking data type decls] + (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs + , con_mb_cxt = cxt, con_g_args = args, con_res_ty = res_ty }) = -- See Note [kcConDecls: kind-checking data type decls] addErrCtxt (dataConCtxt names) $ discardResult $ @@ -1870,45 +1875,80 @@ kcConDecl new_or_data ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) ; con_res_kind <- newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - ; kcConGADTArgs new_or_data con_res_kind args - ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind) + + ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same the kind of `res_ty`, the data con's return type + -- See (KCD2) in Note [kcConDecls: kind-checking data type decls] + ; kcConGADTArgs arg_exp_kind args + + ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr arg_exp_kind) ; return () } {- Note [kcConDecls: kind-checking data type decls] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kcConDecls is used when we are inferring the kind of the type -constructor in a data type declaration. E.g. - data T f a = MkT (f a) -we want to infer the kind of 'f' and 'a'. The basic plan is described -in Note [Inferring kinds for type declarations]; here we are doing Step 2. - -In the GADT case we may have this: - data T f a where - MkT :: forall g b. g b -> T g b - -Notice that the variables f,a, and g,b are quite distinct. -Nevertheless, the type signature for MkT must still influence the kind -T which is (remember Step 1) something like - T :: kappa1 -> kappa2 -> Type -Otherwise we'd infer the bogus kind - T :: forall k1 k2. k1 -> k2 -> Type. - -The type signature for MkT influences the kind of T simply by -kind-checking the result type (T g b), which will force 'f' and 'g' to -have the same kinds. This is the call to - tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) -Because this is the result type of an arrow, we know the kind must be -of form (TYPE rr), and we get better error messages if we enforce that -here (e.g. test gadt10). - -For unlifted newtypes only, we must ensure that the argument kind -and result kind are the same: -* In the H98 case, we need the result kind of the TyCon, to unify with - the argument kind. - -* In GADT syntax, this unification happens via the result kind passed - to kcConGADTArgs. The tycon's result kind is not used at all in the - GADT case. +constructor in a data type declaration. The basic plan is described in +Note [Inferring kinds for type declarations]; here we are doing Step 2. + +We are kind-checking the data constructors /only/ to compute the kind of +the type construtor. For example + data T f a = MkT (f a) +The (f a) in the data construtor constrains the kinds of `f` and `a`, and hence +of `T`. + +There are two cases to consider in `kcConDecl` + +* Haskell 98 data constructors, as above. We simply bring `f` and `a` + into scope and kind-check the data constructors. + +* GADT data type decls e.g. + data S f a where + MkS :: g b -> S g b + Here `f` and `a` don't scope over the data constructor signatures. + Instead, we just kind-check the entire signature (including the result `S g b`), + relying on the fact that `S` is in scope with its initial kind `k1 -> k2 -> Type`; + doing so will constrain `k1` and `k2` appropriately. + +The arguments of each data constructor are always of kind (TYPE r) for some +r :: RuntimeRep. But in the case of a newytype, the argument kind must be +the same as the tycon result kind. Since we are trying to figure out the +tycon kind, kcConDecls must account for this, which is surprisingly tricky. +Again there are two cases to consider in `kcConDecl`: + +* Haskell 98 data type decls, e.g. + data T f a = MkT (f a) + * In the header, all the tycon binders are specified (here `f` and `a`) + and there is no result kind signature. + * The binders from the header scope over the data construtors. + * In the case of unlifted newtypes, the argument kind affects the tycon kind + newtype N = MkN Int# + Here `getInitialKind` will give `N` the result kind `TYPE r`, where `r` is + a unification variable, and `kcConDecls` should unify that `r` with + `IntRep` becuase of the `Int#` + + Solution (KCD1): just check that the argumet type has the same kind as the result + kind of the tycon. + +* GADT data type decls e.g. + data S f :: Type -> Type where + MkS :: g a -> S g a + * In the header, not all the tycon binders are specified (here just `f`), + and there can be a kind signature + * The kind signature may describe some, all, or none of the tycon binders. + Regardless, in the TcTyCon constructed by `getInitialKind`, the tyConResKind + is the signature, not the "ultimate" result type of the tycon (which is + usually Type) + * In the case of unlifted newtypes, we again want the argument kind to be the + same as the result kind of the tycon; but it's not so clear what /is/ the + result kind of the tycon, because of the signature stuff in the previous bullet. + + Solution (KCD2): kind-check the result type of the data constructor (here + `S g a`) and, for newtypes, ensure that the arugment has that same kind. + + (KCD3) The tycon's result kind `tc_res_kind` is not used at all in the GADT + case; rather it is accessed via looking up S's kind in the type environment + when kind-checking the result type of the data constructor. Note [Using TyVarTvs for kind-checking GADTs] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3866,13 +3906,21 @@ nothing wrong with it). We are implicitly requiring tha tcInferLHsTypeKind doesn't any gratuitous top-level casts. -} + +type ConArgKind = ContextKind + -- The expected kind of the argument(s) of a constructor + -- For data types this is always OpenKind + -- For newtypes it is (TheKind ki) + -- where `ki` is the result kind of the newtype + -- With NoUnliftedNewtype, ki=Type, but with UnliftedNewtypes it can be a variable + -- | Produce an "expected kind" for the arguments of a data/newtype. -- If the declaration is indeed for a newtype, -- then this expected kind will be the kind provided. Otherwise, -- it is OpenKind for datatypes and liftedTypeKind. -- Why do we not check for -XUnliftedNewtypes? See point -- in Note [Implementation of UnliftedNewtypes] -getArgExpKind :: NewOrData -> TcKind -> ContextKind +getArgExpKind :: NewOrData -> TcKind -> ConArgKind getArgExpKind NewType res_ki = TheKind res_ki getArgExpKind DataType _ = OpenKind @@ -3898,7 +3946,7 @@ tcConIsInfixGADT con details ; return (con `elemNameEnv` fix_env) } | otherwise -> return False -tcConH98Args :: ContextKind -- expected kind of arguments +tcConH98Args :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclH98Details GhcRn @@ -3912,7 +3960,7 @@ tcConH98Args exp_kind (InfixCon bty1 bty2) tcConH98Args exp_kind (RecCon fields) = tcRecConDeclFields exp_kind fields -tcConGADTArgs :: ContextKind -- expected kind of arguments +tcConGADTArgs :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclGADTDetails GhcRn @@ -3922,7 +3970,7 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (HsScaled w bty) @@ -3932,7 +3980,7 @@ tcConArg exp_kind (HsScaled w bty) ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, getBangStrictness bty) } -tcRecConDeclFields :: ContextKind +tcRecConDeclFields :: ConArgKind -> LocatedL [LConDeclField GhcRn] -> TcM [(Scaled TcType, HsSrcBang)] tcRecConDeclFields exp_kind fields ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -405,6 +405,55 @@ as such you shouldn't need to set any of them explicitly. A flag intermediate language, where it is able to common up some subexpressions that differ in their types, but not their representation. +.. ghc-flag:: -fspec-eval + :shortdesc: Enables speculative evaluation. + :type: dynamic + :category: + :reverse: -fno-spec-eval + + :default: on + :since: 9.14.1 + + Enables speculative evaluation which usually results in fewer allocations. + Enabling speculative evaluation should not cause performance regressions. + If you encounter any, please open a ticket. + + Note that disabling this flag will switch off speculative evaluation + completely, causing :ghc-flag:`-fspec-eval-dictfun` to have + no effect. + +.. ghc-flag:: -fspec-eval-dictfun + :shortdesc: Enables speculative evaluation of dictionary functions. + :type: dynamic + :category: + :reverse: -fno-spec-eval-dictfun + + :default: on + :since: 9.14.1 + + Enables speculative (strict) evaluation of dictionary functions. + + This is best explained with an example :: + + instance C a => D a where ... + + g :: D a => a -> Int + g x = ... + + f :: C a => a -> Int + f x = g x + + Function `f` has to pass a `D a` dictionary to `g`, and uses a dictionary + function `C a => D a` to compute it. If speculative evaluation for + dictionary functions is enabled, this dictionary is computed + strictly. + + Speculative evalation of dictionary functions can lead to slightly better + performance, because a thunk is avoided. However, it results in unnecessary + computation and allocation if the dictionary goes unused. This causes + a significant increase in allocation if the dictionary is large. + See (:ghc-ticket:`25284`). + .. ghc-flag:: -fdicts-cheap :shortdesc: Make dictionary-valued expressions seem cheap to the optimiser. :type: dynamic ===================================== testsuite/tests/core-to-stg/T25284/A.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fspec-eval-dictfun #-} +module A (testX) where + +import qualified Cls + +-- this creates the big dictionary strictly because of speculative evaluation +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/B.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fno-spec-eval-dictfun #-} +module B (testX) where + +import qualified Cls + +-- this creates the big dictionary lazily +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/Cls.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE UndecidableInstances #-} + +module Cls where + +class HasConst a where constVal :: a + +instance Cls.HasConst Word where constVal = 123 + +instance Cls.HasConst Int where constVal = 456 + +-- this class has a big dictionary +class HasConst10 a where + constA :: a + constInt1 :: a -> Int + constInt1 _ = 1 + constInt2 :: a -> Int + constInt2 _ = 2 + constInt3 :: a -> Int + constInt3 _ = 3 + constInt4 :: a -> Int + constInt4 _ = 4 + constInt5 :: a -> Int + constInt5 _ = 5 + constInt6 :: a -> Int + constInt6 _ = 6 + constInt7 :: a -> Int + constInt7 _ = 7 + constInt8 :: a -> Int + constInt8 _ = 8 + constInt9 :: a -> Int + constInt9 _ = 9 + +instance HasConst a => HasConst10 a where + constA = constVal + +-- this doesn't use the big dictionary most of the time +printConst :: forall a. (Show a, HasConst10 a) + => a -> Int -> IO () +printConst x 5000 = print @a constA >> print (constInt8 x) +printConst _ _ = pure () ===================================== testsuite/tests/core-to-stg/T25284/Main.hs ===================================== @@ -0,0 +1,57 @@ +{- + + This tests that speculative evaluation for dictionary functions works as + expected, with a large dictionary that goes unused. + + - Module A: dictfun speculative evaluation enabled + - Module B: dictfun speculative evaluation disabled + + Speculative evaluation causes the unused large dictionary to be allocated + strictly in module A, so we expect more allocations than in module B. + + -} +module Main where + +import qualified A +import qualified B +import qualified Cls + +import Data.Word +import System.Mem (performGC) +import GHC.Stats +import Control.Monad + +{-# NOINLINE getAllocated #-} +getAllocated :: IO Word64 +getAllocated = do + performGC + allocated_bytes <$> getRTSStats + +main :: IO () +main = do + -- warm up (just in case) + _ <- testMain A.testX + _ <- testMain B.testX + + -- for real + a_alloc <- testMain A.testX + b_alloc <- testMain B.testX + + -- expect B to allocate less than A + let alloc_ratio :: Double + alloc_ratio = fromIntegral b_alloc / fromIntegral a_alloc + putStrLn ("expected alloc: " ++ show (alloc_ratio < 0.7)) + +iter :: (Int -> IO ()) -> Int -> Int -> IO () +iter m !i !j + | i < j = m i >> iter m (i+1) j + | otherwise = pure () + +{-# NOINLINE testMain #-} +testMain :: (forall b. (Show b, Cls.HasConst b) => b -> Int -> IO ()) + -> IO Word64 +testMain f = do + alloc0 <- getAllocated + iter (\i -> f (0::Int) i >> f (0::Word) i) 1 100000 + alloc1 <- getAllocated + pure (alloc1 - alloc0) ===================================== testsuite/tests/core-to-stg/T25284/T25284.stdout ===================================== @@ -0,0 +1,17 @@ +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +expected alloc: True ===================================== testsuite/tests/core-to-stg/T25284/all.T ===================================== @@ -0,0 +1,5 @@ +test('T25284', + [extra_files(['Main.hs', 'A.hs', 'B.hs', 'Cls.hs']), + extra_run_opts('+RTS -T -RTS')], + multimod_compile_and_run, + ['Main', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/78c441f0ddce190ddcbba94aa03104ea9859c8fa...4483a1efb3e98f9cd0bd5a73b2c2c456ebcb684b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/78c441f0ddce190ddcbba94aa03104ea9859c8fa...4483a1efb3e98f9cd0bd5a73b2c2c456ebcb684b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 13:53:10 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 08:53:10 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: warnings: Find out if a qualified name is in the interactive scope directly Message-ID: <677d31c64d601_24f1994772b4890d0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 25ead7f9 by Matthew Pickering at 2025-01-07T08:52:55-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 11ae78c6 by Simon Peyton Jones at 2025-01-07T08:52:55-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 2 changed files: - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Rename/Unbound.hs ===================================== @@ -34,10 +34,11 @@ import GHC.Prelude import GHC.Driver.DynFlags import GHC.Driver.Ppr +import GHC.Driver.Env.Types import GHC.Tc.Errors.Types import GHC.Tc.Utils.Monad -import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique) +import GHC.Builtin.Names ( mkUnboundName, isUnboundName ) import GHC.Utils.Misc import GHC.Utils.Panic (panic) @@ -53,16 +54,16 @@ import GHC.Types.Hint import GHC.Types.SrcLoc as SrcLoc import GHC.Types.Name import GHC.Types.Name.Reader -import GHC.Types.Unique.DFM (udfmToList) import GHC.Unit.Module import GHC.Unit.Module.Imported -import GHC.Unit.Home.ModInfo +import GHC.Utils.Outputable +import GHC.Runtime.Context import GHC.Data.Bag -import GHC.Utils.Outputable (empty) +import Language.Haskell.Syntax.ImpExp -import Data.List (sortBy, partition, nub) +import Data.List (sortBy, partition) import Data.List.NonEmpty ( pattern (:|), NonEmpty ) import Data.Function ( on ) import qualified Data.Semigroup as S @@ -146,10 +147,10 @@ unboundNameOrTermInType if_term_in_type looking_for rdr_name hints ; global_env <- getGlobalRdrEnv ; impInfo <- getImports ; currmod <- getModule - ; hpt <- getHpt + ; ic <- hsc_IC <$> getTopEnv ; let (imp_errs, suggs) = unknownNameSuggestions_ looking_for - dflags hpt currmod global_env local_env impInfo + dflags ic currmod global_env local_env impInfo rdr_name ; addErr $ make_error imp_errs (hints ++ suggs) } @@ -179,17 +180,17 @@ notInScopeErr where_look rdr_name unknownNameSuggestions :: LocalRdrEnv -> WhatLooking -> RdrName -> RnM ([ImportError], [GhcHint]) unknownNameSuggestions lcl_env what_look tried_rdr_name = do { dflags <- getDynFlags - ; hpt <- getHpt ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports ; curr_mod <- getModule + ; interactive_context <- hsc_IC <$> getTopEnv ; return $ unknownNameSuggestions_ (LF what_look WL_Anywhere) - dflags hpt curr_mod rdr_env lcl_env imp_info tried_rdr_name } + dflags interactive_context curr_mod rdr_env lcl_env imp_info tried_rdr_name } -unknownNameSuggestions_ :: LookingFor -> DynFlags - -> HomePackageTable -> Module +unknownNameSuggestions_ :: LookingFor -> DynFlags -> InteractiveContext + -> Module -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails -> RdrName -> ([ImportError], [GhcHint]) unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env @@ -201,7 +202,7 @@ unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env , map (ImportSuggestion $ rdrNameOcc tried_rdr_name) imp_suggs , extensionSuggestions tried_rdr_name , fieldSelectorSuggestions global_env tried_rdr_name ] - (imp_errs, imp_suggs) = importSuggestions looking_for global_env hpt curr_mod imports tried_rdr_name + (imp_errs, imp_suggs) = importSuggestions looking_for hpt curr_mod imports tried_rdr_name if_ne :: (NonEmpty a -> b) -> [a] -> [b] if_ne _ [] = [] @@ -308,15 +309,13 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env -- | Generate errors and helpful suggestions if a qualified name Mod.foo is not in scope. importSuggestions :: LookingFor - -> GlobalRdrEnv - -> HomePackageTable -> Module + -> InteractiveContext -> Module -> ImportAvails -> RdrName -> ([ImportError], [ImportSuggestion]) -importSuggestions looking_for global_env hpt currMod imports rdr_name +importSuggestions looking_for ic currMod imports rdr_name | WL_LocalOnly <- lf_where looking_for = ([], []) | WL_LocalTop <- lf_where looking_for = ([], []) | not (isQual rdr_name || isUnqual rdr_name) = ([], []) - | null interesting_imports - , Just name <- mod_name + | Just name <- mod_name , show_not_imported_line name = ([MissingModule name], []) | is_qualified @@ -344,6 +343,17 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name , Just imp <- return $ pick (importedByUser mod_imports) ] + -- Choose the imports from the interactive context which might have provided + -- a module. + interactive_imports = + filter pick_interactive (ic_imports ic) + + pick_interactive :: InteractiveImport -> Bool + pick_interactive (IIDecl d) | mod_name == Just (unLoc (ideclName d)) = True + | mod_name == fmap unLoc (ideclAs d) = True + pick_interactive (IIModule m) | mod_name == Just m = True + pick_interactive _ = False + -- We want to keep only one for each original module; preferably one with an -- explicit import list (for no particularly good reason) pick :: [ImportedModsVal] -> Maybe ImportedModsVal @@ -369,17 +379,10 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name -- See Note [When to show/hide the module-not-imported line] show_not_imported_line :: ModuleName -> Bool -- #15611 show_not_imported_line modnam - | modnam `elem` glob_mods = False -- #14225 -- 1 - | moduleName currMod == modnam = False -- 2.1 - | is_last_loaded_mod modnam hpt_uniques = False -- 2.2 + | not (null interactive_imports) = False -- 1 (interactive context) + | not (null interesting_imports) = False -- 1 (normal module import) + | moduleName currMod == modnam = False -- 2 | otherwise = True - where - hpt_uniques = map fst (udfmToList hpt) - is_last_loaded_mod modnam uniqs = lastMaybe uniqs == Just (getUnique modnam) - glob_mods = nub [ mod - | gre <- globalRdrEnvElts global_env - , (mod, _) <- qualsInScope gre - ] extensionSuggestions :: RdrName -> [GhcHint] extensionSuggestions rdrName @@ -478,13 +481,8 @@ For the error message: Module X does not export Y No module named ‘X’ is imported: there are 2 cases, where we hide the last "no module is imported" line: -1. If the module X has been imported. -2. If the module X is the current module. There are 2 subcases: - 2.1 If the unknown module name is in a input source file, - then we can use the getModule function to get the current module name. - (See test T15611a) - 2.2 If the unknown module name has been entered by the user in GHCi, - then the getModule function returns something like "interactive:Ghci1", - and we have to check the current module in the last added entry of - the HomePackageTable. (See test T15611b) +1. If the module X has been imported (normally or via interactive context). +2. It is the current module we are trying to compile + then we can use the getModule function to get the current module name. + (See test T15611a) -} ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1759,7 +1759,9 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- - In this function, those TcTyVars are unified with other kind variables during -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) -kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) tycon +kcTyClDecl (DataDecl { tcdLName = (L _ _name) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no -- harm. For GADTs, each data con brings its own tyvars into scope, @@ -1767,7 +1769,7 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (dataDefnConsNewOrData cons) (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1799,67 +1801,70 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM () -kcConArgTys new_or_data res_kind arg_tys = do - { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) +kcConArgTys :: ConArgKind -- Expected kind of the argument(s) + -> [HsScaled GhcRn (LHsType GhcRn)] -- User-written argument types + -> TcM () +kcConArgTys exp_kind arg_tys + = forM_ arg_tys $ \(HsScaled mult ty) -> + do { _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + ; tcMult mult } -- See Note [Implementation of UnliftedNewtypes], STEP 2 - } -- Kind-check the types of arguments to a Haskell98 data constructor. -kcConH98Args :: NewOrData -> TcKind -> HsConDeclH98Details GhcRn -> TcM () -kcConH98Args new_or_data res_kind con_args = case con_args of - PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys - InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] - RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConH98Args :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclH98Details GhcRn + -> TcM () +kcConH98Args exp_kind con_args = case con_args of + PrefixCon _ tys -> kcConArgTys exp_kind tys + InfixCon ty1 ty2 -> kcConArgTys exp_kind [ty1, ty2] + RecCon (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. -kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () -kcConGADTArgs new_or_data res_kind con_args = case con_args of - PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys - RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConGADTArgs :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclGADTDetails GhcRn + -> TcM () +kcConGADTArgs exp_kind con_args = case con_args of + PrefixConGADT _ tys -> kcConArgTys exp_kind tys + RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -kcConDecls :: Foldable f - => NewOrData - -> TcKind -- The result kind signature - -- Used only in H98 case - -> f (LConDecl GhcRn) -- The data constructors - -> TcM () +kcConDecls :: TcKind -- Result kind of tycon + -- Used only in H98 case + -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls new_or_data tc_res_kind = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) +kcConDecls tc_res_kind cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons + where + new_or_data = dataDefnConsNewOrData cons -- Kind check a data constructor. In additional to the data constructor, -- we also need to know about whether or not its corresponding type was -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData - -> TcKind -- Result kind of the type constructor - -- Usually Type but can be TYPE UnliftedRep - -- or even TYPE r, in the case of unlifted newtype - -- Used only in H98 case - -> ConDecl GhcRn - -> TcM () -kcConDecl new_or_data tc_res_kind (ConDeclH98 - { con_name = name, con_ex_tvs = ex_tvs - , con_mb_cxt = ex_ctxt, con_args = args }) +kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data tc_res_kind + (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs + , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (dataConCtxt (NE.singleton name)) $ discardResult $ bindExplicitTKBndrs_Tv ex_tvs $ do { _ <- tcHsContext ex_ctxt - ; kcConH98Args new_or_data tc_res_kind args + ; let arg_exp_kind = getArgExpKind new_or_data tc_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same as the tc_res_kind. See (KCD1) + -- in Note [kcConDecls: kind-checking data type decls] + ; kcConH98Args arg_exp_kind args -- We don't need to check the telescope here, -- because that's done in tcConDecl } -kcConDecl new_or_data - _tc_res_kind -- Not used in GADT case (and doesn't make sense) - (ConDeclGADT - { con_names = names, con_bndrs = L _ outer_bndrs, con_mb_cxt = cxt - , con_g_args = args, con_res_ty = res_ty }) +kcConDecl new_or_data _tc_res_kind + -- NB: _tc_res_kind is unused. See (KCD3) in + -- Note [kcConDecls: kind-checking data type decls] + (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs + , con_mb_cxt = cxt, con_g_args = args, con_res_ty = res_ty }) = -- See Note [kcConDecls: kind-checking data type decls] addErrCtxt (dataConCtxt names) $ discardResult $ @@ -1870,45 +1875,80 @@ kcConDecl new_or_data ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) ; con_res_kind <- newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - ; kcConGADTArgs new_or_data con_res_kind args - ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind) + + ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same the kind of `res_ty`, the data con's return type + -- See (KCD2) in Note [kcConDecls: kind-checking data type decls] + ; kcConGADTArgs arg_exp_kind args + + ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr arg_exp_kind) ; return () } {- Note [kcConDecls: kind-checking data type decls] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kcConDecls is used when we are inferring the kind of the type -constructor in a data type declaration. E.g. - data T f a = MkT (f a) -we want to infer the kind of 'f' and 'a'. The basic plan is described -in Note [Inferring kinds for type declarations]; here we are doing Step 2. - -In the GADT case we may have this: - data T f a where - MkT :: forall g b. g b -> T g b - -Notice that the variables f,a, and g,b are quite distinct. -Nevertheless, the type signature for MkT must still influence the kind -T which is (remember Step 1) something like - T :: kappa1 -> kappa2 -> Type -Otherwise we'd infer the bogus kind - T :: forall k1 k2. k1 -> k2 -> Type. - -The type signature for MkT influences the kind of T simply by -kind-checking the result type (T g b), which will force 'f' and 'g' to -have the same kinds. This is the call to - tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) -Because this is the result type of an arrow, we know the kind must be -of form (TYPE rr), and we get better error messages if we enforce that -here (e.g. test gadt10). - -For unlifted newtypes only, we must ensure that the argument kind -and result kind are the same: -* In the H98 case, we need the result kind of the TyCon, to unify with - the argument kind. - -* In GADT syntax, this unification happens via the result kind passed - to kcConGADTArgs. The tycon's result kind is not used at all in the - GADT case. +constructor in a data type declaration. The basic plan is described in +Note [Inferring kinds for type declarations]; here we are doing Step 2. + +We are kind-checking the data constructors /only/ to compute the kind of +the type construtor. For example + data T f a = MkT (f a) +The (f a) in the data construtor constrains the kinds of `f` and `a`, and hence +of `T`. + +There are two cases to consider in `kcConDecl` + +* Haskell 98 data constructors, as above. We simply bring `f` and `a` + into scope and kind-check the data constructors. + +* GADT data type decls e.g. + data S f a where + MkS :: g b -> S g b + Here `f` and `a` don't scope over the data constructor signatures. + Instead, we just kind-check the entire signature (including the result `S g b`), + relying on the fact that `S` is in scope with its initial kind `k1 -> k2 -> Type`; + doing so will constrain `k1` and `k2` appropriately. + +The arguments of each data constructor are always of kind (TYPE r) for some +r :: RuntimeRep. But in the case of a newytype, the argument kind must be +the same as the tycon result kind. Since we are trying to figure out the +tycon kind, kcConDecls must account for this, which is surprisingly tricky. +Again there are two cases to consider in `kcConDecl`: + +* Haskell 98 data type decls, e.g. + data T f a = MkT (f a) + * In the header, all the tycon binders are specified (here `f` and `a`) + and there is no result kind signature. + * The binders from the header scope over the data construtors. + * In the case of unlifted newtypes, the argument kind affects the tycon kind + newtype N = MkN Int# + Here `getInitialKind` will give `N` the result kind `TYPE r`, where `r` is + a unification variable, and `kcConDecls` should unify that `r` with + `IntRep` becuase of the `Int#` + + Solution (KCD1): just check that the argumet type has the same kind as the result + kind of the tycon. + +* GADT data type decls e.g. + data S f :: Type -> Type where + MkS :: g a -> S g a + * In the header, not all the tycon binders are specified (here just `f`), + and there can be a kind signature + * The kind signature may describe some, all, or none of the tycon binders. + Regardless, in the TcTyCon constructed by `getInitialKind`, the tyConResKind + is the signature, not the "ultimate" result type of the tycon (which is + usually Type) + * In the case of unlifted newtypes, we again want the argument kind to be the + same as the result kind of the tycon; but it's not so clear what /is/ the + result kind of the tycon, because of the signature stuff in the previous bullet. + + Solution (KCD2): kind-check the result type of the data constructor (here + `S g a`) and, for newtypes, ensure that the arugment has that same kind. + + (KCD3) The tycon's result kind `tc_res_kind` is not used at all in the GADT + case; rather it is accessed via looking up S's kind in the type environment + when kind-checking the result type of the data constructor. Note [Using TyVarTvs for kind-checking GADTs] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3866,13 +3906,21 @@ nothing wrong with it). We are implicitly requiring tha tcInferLHsTypeKind doesn't any gratuitous top-level casts. -} + +type ConArgKind = ContextKind + -- The expected kind of the argument(s) of a constructor + -- For data types this is always OpenKind + -- For newtypes it is (TheKind ki) + -- where `ki` is the result kind of the newtype + -- With NoUnliftedNewtype, ki=Type, but with UnliftedNewtypes it can be a variable + -- | Produce an "expected kind" for the arguments of a data/newtype. -- If the declaration is indeed for a newtype, -- then this expected kind will be the kind provided. Otherwise, -- it is OpenKind for datatypes and liftedTypeKind. -- Why do we not check for -XUnliftedNewtypes? See point -- in Note [Implementation of UnliftedNewtypes] -getArgExpKind :: NewOrData -> TcKind -> ContextKind +getArgExpKind :: NewOrData -> TcKind -> ConArgKind getArgExpKind NewType res_ki = TheKind res_ki getArgExpKind DataType _ = OpenKind @@ -3898,7 +3946,7 @@ tcConIsInfixGADT con details ; return (con `elemNameEnv` fix_env) } | otherwise -> return False -tcConH98Args :: ContextKind -- expected kind of arguments +tcConH98Args :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclH98Details GhcRn @@ -3912,7 +3960,7 @@ tcConH98Args exp_kind (InfixCon bty1 bty2) tcConH98Args exp_kind (RecCon fields) = tcRecConDeclFields exp_kind fields -tcConGADTArgs :: ContextKind -- expected kind of arguments +tcConGADTArgs :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclGADTDetails GhcRn @@ -3922,7 +3970,7 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (HsScaled w bty) @@ -3932,7 +3980,7 @@ tcConArg exp_kind (HsScaled w bty) ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, getBangStrictness bty) } -tcRecConDeclFields :: ContextKind +tcRecConDeclFields :: ConArgKind -> LocatedL [LConDeclField GhcRn] -> TcM [(Scaled TcType, HsSrcBang)] tcRecConDeclFields exp_kind fields View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4483a1efb3e98f9cd0bd5a73b2c2c456ebcb684b...11ae78c6aeb54ea574040393e7c6f916df12d849 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4483a1efb3e98f9cd0bd5a73b2c2c456ebcb684b...11ae78c6aeb54ea574040393e7c6f916df12d849 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 15:04:59 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 07 Jan 2025 10:04:59 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25629 Message-ID: <677d429bef5ac_22b50842051899128@gitlab.mail> Ben Gamari pushed new branch wip/T25629 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25629 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 16:27:16 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 07 Jan 2025 11:27:16 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25615 Message-ID: <677d55e485496_3fb34463086c56077@gitlab.mail> Ben Gamari pushed new branch wip/T25615 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25615 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 17:26:02 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 07 Jan 2025 12:26:02 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] more clean up and comments Message-ID: <677d63aab4b31_3fb344d4e04062190@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 7cbac5dd by Rodrigo Mesquita at 2025-01-07T17:25:40+00:00 more clean up and comments - - - - - 4 changed files: - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Unit/Env.hs - compiler/GHC/Unit/Home/Graph.hs - compiler/GHC/Unit/Home/PackageTable.hs Changes: ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -2347,9 +2347,6 @@ getCompleteMatchesTcM localAndImportedCompleteMatches :: CompleteMatches -> UnitEnv -> ExternalPackageState -> IO CompleteMatches localAndImportedCompleteMatches tcg_comps unit_env eps = do - -- ROMES:TODO: this whole could be a single query to the UnitEnv, rather than - -- fetching the HUG and EPS separately. this is the only occurrence of - -- hugcompletesigs/hptcompletesigs... hugCSigs <- hugCompleteSigs unit_env return $ tcg_comps -- from the current module ===================================== compiler/GHC/Unit/Env.hs ===================================== @@ -153,7 +153,7 @@ hugCompleteSigs :: UnitEnv -> IO CompleteMatches hugCompleteSigs = HUG.allCompleteSigs . ue_home_unit_graph -------------------------------------------------------------------------------- --- TODO::.... +-- UnitEnv -------------------------------------------------------------------------------- data UnitEnv = UnitEnv ===================================== compiler/GHC/Unit/Home/Graph.hs ===================================== @@ -100,13 +100,10 @@ allCompleteSigs hug = foldr go (pure []) hug where -- Used in @tcRnImports@, to select the instances that are in the -- transitive closure of imports from the currently compiled module. allInstances :: HomeUnitGraph -> IO (InstEnv, [FamInst]) --- ROMES:TODO: Figure out why the return type of allInstances is this --- "[FamInstance]" rather than the something like "famInstances" allInstances hug = foldr go (pure (emptyInstEnv, [])) hug where go hue = liftA2 (\(a,b) (a',b') -> (a `unionInstEnv` a', b ++ b')) (hptAllInstances (homeUnitEnv_hpt hue)) --- | ROMES:TODO: Write a comment allFamInstances :: HomeUnitGraph -> IO (ModuleEnv FamInstEnv) allFamInstances hug = foldr go (pure emptyModuleEnv) hug where go hue = liftA2 plusModuleEnv (hptAllFamInstances (homeUnitEnv_hpt hue)) @@ -116,7 +113,7 @@ allAnns hug = foldr go (pure emptyAnnEnv) hug where go hue = liftA2 plusAnnEnv (hptAllAnnotations (homeUnitEnv_hpt hue)) -------------------------------------------------------------------------------- --- OK? +-- HomeUnitGraph (HUG) -------------------------------------------------------------------------------- type HomeUnitGraph = UnitEnvGraph HomeUnitEnv @@ -186,6 +183,9 @@ addHomeModInfoToHug hmi hug = hmi_mod = mi_module (hm_iface hmi) hmi_unit = toUnitId (moduleUnit hmi_mod) +-- | Thin each HPT variable to only contain keys from the given dependencies. +-- This is used at the end of upsweep to make sure that only completely successfully loaded +-- modules are visible for subsequent operations. restrictHug :: [(UnitId, [HomeModInfo])] -> HomeUnitGraph -> IO () restrictHug deps hug = unitEnv_foldWithKey (\k uid hue -> restrict_one uid hue >> k) (return ()) hug where @@ -222,7 +222,6 @@ updateUnitFlags uid f = unitEnv_adjust update uid -- | Compute the transitive closure of a unit in the 'HomeUnitGraph'. -- If the argument unit is not present in the graph returns Nothing. transitiveHomeDeps :: UnitId -> HomeUnitGraph -> Maybe [UnitId] --- todo: is it worth it caching this computation further? transitiveHomeDeps uid hug = case lookupHugUnit uid hug of Nothing -> Nothing Just hue -> Just $ ===================================== compiler/GHC/Unit/Home/PackageTable.hs ===================================== @@ -117,14 +117,17 @@ newtype HomePackageTable = HPT { -- ^ Domain = modules in the home unit that have been fully compiled -- "home" unit id cached (implicit) here for convenience. -- - -- This is an IORef because the HPT musn't leak; We want to always augment - -- it, and handle rehydration such that rehydrated modules point to the - -- actual modules rather than to hs-boot files... Previously we did this by - -- tying a knot on the lazy HPT, but this leaked the HPT, ... + -- This is an IORef because we want to avoid leaking HPTs (see the particularly bad #25511). + -- Moreover, the HPT invariant allows mutability in this table without compromising thread safety or soundness. + -- To recall: + -- A query to the HPT should depend only on data relevant to that query, such that + -- there being more or less unrelated entries in the HPT does not influence the result in any way. -- - -- The elements of this table may be updated (e.g. on rehydration). + -- Note that the HPT increases monotonically, except at certain barrier + -- points like when 'restrictHpt' is called. At these barriers, it is safe + -- to temporarily violate the HPT monotonicity. -- - -- ROMES:TODO: Explain!!!!! + -- The elements of this table may be updated (e.g. on rehydration). } -- | Create a new 'HomePackageTable'. @@ -183,6 +186,14 @@ addToHpt HPT{table=hptr} mn hmi = do addHomeModInfosToHpt :: HomePackageTable -> [HomeModInfo] -> IO () addHomeModInfosToHpt hpt = mapM_ (flip addHomeModInfoToHpt hpt) +-- | Thin each HPT variable to only contain keys from the given dependencies. +-- This is used at the end of upsweep to make sure that only completely successfully loaded +-- modules are visible for subsequent operations. +-- +-- This is an exception to the invariant of the HPT -- that it grows +-- monotonically, never removing entries -- which is safe as long as it is only +-- called at barrier points, such as the end of upsweep, when all threads are +-- done and we want to clean up failed entries. restrictHpt :: HomePackageTable -> [HomeModInfo] -> IO () restrictHpt HPT{table=hptr} hmis = let key_set = map (getKey . getUnique . hmi_mod) hmis @@ -203,11 +214,7 @@ addListToHpt hpt = mapM_ (uncurry (addToHpt hpt)) hptCompleteSigs :: HomePackageTable -> IO CompleteMatches hptCompleteSigs = concatHpt (md_complete_matches . hm_details) --- | Find all the instance declarations (of classes and families) from --- the Home Package Table filtered by the provided predicate function. --- Used in @tcRnImports@, to select the instances that are in the --- transitive closure of imports from the currently compiled module. --- ROMES:TODO: wait what? +-- | Find all the instance declarations (of classes and families) from this Home Package Table hptAllInstances :: HomePackageTable -> IO (InstEnv, [FamInst]) hptAllInstances hpt = do hits <- flip concatHpt hpt $ \mod_info -> do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7cbac5dd4212441e68b54e3774843689ece27d64 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7cbac5dd4212441e68b54e3774843689ece27d64 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 17:31:35 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 07 Jan 2025 12:31:35 -0500 Subject: [Git][ghc/ghc][wip/T25452] 191 commits: Add regression test for #16234 Message-ID: <677d64f7b57ef_3fb344104c72462561@gitlab.mail> Ben Gamari pushed to branch wip/T25452 at Glasgow Haskell Compiler / GHC Commits: fa66fa64 by Ryan Scott at 2024-11-14T19:05:00-05:00 Add regression test for #16234 Issue #16234 was likely fixed by !9765. This adds a regression test to ensure that it remains fixed. Fixes #16234. - - - - - bfe64df8 by Matthew Pickering at 2024-11-14T19:05:36-05:00 ghc-internal: Update to Unicode 16 This patch updates the automatically generated code for querying unicode properties to unicode 16. Fixes #25402 - - - - - 1fd83f86 by Ben Gamari at 2024-11-14T19:06:13-05:00 configure: Accept happy-2.1.2 happy-2.1 was released in late Oct 2024. I have confirmed that master bootstraps with it. Here we teach configure to accept this tool. Fixes #25438. - - - - - aa58fc5b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Tighten up invariants of PACK - - - - - 8aa4c10a by Ben Gamari at 2024-11-14T19:06:49-05:00 testsuite: Fix badly escaped literals Use raw string literals to ensure that `\s` is correctly interpreted as a character class. - - - - - 0e084029 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Improve documentation of SLIDE bytecode instruction - - - - - 9bf3663b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Assert that TEST*_P discriminators are valid - - - - - 1f668511 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Improve documentation of TEST*_P instructions - - - - - 59e0a770 by Cheng Shao at 2024-11-14T19:07:25-05:00 misc: improve clangd compile_flags.txt flags This patch improves the compile_flags.txt config used to power clangd for the rts C codebase. The flags in the file are sampled & deduped from a real stage1 build with clang-19 and vastly improves the IDE accuracy when hacking the rts. For maximum code coverage under the default settings, compile_flags.txt defaults to threaded+profiled+dynamic+debug way. This does not mean profdyn needs to be actually built in _build/stage1 for IDE to work. To activate IDE for other RTS ways, simply remove one of the -D flags at the end of compile_flags.txt and restart clangd. - - - - - c2c562e0 by Ben Gamari at 2024-11-14T19:08:01-05:00 testsuite: Don't consider untracked files in dirtiness check Considering trees containing untracked files as dirty is a bridge too far. The chance of an untracked file significantly affecting measured performanced metrics is quite small whereas not collecting measurements is quite inconvenient for some workflows. We now ignore untracked files in the dirtiness check. Fixes #25471. - - - - - ed2ed6c5 by Cheng Shao at 2024-11-14T19:08:37-05:00 testsuite: add regression test T25473 This commit adds regression test T25473 marked as broken due to #25473. It will be fixed in the subsequent commit. - - - - - bd0a8b7e by Cheng Shao at 2024-11-14T19:08:37-05:00 wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. - - - - - f1b0bc32 by Ben Gamari at 2024-11-14T19:09:13-05:00 rts/linker: Make FreeBSD declarations proper prototypes The iconv declarations for FreeBSD were previously not prototypes, leading to warnings. - - - - - 086cbbc1 by Ben Gamari at 2024-11-14T19:09:13-05:00 base: Drop redundant import in FreeBSD ExecutablePath implementation - - - - - 79ecd199 by Ben Gamari at 2024-11-14T19:09:13-05:00 compiler: Fix partial selector warnings in GHC.Runtime.Heap.Inspect - - - - - 1acb73bf by Andrew Lelechenko at 2024-11-15T06:10:47-05:00 gitlab: mention CLC in MR template - - - - - 8f2e0832 by Ben Gamari at 2024-11-15T06:11:24-05:00 rts: Allow use of GNU-stack notes on FreeBSD Previously we gated use of GNU-style non-executable stack notes to only apply on Linux. However, these are also supported by FreeBSD, which also uses ELF. Fix this. Fixes #25475. - - - - - 2c427cb0 by Ben Gamari at 2024-11-16T05:27:40-05:00 rts: Fix EINTR check in timerfd ticker When `poll` failed we previously checked that `errno == -EINTR` to silence the failure warning. However, this is wrong as `errno` values are generally not negated error codes (in contrast to many system call results, which is likely what the original author had in mind). Fixes #25477. - - - - - a0fa4941 by Ben Gamari at 2024-11-16T05:28:16-05:00 rts: Increase gen_workspace alignment to 128 bytes on AArch64 Increase to match the 128-byte cache-line size of Apple's ARMv8 implementation. Closes #25459. - - - - - 142d8afa by Ben Gamari at 2024-11-16T16:20:47-05:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - b7a146e5 by Ben Gamari at 2024-11-16T16:20:47-05:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - ddb7afa6 by Ben Gamari at 2024-11-16T16:21:23-05:00 users guide: Mention language extensions in equality constraints discussion As suggested in #24127, mention the language extensions necessary for usage of equality constriants in their documentation. Closes #24127. - - - - - 36133dac by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/9.14.1-notes: Fix list syntax - - - - - 888de658 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/debug-info: Fix duplicate flag descriptions - - - - - f120e427 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide: Fix reference to 9.14.1 release notes - - - - - 8e975032 by Ben Gamari at 2024-11-16T16:21:59-05:00 Introduce GHC.Tc.Plugin.lookupTHName This makes it significantly more convenient (and less GHC-version-dependent) to resolve a template-haskell name into a GHC Name. As proposed in #24741. - - - - - a0e168ec by ARATA Mizuki at 2024-11-16T16:22:40-05:00 x86 NCG SIMD: Lower packFloatX4#, insertFloatX4# and broadcastFloatX4# to SSE1 instructions Fixes #25441 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 3936bf1b by sheaf at 2024-11-16T16:23:22-05:00 X86 NCG: allow VXOR at scalar floating-point types The NCG can emit VXOR instructions at scalar floating-point types, but the pretty-printer would panic instead of emitting the appropriate VXORPS/VXORPD instructions. This patch rectifies that oversight. Fixes #25455 - - - - - d9dff93a by Ben Gamari at 2024-11-16T16:23:58-05:00 rts: Fix platform-dependent pointer casts Previously we had unnecessary (and incorrect) platform-dependent casts to turn `OSThreadIds`s into a integer. We now just uniformly cast first to a `uintptr_t` (which is always safe, regardless of whether `OSThreadId` is a pointer), and then cast to the desired integral type. This fixes a warning on musl platforms. - - - - - 6d95cdb8 by Ben Gamari at 2024-11-16T16:24:34-05:00 testsuite: Mark encoding004 as broken on FreeBSD Due to #22003, CP936 fails to roundtrip: ```diff == CP936 +Failed to roundtrip given mutant byte at index 891 (251 /= 123 at index 891) +Failed to roundtrip given mutant byte at index 1605 (197 /= 69 at index 1605) +Failed to roundtrip given mutant byte at index 2411 (235 /= 107 at index 2411) +Failed to roundtrip given mutant byte at index 6480 (208 /= 80 at index 6480) +Failed to roundtrip given mutant byte at index 6482 (210 /= 82 at index 6482) +Failed to roundtrip given mutant byte at index 6484 (212 /= 84 at index 6484) +Failed to roundtrip given mutant byte at index 6496 (224 /= 96 at index 6496) +Failed to roundtrip given mutant byte at index 7243 (203 /= 75 at index 7243) +Failed to roundtrip given mutant byte at index 7277 (237 /= 109 at index 7277) +Failed to roundtrip given mutant byte at index 8027 (219 /= 91 at index 8027) +Failed to roundtrip given mutant byte at index 8801 (225 /= 97 at index 8801) ``` - - - - - 26e86984 by Ben Gamari at 2024-11-18T04:05:31-05:00 hadrian: Allow haddock options to be passed via key-value settings - - - - - 6e68b117 by Matthew Pickering at 2024-11-18T04:06:07-05:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - a4e0d235 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 exceptions: Improve the message layout as per #285 This commit fixes the layout of the additional information included when displaying an exception, namely the type of the exception. It also fixes the default handler's heading message to work well together with the improved display message of SomeException. CLC proposal#285 - - - - - 284ffab3 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 Display type and callstack of exception on handler This commit changes the Exception instance of SomeException to *simply* display the underlying exception in `displayException`. The augmented exception message that included the type and backtrace of the exception are now only printed on a call to `displayExceptionWithInfo`. At a surface level, existing programs should behave the same since the `uncaughtExceptionHandler`, which is responsible for printing out uncaught exceptions to the user, will use `displayExceptionWithInfo` by default. However, unlike the instance's `displayException` method, the `uncaughtExceptionHandler` can be overriden with `setUncaughtExceptionHandler`. This makes the extra information opt-in without fixing it the instance, which can be valuable if your program wants to display uncaught exceptions to users in a user-facing way (ie without backtraces). This is what was originally agreed for CLC#231 or CLC#261 with regard to the type of the exception information. The call stack also becoming part of the default handler rather than the Exception instance is an ammendment to CLC#164. Discussion of the ammendment is part of CLC#285. - - - - - 36cddd2c by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Remove redundant CallStack from exceptions Before the exception backtraces proposal was implemented, ErrorCall accumulated its own callstack via HasCallStack constraints, but ExceptionContext is now accumulated automatically. The original ErrorCall mechanism is now redundant and we get a duplicate CallStack Updates Cabal submodule to fix their usage of ErrorCallWithLocation to ErrorCall CLC proposal#285 Fixes #25283 - - - - - 7a74330b by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Freeze call stack in error throwing functions CLC proposal#285 - - - - - 3abf31a4 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 De-duplicate displayContext and displayExceptionContext The former was unused except for one module where it was essentially re-defining displayExceptionContext. Moreover, this commit extends the fix from bfe600f5bb3ecd2c8fa71c536c63d3c46984e3f8 to displayExceptionContext too, which was missing. - - - - - c0d783f8 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Re-export NoBacktrace from Control.Exception This was originally proposed and accepted in section "2.7 Capturing Backtraces on Exceptions" of the CLC proposal for exception backtraces. However, the implementation missed this re-export, which this commit now fixes. - - - - - 802b5c3e by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Fix exception backtraces from GHCi When running the program with `runhaskell`/`runghc` the backtrace should match the backtrace one would get by compiling and running the program. But currently, an exception thrown in a program interpreted with `runhaskell` will: * Not include the original exception backtrace at all * Include the backtrace from the internal GHCi/ghc rethrowing of the original exception This commit fixes this divergence by not annotating the ghc(i) backtrace (with NoBacktrace) and making sure that the backtrace of the original exception is serialized across the boundary and rethrown with the appropriate context. Fixes #25116 The !13301 MR (not this commit in particular) improves performance of MultiLayerModules. Unfortunately, T3294 regresses on aarch64-linux-deb12 by 1% allocations. Since this patch must be merged for 9.12 ASAP, we will not be able to investigate the slight regression on this platform in time. ------------------------- Metric Decrease: MultiLayerModulesRecomp MultiLayerModulesTH_OneShot Metric Increase: T3294 ------------------------- - - - - - 3e89eb65 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 base: Add to changelog.md CLC #285 - - - - - d9326a48 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Bump array and stm submodules for testsuite The testsuites of array and stm had to be updated according to !13301. Updates submodule array and stm. - - - - - 325fcb5d by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Clean up code style of Nativei386 adjustor - - - - - 39bb6e58 by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Fix stack overrun error in Nativei386 adjustor We were reserving the wrong kind of adjustor context (the generic `AdjustorContext` used by other adjustor implementations, rather than the i386-specific `CCallContext`) to return the adjustor context while freeing, resulting in #25485. Fixes #25485. - - - - - 831aab22 by sheaf at 2024-11-18T21:22:36-05:00 Include diagnostic reason in -fdiagnostics-as-json This commit ensures that the -fdiagnostics-as-json output includes the diagnostic reason. This allows the full error message produced by GHC to be re-constructed from the JSON output. Fixes #25403 - - - - - 3e5bfdd3 by Ben Gamari at 2024-11-18T21:23:12-05:00 rts: Introduce printIPE This is a convenience utility for use in GDB. - - - - - 44d909a3 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Don't store boot locations in finder cache Partially reverts commit fff55592a7b Amends add(Home)ModuleToFinder so that locations for boot files are not stored in the finder cache. Removes InstalledModule field from InstalledFound constructor since it's the same as the key that was searched for. - - - - - 64c95292 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Concentrate boot extension logic in Finder With new mkHomeModLocation that takes an extra HscSource to add boot extensions if required. - - - - - 11bad98d by ARATA Mizuki at 2024-11-19T14:39:08-05:00 Better documentation for floating-point min/max and SIMD primitives See #25350 for floating-point min/max Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 791a47b2 by Arnaud Spiwack at 2024-11-20T14:00:05+00:00 Add test for #25185 - - - - - 374e18e5 by Arnaud Spiwack at 2024-11-20T14:09:30+00:00 Quick look: emit the multiplicity of app heads in tcValArgs Otherwise it's not scaled properly by the context, allowing unsound expressions. Fixes #25185. - - - - - 1fc02399 by sheaf at 2024-11-20T18:11:03-05:00 x86 NCG: fix regUsageOfInstr for VMOVU & friends This commit fixes the implementation of 'regUsageOfInstr' for vector operations that take an 'Operand' as the destination, by ensuring that when the destination is an address then the address should be *READ*, and not *WRITTEN*. Getting this wrong is a disaster, as it means the register allocator has incorrect information, which can lead to it discard stores to registers, segfaults ensuing. Fixes #25486 - - - - - 7bd407a6 by Brandon Chinn at 2024-11-21T14:08:15-05:00 Fix CRLF in multiline strings (#25375) - - - - - 7575709b by Rodrigo Mesquita at 2024-11-21T14:08:52-05:00 Improve reachability queries on ModuleGraph Introduces `ReachabilityIndex`, an index constructed from a `GHC.Data.Graph.Directed` `Graph` that supports fast reachability queries (in $O(1)$). This abstract data structure is exposed from `GHC.Data.Graph.Directed.Reachability`. This index is constructed from the module graph nodes and cached in `ModuleGraph`, enabling efficient reachability queries on the module graph. Previously, we'd construct a Map of Set of ModuleGraph nodes which used a lot of memory (`O(n^2)` in the number of nodes) and cache that in the `ModuleGraph`. By using the reachability index we get rid of this space leak in the module graph -- even though the index is still quadratic in the number of modules, it is much, much more space efficient due to its representation using an IntMap of IntSet as opposed to the transitive closure we previously cached. In a memory profile of MultiLayerModules with 100x100 modules, memory usage improved from 6GB residency to 2.8GB, out of which roughly 1.8GB are caused by a second space leak related to ModuleGraph. On the same program, it brings compile time from 7.5s to 5.5s. Note how we simplify `checkHomeUnitsClosed` in terms of `isReachableMany` and by avoiding constructing a second graph with the full transitive closure -- it suffices to answer the reachability query on the full graph without collapsing the transitive closure completely into nodes. Unfortunately, solving this leak means we have to do a little bit more work since we can no longer cache the result of turning vertex indices into nodes. This results in a slight regression in MultiLayerModulesTH_Make, but results in large performance and memory wins when compiling large amounts of modules. ------------------------- Metric Decrease: mhu-perf Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - bcbcdaaf by Cheng Shao at 2024-11-21T14:09:28-05:00 driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code This commit fixes an undefined symbol error in RTS linker when attempting to compile home modules with -fhpc and -fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for detailed description and analysis of the bug. Also adds T25510/T25510c regression tests to test make mode/oneshot mode of the bug. - - - - - 970ada5a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Bump ci-images For introduction of Alpine/i386 image. Thanks to Julian for the base image. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 8115abc2 by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Add release job for i386/Alpine As requested by Mikolaj and started by Julian. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 639f0149 by Ben Gamari at 2024-11-22T23:32:06-05:00 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ - - - - - 490d4d0a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Mark i386 Alpine test breakages Marks the following tests as broken on i386/Alpine: * T22033 due to #25497 * simd009, T25062_V16, T25169, T22187_run due to #25498 - - - - - 536cdf09 by Cheng Shao at 2024-11-22T23:32:42-05:00 compiler: remove unused GHC.Linker.Loader.loadExpr This patch removes the unused `GHC.Linker.Loader.loadExpr` function. It was moved from `GHC.Runtime.Linker.linkExpr` in `ghc-9.0` to `GHC.Linker.Loader.loadExpr` in `ghc-9.2`, and remain completely unused and untested ever since. There's also no third party user of this function to my best knowledge, so let's remove this. Anyone who wants to write their own GHC API function to load bytecode can consult the source code in older release branches. - - - - - 6ee35024 by Drew Fenwick at 2024-11-22T23:33:26-05:00 Fix a non-compiling example in the type abstractions docs This patch adds a missing Show constraint to a code example in the User Guide's type abstractions docs to fix issue #25422. - - - - - d1172e20 by Rodrigo Mesquita at 2024-11-22T23:34:02-05:00 Re-introduce ErrorCallWithLocation with a deprecation pragma With the removal of the duplicate backtrace, part of CLC proposal #285, the constructor `ErrorCallWithLocation` was removed from base. This commit re-introduces it with a deprecation. - - - - - 1187a60a by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Skip tests requiring Hadrian deps in out-of-tree testsuite runs Some testsuite tests require specific tools (e.g. `check-ppr` and `check-exact`) beyond those shipped in the binary distribution. Skip these tests. Fixes #13897. - - - - - c37d7a2e by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Declare exactprint tests' dependency on check-exact - - - - - 454ce957 by Ben Gamari at 2024-11-22T23:35:15-05:00 ghc-internal: Fix a few cases of missing Haddock markup - - - - - a249649b by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/GHCiPrimCall : Add missing Makefile includes - - - - - a021a493 by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/IpeStats: Use Make rather than shell interpolation - - - - - 6e1fbda7 by Ben Gamari at 2024-11-25T03:55:44-05:00 hadrian-ghci-multi: Pass -this-package-name in unit response files As noted in #25509, the `-this-package-name` must be passed for each package to ensure that GHC can response references to the packages' exposed modules via package-qualified imports. Fix this. Closes #25509. - - - - - a05e4a9b by Simon Hengel at 2024-11-25T03:56:33-05:00 Refactoring: Use `OnOff` more consistently for `Extension` - - - - - 7536181d by Matthew Pickering at 2024-11-25T14:00:07-05:00 driver: Always link against "base" package when one shot linking The default value for base-unit-id is stored in the settings file. At install time, this can be set by using the BASE_UNIT_ID environment variable. At runtime, the value can be set by `-base-unit-id` flag. For whether all this is a good idea, see #25382 Fixes #25382 - - - - - 7f90f319 by Andreas Klebinger at 2024-11-25T14:00:44-05:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 - - - - - 291388e1 by Cheng Shao at 2024-11-25T14:01:19-05:00 ci: minor nix-in-docker improvements This patch makes some minor improvements re nix-in-docker logic in the ci configuration: - Update `nixos/nix` to the latest version - Apply $CPUS to `cores`/`max-jobs` to avoid oversubscribing while allowing a reasonable degree of parallelism - Remove redundant `--extra-experimental-features nix-command` in later `nix shell` invocations, it's already configured in `/etc/nix/nix.conf` - - - - - e684c406 by Cheng Shao at 2024-11-25T14:01:57-05:00 ci: avoid depending on stack job for test-bootstrap jobs This patch makes test-bootstrap related ci jobs only depend on hadrian-ghc-in-ghci job to finish, consistent with other jobs in the full-build stage generated by gen_ci.hs. This allows the jobs to be spawned earlier and improve overall pipeline parallelism. - - - - - caaf5388 by Simon Hengel at 2024-11-25T14:02:41-05:00 Refactoring: Remove `pSupportedExts` from `ParserOpts` This is never used for lexing / parsing. It is only used by `GHC.Parser.Header.getOptions`. - - - - - 41f8365c by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Add test for #25515 - - - - - 9279619f by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Desugar record notation with correct multiplicities Simply uses the multiplicity as stored in the field. As I'm writing this commit, the only possible multiplicity is 1, but !13525 is changing this. It's actually easier to take !13525 into account. Fixes #25515. - - - - - fcc3ae6e by Andreas Klebinger at 2024-11-26T08:24:58-05:00 Clarify INLINE unfolding optimization docs. Fixes #24660 - - - - - 88c4fe1d by Cheng Shao at 2024-11-26T08:25:34-05:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. - - - - - 53f978c0 by doyougnu at 2024-11-26T16:07:26-05:00 ghc-experimental: expose GHC.RTS.Flags, GHC.Stats See this CLC proposal: - https://github.com/haskell/core-libraries-committee/issues/289 and this CLC proposal for background: - https://github.com/haskell/core-libraries-committee/issues/288 Metric Decrease: MultiLayerModulesTH_OneShot - - - - - e70d4140 by Wang Xin at 2024-11-26T16:08:10-05:00 Add -mcmodel=medium moduleflag to generated LLVM IR on LoongArch platform With the Medium code model, the jump range of the generated jump instruction is larger than that of the Small code model. It's a temporary fix of the problem descriped in https://gitlab.haskell .org/ghc/ghc/-/issues/25495. This commit requires that the LLVM used contains the code of commit 9dd1d451d9719aa91b3bdd59c0c6679 83e1baf05, i.e., version 8.0 and later. Actually we should not rely on LLVM, so the only way to solve this problem is to implement the LoongArch backend. Add new type for codemodel - - - - - df42ba16 by Andreas Klebinger at 2024-11-27T11:40:49-05:00 Cmm constant folding: Narrow results to operations bitwidth. When constant folding ensure the result is still within bounds for the given type by explicitly narrowing the results. Not doing so results in a lot of spurious assembler warnings especially when testing primops. - - - - - bf3db97e by Ben Gamari at 2024-11-27T11:41:26-05:00 ghc-toolchain: Introduce basic flag validation We verify that required flags (currently `--output` and `--triple`) are provided. The implementation is truly awful, but so is getopt. Begins to address #25500. - - - - - a104508d by Ben Gamari at 2024-11-27T11:42:03-05:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. - - - - - c3fc9b86 by Ben Gamari at 2024-11-27T11:42:39-05:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. - - - - - a362b943 by sheaf at 2024-11-27T23:44:28-05:00 Add checkExact to toolTargets This change means that the Hadrian multi target will include exactprint. In particular, this means that HLS will work on exactprint inside the GHC tree. - - - - - e6c957e4 by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Add test for #25428 - - - - - 52d97f4e by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Don't bypass MonoLocalBind in empty patterns Fixes #25428 - - - - - 7890f2d8 by Ben Gamari at 2024-11-28T10:26:46-05:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. - - - - - 0fd43ea6 by Adam Sandberg Ericsson at 2024-11-28T10:27:22-05:00 mention -Iw in +RTS -? - - - - - 6cf579b9 by Ben Gamari at 2024-11-28T10:27:59-05:00 gitlab-ci: Set GIT_SUBMODULE_FORCE_HTTPS GitLab recommends using `https://` to clone submodules and provides the `GIT_SUBMODULE_FORCE_HTTPS` variable to force this. Fixes #25528. - - - - - 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - 454feb17 by Ben Gamari at 2025-01-07T12:29:28-05:00 base: Label threads forked by IO operations Addresses part of #25452. - - - - - 276f9c15 by Ben Gamari at 2025-01-07T12:29:29-05:00 base: Label threads forked by System.Timeout Addresses part of #25452. - - - - - aca7cffc by Ben Gamari at 2025-01-07T12:29:29-05:00 base: Label signal handling threads Addresses part of #25452. - - - - - 060d756c by Ben Gamari at 2025-01-07T12:29:29-05:00 base: Label Windows console event handling threads Addresses part of #25452. - - - - - 5d31bd86 by Ben Gamari at 2025-01-07T12:29:29-05:00 ghci: Label evaluation sandbox thread Addresses part of #25452. - - - - - 985e73be by Ben Gamari at 2025-01-07T12:31:20-05:00 base: Add changelog entry for addition of thread labels Addresses #25452. - - - - - 25 changed files: - .gitattributes - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/hello.hs - .gitlab/jobs.yaml - .gitlab/merge_request_templates/Default.md - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/upload.sh - .gitmodules - compile_flags.txt - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/Format.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bade7f85e1fcc71c5d8e30ac2d068eeef3bd833e...985e73beb05bf1b22df3f2ed529e8006820e02d5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bade7f85e1fcc71c5d8e30ac2d068eeef3bd833e...985e73beb05bf1b22df3f2ed529e8006820e02d5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 17:49:37 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 07 Jan 2025 12:49:37 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] driver: Store the HomePackageTable in a mutable reference Message-ID: <677d6931d4281_3fb344122b8386317@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 82a818a7 by Rodrigo Mesquita at 2025-01-07T17:28:43+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/82a818a72248753949ec5d099143ebaa459bd291 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/82a818a72248753949ec5d099143ebaa459bd291 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 18:53:37 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 13:53:37 -0500 Subject: [Git][ghc/ghc][master] warnings: Find out if a qualified name is in the interactive scope directly Message-ID: <677d7831d34bf_3fb3441abe0547097d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 1 changed file: - compiler/GHC/Rename/Unbound.hs Changes: ===================================== compiler/GHC/Rename/Unbound.hs ===================================== @@ -34,10 +34,11 @@ import GHC.Prelude import GHC.Driver.DynFlags import GHC.Driver.Ppr +import GHC.Driver.Env.Types import GHC.Tc.Errors.Types import GHC.Tc.Utils.Monad -import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique) +import GHC.Builtin.Names ( mkUnboundName, isUnboundName ) import GHC.Utils.Misc import GHC.Utils.Panic (panic) @@ -53,16 +54,16 @@ import GHC.Types.Hint import GHC.Types.SrcLoc as SrcLoc import GHC.Types.Name import GHC.Types.Name.Reader -import GHC.Types.Unique.DFM (udfmToList) import GHC.Unit.Module import GHC.Unit.Module.Imported -import GHC.Unit.Home.ModInfo +import GHC.Utils.Outputable +import GHC.Runtime.Context import GHC.Data.Bag -import GHC.Utils.Outputable (empty) +import Language.Haskell.Syntax.ImpExp -import Data.List (sortBy, partition, nub) +import Data.List (sortBy, partition) import Data.List.NonEmpty ( pattern (:|), NonEmpty ) import Data.Function ( on ) import qualified Data.Semigroup as S @@ -146,10 +147,10 @@ unboundNameOrTermInType if_term_in_type looking_for rdr_name hints ; global_env <- getGlobalRdrEnv ; impInfo <- getImports ; currmod <- getModule - ; hpt <- getHpt + ; ic <- hsc_IC <$> getTopEnv ; let (imp_errs, suggs) = unknownNameSuggestions_ looking_for - dflags hpt currmod global_env local_env impInfo + dflags ic currmod global_env local_env impInfo rdr_name ; addErr $ make_error imp_errs (hints ++ suggs) } @@ -179,17 +180,17 @@ notInScopeErr where_look rdr_name unknownNameSuggestions :: LocalRdrEnv -> WhatLooking -> RdrName -> RnM ([ImportError], [GhcHint]) unknownNameSuggestions lcl_env what_look tried_rdr_name = do { dflags <- getDynFlags - ; hpt <- getHpt ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports ; curr_mod <- getModule + ; interactive_context <- hsc_IC <$> getTopEnv ; return $ unknownNameSuggestions_ (LF what_look WL_Anywhere) - dflags hpt curr_mod rdr_env lcl_env imp_info tried_rdr_name } + dflags interactive_context curr_mod rdr_env lcl_env imp_info tried_rdr_name } -unknownNameSuggestions_ :: LookingFor -> DynFlags - -> HomePackageTable -> Module +unknownNameSuggestions_ :: LookingFor -> DynFlags -> InteractiveContext + -> Module -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails -> RdrName -> ([ImportError], [GhcHint]) unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env @@ -201,7 +202,7 @@ unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env , map (ImportSuggestion $ rdrNameOcc tried_rdr_name) imp_suggs , extensionSuggestions tried_rdr_name , fieldSelectorSuggestions global_env tried_rdr_name ] - (imp_errs, imp_suggs) = importSuggestions looking_for global_env hpt curr_mod imports tried_rdr_name + (imp_errs, imp_suggs) = importSuggestions looking_for hpt curr_mod imports tried_rdr_name if_ne :: (NonEmpty a -> b) -> [a] -> [b] if_ne _ [] = [] @@ -308,15 +309,13 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env -- | Generate errors and helpful suggestions if a qualified name Mod.foo is not in scope. importSuggestions :: LookingFor - -> GlobalRdrEnv - -> HomePackageTable -> Module + -> InteractiveContext -> Module -> ImportAvails -> RdrName -> ([ImportError], [ImportSuggestion]) -importSuggestions looking_for global_env hpt currMod imports rdr_name +importSuggestions looking_for ic currMod imports rdr_name | WL_LocalOnly <- lf_where looking_for = ([], []) | WL_LocalTop <- lf_where looking_for = ([], []) | not (isQual rdr_name || isUnqual rdr_name) = ([], []) - | null interesting_imports - , Just name <- mod_name + | Just name <- mod_name , show_not_imported_line name = ([MissingModule name], []) | is_qualified @@ -344,6 +343,17 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name , Just imp <- return $ pick (importedByUser mod_imports) ] + -- Choose the imports from the interactive context which might have provided + -- a module. + interactive_imports = + filter pick_interactive (ic_imports ic) + + pick_interactive :: InteractiveImport -> Bool + pick_interactive (IIDecl d) | mod_name == Just (unLoc (ideclName d)) = True + | mod_name == fmap unLoc (ideclAs d) = True + pick_interactive (IIModule m) | mod_name == Just m = True + pick_interactive _ = False + -- We want to keep only one for each original module; preferably one with an -- explicit import list (for no particularly good reason) pick :: [ImportedModsVal] -> Maybe ImportedModsVal @@ -369,17 +379,10 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name -- See Note [When to show/hide the module-not-imported line] show_not_imported_line :: ModuleName -> Bool -- #15611 show_not_imported_line modnam - | modnam `elem` glob_mods = False -- #14225 -- 1 - | moduleName currMod == modnam = False -- 2.1 - | is_last_loaded_mod modnam hpt_uniques = False -- 2.2 + | not (null interactive_imports) = False -- 1 (interactive context) + | not (null interesting_imports) = False -- 1 (normal module import) + | moduleName currMod == modnam = False -- 2 | otherwise = True - where - hpt_uniques = map fst (udfmToList hpt) - is_last_loaded_mod modnam uniqs = lastMaybe uniqs == Just (getUnique modnam) - glob_mods = nub [ mod - | gre <- globalRdrEnvElts global_env - , (mod, _) <- qualsInScope gre - ] extensionSuggestions :: RdrName -> [GhcHint] extensionSuggestions rdrName @@ -478,13 +481,8 @@ For the error message: Module X does not export Y No module named ‘X’ is imported: there are 2 cases, where we hide the last "no module is imported" line: -1. If the module X has been imported. -2. If the module X is the current module. There are 2 subcases: - 2.1 If the unknown module name is in a input source file, - then we can use the getModule function to get the current module name. - (See test T15611a) - 2.2 If the unknown module name has been entered by the user in GHCi, - then the getModule function returns something like "interactive:Ghci1", - and we have to check the current module in the last added entry of - the HomePackageTable. (See test T15611b) +1. If the module X has been imported (normally or via interactive context). +2. It is the current module we are trying to compile + then we can use the getModule function to get the current module name. + (See test T15611a) -} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f56558bea3210c6688c0c4d1e96a94d5ad914918 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f56558bea3210c6688c0c4d1e96a94d5ad914918 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 18:54:20 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 13:54:20 -0500 Subject: [Git][ghc/ghc][master] Tidy up kcConDecls Message-ID: <677d785cc89b3_3fb3441aea424735a9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1759,7 +1759,9 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- - In this function, those TcTyVars are unified with other kind variables during -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) -kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) tycon +kcTyClDecl (DataDecl { tcdLName = (L _ _name) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no -- harm. For GADTs, each data con brings its own tyvars into scope, @@ -1767,7 +1769,7 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (dataDefnConsNewOrData cons) (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1799,67 +1801,70 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM () -kcConArgTys new_or_data res_kind arg_tys = do - { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) +kcConArgTys :: ConArgKind -- Expected kind of the argument(s) + -> [HsScaled GhcRn (LHsType GhcRn)] -- User-written argument types + -> TcM () +kcConArgTys exp_kind arg_tys + = forM_ arg_tys $ \(HsScaled mult ty) -> + do { _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + ; tcMult mult } -- See Note [Implementation of UnliftedNewtypes], STEP 2 - } -- Kind-check the types of arguments to a Haskell98 data constructor. -kcConH98Args :: NewOrData -> TcKind -> HsConDeclH98Details GhcRn -> TcM () -kcConH98Args new_or_data res_kind con_args = case con_args of - PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys - InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] - RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConH98Args :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclH98Details GhcRn + -> TcM () +kcConH98Args exp_kind con_args = case con_args of + PrefixCon _ tys -> kcConArgTys exp_kind tys + InfixCon ty1 ty2 -> kcConArgTys exp_kind [ty1, ty2] + RecCon (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. -kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () -kcConGADTArgs new_or_data res_kind con_args = case con_args of - PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys - RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConGADTArgs :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclGADTDetails GhcRn + -> TcM () +kcConGADTArgs exp_kind con_args = case con_args of + PrefixConGADT _ tys -> kcConArgTys exp_kind tys + RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -kcConDecls :: Foldable f - => NewOrData - -> TcKind -- The result kind signature - -- Used only in H98 case - -> f (LConDecl GhcRn) -- The data constructors - -> TcM () +kcConDecls :: TcKind -- Result kind of tycon + -- Used only in H98 case + -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls new_or_data tc_res_kind = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) +kcConDecls tc_res_kind cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons + where + new_or_data = dataDefnConsNewOrData cons -- Kind check a data constructor. In additional to the data constructor, -- we also need to know about whether or not its corresponding type was -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData - -> TcKind -- Result kind of the type constructor - -- Usually Type but can be TYPE UnliftedRep - -- or even TYPE r, in the case of unlifted newtype - -- Used only in H98 case - -> ConDecl GhcRn - -> TcM () -kcConDecl new_or_data tc_res_kind (ConDeclH98 - { con_name = name, con_ex_tvs = ex_tvs - , con_mb_cxt = ex_ctxt, con_args = args }) +kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data tc_res_kind + (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs + , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (dataConCtxt (NE.singleton name)) $ discardResult $ bindExplicitTKBndrs_Tv ex_tvs $ do { _ <- tcHsContext ex_ctxt - ; kcConH98Args new_or_data tc_res_kind args + ; let arg_exp_kind = getArgExpKind new_or_data tc_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same as the tc_res_kind. See (KCD1) + -- in Note [kcConDecls: kind-checking data type decls] + ; kcConH98Args arg_exp_kind args -- We don't need to check the telescope here, -- because that's done in tcConDecl } -kcConDecl new_or_data - _tc_res_kind -- Not used in GADT case (and doesn't make sense) - (ConDeclGADT - { con_names = names, con_bndrs = L _ outer_bndrs, con_mb_cxt = cxt - , con_g_args = args, con_res_ty = res_ty }) +kcConDecl new_or_data _tc_res_kind + -- NB: _tc_res_kind is unused. See (KCD3) in + -- Note [kcConDecls: kind-checking data type decls] + (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs + , con_mb_cxt = cxt, con_g_args = args, con_res_ty = res_ty }) = -- See Note [kcConDecls: kind-checking data type decls] addErrCtxt (dataConCtxt names) $ discardResult $ @@ -1870,45 +1875,80 @@ kcConDecl new_or_data ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) ; con_res_kind <- newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - ; kcConGADTArgs new_or_data con_res_kind args - ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind) + + ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same the kind of `res_ty`, the data con's return type + -- See (KCD2) in Note [kcConDecls: kind-checking data type decls] + ; kcConGADTArgs arg_exp_kind args + + ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr arg_exp_kind) ; return () } {- Note [kcConDecls: kind-checking data type decls] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kcConDecls is used when we are inferring the kind of the type -constructor in a data type declaration. E.g. - data T f a = MkT (f a) -we want to infer the kind of 'f' and 'a'. The basic plan is described -in Note [Inferring kinds for type declarations]; here we are doing Step 2. - -In the GADT case we may have this: - data T f a where - MkT :: forall g b. g b -> T g b - -Notice that the variables f,a, and g,b are quite distinct. -Nevertheless, the type signature for MkT must still influence the kind -T which is (remember Step 1) something like - T :: kappa1 -> kappa2 -> Type -Otherwise we'd infer the bogus kind - T :: forall k1 k2. k1 -> k2 -> Type. - -The type signature for MkT influences the kind of T simply by -kind-checking the result type (T g b), which will force 'f' and 'g' to -have the same kinds. This is the call to - tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) -Because this is the result type of an arrow, we know the kind must be -of form (TYPE rr), and we get better error messages if we enforce that -here (e.g. test gadt10). - -For unlifted newtypes only, we must ensure that the argument kind -and result kind are the same: -* In the H98 case, we need the result kind of the TyCon, to unify with - the argument kind. - -* In GADT syntax, this unification happens via the result kind passed - to kcConGADTArgs. The tycon's result kind is not used at all in the - GADT case. +constructor in a data type declaration. The basic plan is described in +Note [Inferring kinds for type declarations]; here we are doing Step 2. + +We are kind-checking the data constructors /only/ to compute the kind of +the type construtor. For example + data T f a = MkT (f a) +The (f a) in the data construtor constrains the kinds of `f` and `a`, and hence +of `T`. + +There are two cases to consider in `kcConDecl` + +* Haskell 98 data constructors, as above. We simply bring `f` and `a` + into scope and kind-check the data constructors. + +* GADT data type decls e.g. + data S f a where + MkS :: g b -> S g b + Here `f` and `a` don't scope over the data constructor signatures. + Instead, we just kind-check the entire signature (including the result `S g b`), + relying on the fact that `S` is in scope with its initial kind `k1 -> k2 -> Type`; + doing so will constrain `k1` and `k2` appropriately. + +The arguments of each data constructor are always of kind (TYPE r) for some +r :: RuntimeRep. But in the case of a newytype, the argument kind must be +the same as the tycon result kind. Since we are trying to figure out the +tycon kind, kcConDecls must account for this, which is surprisingly tricky. +Again there are two cases to consider in `kcConDecl`: + +* Haskell 98 data type decls, e.g. + data T f a = MkT (f a) + * In the header, all the tycon binders are specified (here `f` and `a`) + and there is no result kind signature. + * The binders from the header scope over the data construtors. + * In the case of unlifted newtypes, the argument kind affects the tycon kind + newtype N = MkN Int# + Here `getInitialKind` will give `N` the result kind `TYPE r`, where `r` is + a unification variable, and `kcConDecls` should unify that `r` with + `IntRep` becuase of the `Int#` + + Solution (KCD1): just check that the argumet type has the same kind as the result + kind of the tycon. + +* GADT data type decls e.g. + data S f :: Type -> Type where + MkS :: g a -> S g a + * In the header, not all the tycon binders are specified (here just `f`), + and there can be a kind signature + * The kind signature may describe some, all, or none of the tycon binders. + Regardless, in the TcTyCon constructed by `getInitialKind`, the tyConResKind + is the signature, not the "ultimate" result type of the tycon (which is + usually Type) + * In the case of unlifted newtypes, we again want the argument kind to be the + same as the result kind of the tycon; but it's not so clear what /is/ the + result kind of the tycon, because of the signature stuff in the previous bullet. + + Solution (KCD2): kind-check the result type of the data constructor (here + `S g a`) and, for newtypes, ensure that the arugment has that same kind. + + (KCD3) The tycon's result kind `tc_res_kind` is not used at all in the GADT + case; rather it is accessed via looking up S's kind in the type environment + when kind-checking the result type of the data constructor. Note [Using TyVarTvs for kind-checking GADTs] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3866,13 +3906,21 @@ nothing wrong with it). We are implicitly requiring tha tcInferLHsTypeKind doesn't any gratuitous top-level casts. -} + +type ConArgKind = ContextKind + -- The expected kind of the argument(s) of a constructor + -- For data types this is always OpenKind + -- For newtypes it is (TheKind ki) + -- where `ki` is the result kind of the newtype + -- With NoUnliftedNewtype, ki=Type, but with UnliftedNewtypes it can be a variable + -- | Produce an "expected kind" for the arguments of a data/newtype. -- If the declaration is indeed for a newtype, -- then this expected kind will be the kind provided. Otherwise, -- it is OpenKind for datatypes and liftedTypeKind. -- Why do we not check for -XUnliftedNewtypes? See point -- in Note [Implementation of UnliftedNewtypes] -getArgExpKind :: NewOrData -> TcKind -> ContextKind +getArgExpKind :: NewOrData -> TcKind -> ConArgKind getArgExpKind NewType res_ki = TheKind res_ki getArgExpKind DataType _ = OpenKind @@ -3898,7 +3946,7 @@ tcConIsInfixGADT con details ; return (con `elemNameEnv` fix_env) } | otherwise -> return False -tcConH98Args :: ContextKind -- expected kind of arguments +tcConH98Args :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclH98Details GhcRn @@ -3912,7 +3960,7 @@ tcConH98Args exp_kind (InfixCon bty1 bty2) tcConH98Args exp_kind (RecCon fields) = tcRecConDeclFields exp_kind fields -tcConGADTArgs :: ContextKind -- expected kind of arguments +tcConGADTArgs :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclGADTDetails GhcRn @@ -3922,7 +3970,7 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (HsScaled w bty) @@ -3932,7 +3980,7 @@ tcConArg exp_kind (HsScaled w bty) ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, getBangStrictness bty) } -tcRecConDeclFields :: ContextKind +tcRecConDeclFields :: ConArgKind -> LocatedL [LConDeclField GhcRn] -> TcM [(Scaled TcType, HsSrcBang)] tcRecConDeclFields exp_kind fields View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/84155cdb8f75849c124b9e295a49916c0a2f6cdf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/84155cdb8f75849c124b9e295a49916c0a2f6cdf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 19:25:55 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 14:25:55 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: warnings: Find out if a qualified name is in the interactive scope directly Message-ID: <677d7fc3d08d3_2e2f1927af3853643@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - d1feac42 by Bryan Richter at 2025-01-07T14:24:55-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 0451d7e4 by Cheng Shao at 2025-01-07T14:24:55-05:00 xxhash: bump to v0.8.3 - - - - - a0d4dd42 by sheaf at 2025-01-07T14:24:56-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 5 changed files: - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/TyCl.hs - m4/ghc_toolchain.m4 - rts/xxhash.h Changes: ===================================== compiler/GHC/Rename/Unbound.hs ===================================== @@ -34,10 +34,11 @@ import GHC.Prelude import GHC.Driver.DynFlags import GHC.Driver.Ppr +import GHC.Driver.Env.Types import GHC.Tc.Errors.Types import GHC.Tc.Utils.Monad -import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique) +import GHC.Builtin.Names ( mkUnboundName, isUnboundName ) import GHC.Utils.Misc import GHC.Utils.Panic (panic) @@ -53,16 +54,16 @@ import GHC.Types.Hint import GHC.Types.SrcLoc as SrcLoc import GHC.Types.Name import GHC.Types.Name.Reader -import GHC.Types.Unique.DFM (udfmToList) import GHC.Unit.Module import GHC.Unit.Module.Imported -import GHC.Unit.Home.ModInfo +import GHC.Utils.Outputable +import GHC.Runtime.Context import GHC.Data.Bag -import GHC.Utils.Outputable (empty) +import Language.Haskell.Syntax.ImpExp -import Data.List (sortBy, partition, nub) +import Data.List (sortBy, partition) import Data.List.NonEmpty ( pattern (:|), NonEmpty ) import Data.Function ( on ) import qualified Data.Semigroup as S @@ -146,10 +147,10 @@ unboundNameOrTermInType if_term_in_type looking_for rdr_name hints ; global_env <- getGlobalRdrEnv ; impInfo <- getImports ; currmod <- getModule - ; hpt <- getHpt + ; ic <- hsc_IC <$> getTopEnv ; let (imp_errs, suggs) = unknownNameSuggestions_ looking_for - dflags hpt currmod global_env local_env impInfo + dflags ic currmod global_env local_env impInfo rdr_name ; addErr $ make_error imp_errs (hints ++ suggs) } @@ -179,17 +180,17 @@ notInScopeErr where_look rdr_name unknownNameSuggestions :: LocalRdrEnv -> WhatLooking -> RdrName -> RnM ([ImportError], [GhcHint]) unknownNameSuggestions lcl_env what_look tried_rdr_name = do { dflags <- getDynFlags - ; hpt <- getHpt ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports ; curr_mod <- getModule + ; interactive_context <- hsc_IC <$> getTopEnv ; return $ unknownNameSuggestions_ (LF what_look WL_Anywhere) - dflags hpt curr_mod rdr_env lcl_env imp_info tried_rdr_name } + dflags interactive_context curr_mod rdr_env lcl_env imp_info tried_rdr_name } -unknownNameSuggestions_ :: LookingFor -> DynFlags - -> HomePackageTable -> Module +unknownNameSuggestions_ :: LookingFor -> DynFlags -> InteractiveContext + -> Module -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails -> RdrName -> ([ImportError], [GhcHint]) unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env @@ -201,7 +202,7 @@ unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env , map (ImportSuggestion $ rdrNameOcc tried_rdr_name) imp_suggs , extensionSuggestions tried_rdr_name , fieldSelectorSuggestions global_env tried_rdr_name ] - (imp_errs, imp_suggs) = importSuggestions looking_for global_env hpt curr_mod imports tried_rdr_name + (imp_errs, imp_suggs) = importSuggestions looking_for hpt curr_mod imports tried_rdr_name if_ne :: (NonEmpty a -> b) -> [a] -> [b] if_ne _ [] = [] @@ -308,15 +309,13 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env -- | Generate errors and helpful suggestions if a qualified name Mod.foo is not in scope. importSuggestions :: LookingFor - -> GlobalRdrEnv - -> HomePackageTable -> Module + -> InteractiveContext -> Module -> ImportAvails -> RdrName -> ([ImportError], [ImportSuggestion]) -importSuggestions looking_for global_env hpt currMod imports rdr_name +importSuggestions looking_for ic currMod imports rdr_name | WL_LocalOnly <- lf_where looking_for = ([], []) | WL_LocalTop <- lf_where looking_for = ([], []) | not (isQual rdr_name || isUnqual rdr_name) = ([], []) - | null interesting_imports - , Just name <- mod_name + | Just name <- mod_name , show_not_imported_line name = ([MissingModule name], []) | is_qualified @@ -344,6 +343,17 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name , Just imp <- return $ pick (importedByUser mod_imports) ] + -- Choose the imports from the interactive context which might have provided + -- a module. + interactive_imports = + filter pick_interactive (ic_imports ic) + + pick_interactive :: InteractiveImport -> Bool + pick_interactive (IIDecl d) | mod_name == Just (unLoc (ideclName d)) = True + | mod_name == fmap unLoc (ideclAs d) = True + pick_interactive (IIModule m) | mod_name == Just m = True + pick_interactive _ = False + -- We want to keep only one for each original module; preferably one with an -- explicit import list (for no particularly good reason) pick :: [ImportedModsVal] -> Maybe ImportedModsVal @@ -369,17 +379,10 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name -- See Note [When to show/hide the module-not-imported line] show_not_imported_line :: ModuleName -> Bool -- #15611 show_not_imported_line modnam - | modnam `elem` glob_mods = False -- #14225 -- 1 - | moduleName currMod == modnam = False -- 2.1 - | is_last_loaded_mod modnam hpt_uniques = False -- 2.2 + | not (null interactive_imports) = False -- 1 (interactive context) + | not (null interesting_imports) = False -- 1 (normal module import) + | moduleName currMod == modnam = False -- 2 | otherwise = True - where - hpt_uniques = map fst (udfmToList hpt) - is_last_loaded_mod modnam uniqs = lastMaybe uniqs == Just (getUnique modnam) - glob_mods = nub [ mod - | gre <- globalRdrEnvElts global_env - , (mod, _) <- qualsInScope gre - ] extensionSuggestions :: RdrName -> [GhcHint] extensionSuggestions rdrName @@ -478,13 +481,8 @@ For the error message: Module X does not export Y No module named ‘X’ is imported: there are 2 cases, where we hide the last "no module is imported" line: -1. If the module X has been imported. -2. If the module X is the current module. There are 2 subcases: - 2.1 If the unknown module name is in a input source file, - then we can use the getModule function to get the current module name. - (See test T15611a) - 2.2 If the unknown module name has been entered by the user in GHCi, - then the getModule function returns something like "interactive:Ghci1", - and we have to check the current module in the last added entry of - the HomePackageTable. (See test T15611b) +1. If the module X has been imported (normally or via interactive context). +2. It is the current module we are trying to compile + then we can use the getModule function to get the current module name. + (See test T15611a) -} ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -1432,7 +1432,7 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1 }) ; wanted <- TcS.zonkSimples simples1 -- Plugin requires zonked inputs ; traceTcS "Running plugins (" (vcat [ text "Given:" <+> ppr given - , text "Watned:" <+> ppr wanted ]) + , text "Wanted:" <+> ppr wanted ]) ; p <- runTcPluginSolvers solvers (given, bagToList wanted) ; let (_, solved_wanted) = pluginSolvedCts p (_, unsolved_wanted) = pluginInputCts p ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1759,7 +1759,9 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- - In this function, those TcTyVars are unified with other kind variables during -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) -kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) tycon +kcTyClDecl (DataDecl { tcdLName = (L _ _name) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no -- harm. For GADTs, each data con brings its own tyvars into scope, @@ -1767,7 +1769,7 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (dataDefnConsNewOrData cons) (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1799,67 +1801,70 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM () -kcConArgTys new_or_data res_kind arg_tys = do - { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) +kcConArgTys :: ConArgKind -- Expected kind of the argument(s) + -> [HsScaled GhcRn (LHsType GhcRn)] -- User-written argument types + -> TcM () +kcConArgTys exp_kind arg_tys + = forM_ arg_tys $ \(HsScaled mult ty) -> + do { _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + ; tcMult mult } -- See Note [Implementation of UnliftedNewtypes], STEP 2 - } -- Kind-check the types of arguments to a Haskell98 data constructor. -kcConH98Args :: NewOrData -> TcKind -> HsConDeclH98Details GhcRn -> TcM () -kcConH98Args new_or_data res_kind con_args = case con_args of - PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys - InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] - RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConH98Args :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclH98Details GhcRn + -> TcM () +kcConH98Args exp_kind con_args = case con_args of + PrefixCon _ tys -> kcConArgTys exp_kind tys + InfixCon ty1 ty2 -> kcConArgTys exp_kind [ty1, ty2] + RecCon (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. -kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () -kcConGADTArgs new_or_data res_kind con_args = case con_args of - PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys - RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConGADTArgs :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclGADTDetails GhcRn + -> TcM () +kcConGADTArgs exp_kind con_args = case con_args of + PrefixConGADT _ tys -> kcConArgTys exp_kind tys + RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -kcConDecls :: Foldable f - => NewOrData - -> TcKind -- The result kind signature - -- Used only in H98 case - -> f (LConDecl GhcRn) -- The data constructors - -> TcM () +kcConDecls :: TcKind -- Result kind of tycon + -- Used only in H98 case + -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls new_or_data tc_res_kind = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) +kcConDecls tc_res_kind cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons + where + new_or_data = dataDefnConsNewOrData cons -- Kind check a data constructor. In additional to the data constructor, -- we also need to know about whether or not its corresponding type was -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData - -> TcKind -- Result kind of the type constructor - -- Usually Type but can be TYPE UnliftedRep - -- or even TYPE r, in the case of unlifted newtype - -- Used only in H98 case - -> ConDecl GhcRn - -> TcM () -kcConDecl new_or_data tc_res_kind (ConDeclH98 - { con_name = name, con_ex_tvs = ex_tvs - , con_mb_cxt = ex_ctxt, con_args = args }) +kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data tc_res_kind + (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs + , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (dataConCtxt (NE.singleton name)) $ discardResult $ bindExplicitTKBndrs_Tv ex_tvs $ do { _ <- tcHsContext ex_ctxt - ; kcConH98Args new_or_data tc_res_kind args + ; let arg_exp_kind = getArgExpKind new_or_data tc_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same as the tc_res_kind. See (KCD1) + -- in Note [kcConDecls: kind-checking data type decls] + ; kcConH98Args arg_exp_kind args -- We don't need to check the telescope here, -- because that's done in tcConDecl } -kcConDecl new_or_data - _tc_res_kind -- Not used in GADT case (and doesn't make sense) - (ConDeclGADT - { con_names = names, con_bndrs = L _ outer_bndrs, con_mb_cxt = cxt - , con_g_args = args, con_res_ty = res_ty }) +kcConDecl new_or_data _tc_res_kind + -- NB: _tc_res_kind is unused. See (KCD3) in + -- Note [kcConDecls: kind-checking data type decls] + (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs + , con_mb_cxt = cxt, con_g_args = args, con_res_ty = res_ty }) = -- See Note [kcConDecls: kind-checking data type decls] addErrCtxt (dataConCtxt names) $ discardResult $ @@ -1870,45 +1875,80 @@ kcConDecl new_or_data ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) ; con_res_kind <- newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - ; kcConGADTArgs new_or_data con_res_kind args - ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind) + + ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same the kind of `res_ty`, the data con's return type + -- See (KCD2) in Note [kcConDecls: kind-checking data type decls] + ; kcConGADTArgs arg_exp_kind args + + ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr arg_exp_kind) ; return () } {- Note [kcConDecls: kind-checking data type decls] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kcConDecls is used when we are inferring the kind of the type -constructor in a data type declaration. E.g. - data T f a = MkT (f a) -we want to infer the kind of 'f' and 'a'. The basic plan is described -in Note [Inferring kinds for type declarations]; here we are doing Step 2. - -In the GADT case we may have this: - data T f a where - MkT :: forall g b. g b -> T g b - -Notice that the variables f,a, and g,b are quite distinct. -Nevertheless, the type signature for MkT must still influence the kind -T which is (remember Step 1) something like - T :: kappa1 -> kappa2 -> Type -Otherwise we'd infer the bogus kind - T :: forall k1 k2. k1 -> k2 -> Type. - -The type signature for MkT influences the kind of T simply by -kind-checking the result type (T g b), which will force 'f' and 'g' to -have the same kinds. This is the call to - tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) -Because this is the result type of an arrow, we know the kind must be -of form (TYPE rr), and we get better error messages if we enforce that -here (e.g. test gadt10). - -For unlifted newtypes only, we must ensure that the argument kind -and result kind are the same: -* In the H98 case, we need the result kind of the TyCon, to unify with - the argument kind. - -* In GADT syntax, this unification happens via the result kind passed - to kcConGADTArgs. The tycon's result kind is not used at all in the - GADT case. +constructor in a data type declaration. The basic plan is described in +Note [Inferring kinds for type declarations]; here we are doing Step 2. + +We are kind-checking the data constructors /only/ to compute the kind of +the type construtor. For example + data T f a = MkT (f a) +The (f a) in the data construtor constrains the kinds of `f` and `a`, and hence +of `T`. + +There are two cases to consider in `kcConDecl` + +* Haskell 98 data constructors, as above. We simply bring `f` and `a` + into scope and kind-check the data constructors. + +* GADT data type decls e.g. + data S f a where + MkS :: g b -> S g b + Here `f` and `a` don't scope over the data constructor signatures. + Instead, we just kind-check the entire signature (including the result `S g b`), + relying on the fact that `S` is in scope with its initial kind `k1 -> k2 -> Type`; + doing so will constrain `k1` and `k2` appropriately. + +The arguments of each data constructor are always of kind (TYPE r) for some +r :: RuntimeRep. But in the case of a newytype, the argument kind must be +the same as the tycon result kind. Since we are trying to figure out the +tycon kind, kcConDecls must account for this, which is surprisingly tricky. +Again there are two cases to consider in `kcConDecl`: + +* Haskell 98 data type decls, e.g. + data T f a = MkT (f a) + * In the header, all the tycon binders are specified (here `f` and `a`) + and there is no result kind signature. + * The binders from the header scope over the data construtors. + * In the case of unlifted newtypes, the argument kind affects the tycon kind + newtype N = MkN Int# + Here `getInitialKind` will give `N` the result kind `TYPE r`, where `r` is + a unification variable, and `kcConDecls` should unify that `r` with + `IntRep` becuase of the `Int#` + + Solution (KCD1): just check that the argumet type has the same kind as the result + kind of the tycon. + +* GADT data type decls e.g. + data S f :: Type -> Type where + MkS :: g a -> S g a + * In the header, not all the tycon binders are specified (here just `f`), + and there can be a kind signature + * The kind signature may describe some, all, or none of the tycon binders. + Regardless, in the TcTyCon constructed by `getInitialKind`, the tyConResKind + is the signature, not the "ultimate" result type of the tycon (which is + usually Type) + * In the case of unlifted newtypes, we again want the argument kind to be the + same as the result kind of the tycon; but it's not so clear what /is/ the + result kind of the tycon, because of the signature stuff in the previous bullet. + + Solution (KCD2): kind-check the result type of the data constructor (here + `S g a`) and, for newtypes, ensure that the arugment has that same kind. + + (KCD3) The tycon's result kind `tc_res_kind` is not used at all in the GADT + case; rather it is accessed via looking up S's kind in the type environment + when kind-checking the result type of the data constructor. Note [Using TyVarTvs for kind-checking GADTs] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3866,13 +3906,21 @@ nothing wrong with it). We are implicitly requiring tha tcInferLHsTypeKind doesn't any gratuitous top-level casts. -} + +type ConArgKind = ContextKind + -- The expected kind of the argument(s) of a constructor + -- For data types this is always OpenKind + -- For newtypes it is (TheKind ki) + -- where `ki` is the result kind of the newtype + -- With NoUnliftedNewtype, ki=Type, but with UnliftedNewtypes it can be a variable + -- | Produce an "expected kind" for the arguments of a data/newtype. -- If the declaration is indeed for a newtype, -- then this expected kind will be the kind provided. Otherwise, -- it is OpenKind for datatypes and liftedTypeKind. -- Why do we not check for -XUnliftedNewtypes? See point -- in Note [Implementation of UnliftedNewtypes] -getArgExpKind :: NewOrData -> TcKind -> ContextKind +getArgExpKind :: NewOrData -> TcKind -> ConArgKind getArgExpKind NewType res_ki = TheKind res_ki getArgExpKind DataType _ = OpenKind @@ -3898,7 +3946,7 @@ tcConIsInfixGADT con details ; return (con `elemNameEnv` fix_env) } | otherwise -> return False -tcConH98Args :: ContextKind -- expected kind of arguments +tcConH98Args :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclH98Details GhcRn @@ -3912,7 +3960,7 @@ tcConH98Args exp_kind (InfixCon bty1 bty2) tcConH98Args exp_kind (RecCon fields) = tcRecConDeclFields exp_kind fields -tcConGADTArgs :: ContextKind -- expected kind of arguments +tcConGADTArgs :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclGADTDetails GhcRn @@ -3922,7 +3970,7 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (HsScaled w bty) @@ -3932,7 +3980,7 @@ tcConArg exp_kind (HsScaled w bty) ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, getBangStrictness bty) } -tcRecConDeclFields :: ContextKind +tcRecConDeclFields :: ConArgKind -> LocatedL [LConDeclField GhcRn] -> TcM [(Scaled TcType, HsSrcBang)] tcRecConDeclFields exp_kind fields ===================================== m4/ghc_toolchain.m4 ===================================== @@ -187,6 +187,7 @@ AC_DEFUN([VALIDATE_GHC_TOOLCHAIN],[ "$GHC_TOOLCHAIN_BIN" format --input="$1" --output="$o1" "$GHC_TOOLCHAIN_BIN" format --input="$2" --output="$o2" diff_output=`diff "$o1" "$o2" 2>&1` + rm -f "$o1" "$o2" if test -z "$diff_output"; then true else ===================================== rts/xxhash.h ===================================== @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (C) 2012-2021 Yann Collet + * Copyright (C) 2012-2023 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -130,6 +130,7 @@ * } * @endcode * + * * @anchor streaming_example * **Streaming** * @@ -165,6 +166,77 @@ * } * @endcode * + * Streaming functions generate the xxHash value from an incremental input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + * + * + * @anchor canonical_representation_example + * **Canonical Representation** + * + * The default return values from XXH functions are unsigned 32, 64 and 128 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + * + * XXH32_canonicalFromHash(), XXH32_hashFromCanonical(), + * XXH64_canonicalFromHash(), XXH64_hashFromCanonical(), + * XXH128_canonicalFromHash(), XXH128_hashFromCanonical(), + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which prints XXH32_hash_t in human readable format + * void printXxh32(XXH32_hash_t hash) + * { + * XXH32_canonical_t cano; + * XXH32_canonicalFromHash(&cano, hash); + * size_t i; + * for(i = 0; i < sizeof(cano.digest); ++i) { + * printf("%02x", cano.digest[i]); + * } + * printf("\n"); + * } + * + * // Example for a function which converts XXH32_canonical_t to XXH32_hash_t + * XXH32_hash_t convertCanonicalToXxh32(XXH32_canonical_t cano) + * { + * XXH32_hash_t hash = XXH32_hashFromCanonical(&cano); + * return hash; + * } + * @endcode + * + * * @file xxhash.h * xxHash prototypes and implementation */ @@ -261,7 +333,7 @@ extern "C" { /* make all functions private */ # undef XXH_PUBLIC_API # if defined(__GNUC__) -# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# define XXH_PUBLIC_API static __inline __attribute__((__unused__)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # define XXH_PUBLIC_API static inline # elif defined(_MSC_VER) @@ -373,7 +445,7 @@ extern "C" { /*! @brief Marks a global symbol. */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -449,7 +521,7 @@ extern "C" { /* specific declaration modes for Windows */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -461,9 +533,9 @@ extern "C" { #endif #if defined (__GNUC__) -# define XXH_CONSTF __attribute__((const)) -# define XXH_PUREF __attribute__((pure)) -# define XXH_MALLOCF __attribute__((malloc)) +# define XXH_CONSTF __attribute__((__const__)) +# define XXH_PUREF __attribute__((__pure__)) +# define XXH_MALLOCF __attribute__((__malloc__)) #else # define XXH_CONSTF /* disable */ # define XXH_PUREF @@ -475,7 +547,7 @@ extern "C" { ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 8 -#define XXH_VERSION_RELEASE 2 +#define XXH_VERSION_RELEASE 3 /*! @brief Version number, encoded as two digits each */ #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) @@ -517,7 +589,11 @@ typedef uint32_t XXH32_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint32_t XXH32_hash_t; #else @@ -551,10 +627,6 @@ typedef uint32_t XXH32_hash_t; /*! * @brief Calculates the 32-bit hash of @p input using xxHash32. * - * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s - * - * See @ref single_shot_example "Single Shot Example" for an example. - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 32-bit seed to alter the hash's output predictably. @@ -564,63 +636,44 @@ typedef uint32_t XXH32_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 32-bit hash value. + * @return The calculated 32-bit xxHash32 value. * - * @see - * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); #ifndef XXH_NO_STREAM -/*! - * Streaming functions generate the xxHash value from an incremental input. - * This method is slower than single-call functions, due to state management. - * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. - * - * An XXH state must first be allocated using `XXH*_createState()`. - * - * Start a new hash by initializing the state with a seed using `XXH*_reset()`. - * - * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. - * - * The function returns an error code, with 0 meaning OK, and any other value - * meaning there is an error. - * - * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. - * This function returns the nn-bits hash as an int or long long. - * - * It's still possible to continue inserting input into the hash state after a - * digest, and generate new hash values later on by invoking `XXH*_digest()`. - * - * When done, release the state using `XXH*_freeState()`. - * - * @see streaming_example at the top of @ref xxhash.h for an example. - */ - /*! * @typedef struct XXH32_state_s XXH32_state_t * @brief The opaque state struct for the XXH32 streaming API. * * @see XXH32_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH32_state_s XXH32_state_t; /*! * @brief Allocates an @ref XXH32_state_t. * - * Must be freed with XXH32_freeState(). - * @return An allocated XXH32_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH32_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH32_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void); /*! * @brief Frees an @ref XXH32_state_t. * - * Must be allocated with XXH32_createState(). * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH32_createState(). + * + * @see @ref streaming_example "Streaming Example" + * */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); /*! @@ -636,23 +689,24 @@ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_ /*! * @brief Resets an @ref XXH32_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH32_update(). - * * @param statePtr The state struct to reset. * @param seed The 32-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH32_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH32_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -664,48 +718,36 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH32_state_t. * - * @note - * Calling XXH32_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash32 value from that state. + * @return The calculated 32-bit xxHash32 value from that state. + * + * @note + * Calling XXH32_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/* - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * This the simplest and fastest format for further post-processing. - * - * However, this leaves open the question of what is the order on the byte level, - * since little and big endian conventions will store the same number differently. - * - * The canonical representation settles this issue by mandating big-endian - * convention, the same convention as human-readable numbers (large digits first). - * - * When writing hash values to storage, sending them over a network, or printing - * them, it's highly recommended to use the canonical representation to ensure - * portability across a wider range of systems, present and future. - * - * The following functions allow transformation of hash values to and from - * canonical format. - */ - /*! * @brief Canonical (big endian) representation of @ref XXH32_hash_t. */ @@ -716,11 +758,13 @@ typedef struct { /*! * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t. * - * @param dst The @ref XXH32_canonical_t pointer to be stored to. + * @param dst The @ref XXH32_canonical_t pointer to be stored to. * @param hash The @ref XXH32_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); @@ -733,6 +777,8 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); @@ -794,7 +840,7 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni * As of writing this, only supported by clang. */ #if XXH_HAS_ATTRIBUTE(noescape) -# define XXH_NOESCAPE __attribute__((noescape)) +# define XXH_NOESCAPE __attribute__((__noescape__)) #else # define XXH_NOESCAPE #endif @@ -821,7 +867,11 @@ typedef uint64_t XXH64_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint64_t XXH64_hash_t; #else # include @@ -851,9 +901,6 @@ typedef uint64_t XXH64_hash_t; /*! * @brief Calculates the 64-bit hash of @p input using xxHash64. * - * This function usually runs faster on 64-bit systems, but slower on 32-bit - * systems (see benchmark). - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 64-bit seed to alter the hash's output predictably. @@ -863,13 +910,9 @@ typedef uint64_t XXH64_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 64-bit hash. + * @return The calculated 64-bit xxHash64 value. * - * @see - * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -879,23 +922,32 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size * @brief The opaque state struct for the XXH64 streaming API. * * @see XXH64_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ /*! * @brief Allocates an @ref XXH64_state_t. * - * Must be freed with XXH64_freeState(). - * @return An allocated XXH64_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH64_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH64_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void); /*! * @brief Frees an @ref XXH64_state_t. * - * Must be allocated with XXH64_createState(). * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH64_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); @@ -912,23 +964,24 @@ XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const /*! * @brief Resets an @ref XXH64_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH64_update(). - * * @param statePtr The state struct to reset. * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH64_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH64_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -940,23 +993,30 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH64_state_t. * - * @note - * Calling XXH64_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash64 value from that state. + * @return The calculated 64-bit xxHash64 value from that state. + * + * @note + * Calling XXH64_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -975,6 +1035,8 @@ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash); @@ -987,6 +1049,8 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src); @@ -1046,40 +1110,74 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const * * The API supports one-shot hashing, streaming mode, and custom secrets. */ + +/*! + * @ingroup tuning + * @brief Possible values for @ref XXH_VECTOR. + * + * Unless set explicitly, determined automatically. + */ +# define XXH_SCALAR 0 /*!< Portable scalar version */ +# define XXH_SSE2 1 /*!< SSE2 for Pentium 4, Opteron, all x86_64. */ +# define XXH_AVX2 2 /*!< AVX2 for Haswell and Bulldozer */ +# define XXH_AVX512 3 /*!< AVX512 for Skylake and Icelake */ +# define XXH_NEON 4 /*!< NEON for most ARMv7-A, all AArch64, and WASM SIMD128 */ +# define XXH_VSX 5 /*!< VSX and ZVector for POWER8/z13 (64-bit) */ +# define XXH_SVE 6 /*!< SVE for some ARMv8-A and ARMv9-A */ +# define XXH_LSX 7 /*!< LSX (128-bit SIMD) for LoongArch64 */ + + /*-********************************************************************** * XXH3 64-bit variant ************************************************************************/ /*! - * @brief 64-bit unseeded variant of XXH3. + * @brief Calculates 64-bit unseeded variant of XXH3 hash of @p input. * - * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however - * it may have slightly better performance due to constant propagation of the - * defaults. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. * - * @see - * XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms * @see * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants - * @see - * XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length); /*! - * @brief 64-bit seeded variant of XXH3 + * @brief Calculates 64-bit seeded variant of XXH3 hash of @p input. * - * This variant generates a custom secret on the fly based on default secret - * altered using the `seed` value. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. * - * While this operation is decently fast, note that it's not completely free. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. * * @note * seed == 0 produces the same results as @ref XXH3_64bits(). * - * @param input The data to hash - * @param length The length - * @param seed The 64-bit seed to alter the state. + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -1093,22 +1191,36 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const vo #define XXH3_SECRET_SIZE_MIN 136 /*! - * @brief 64-bit variant of XXH3 with a custom "secret". + * @brief Calculates 64-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. * * It's possible to provide any blob of bytes as a "secret" to generate the hash. * This makes it more difficult for an external actor to prepare an intentional collision. - * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). * However, the quality of the secret impacts the dispersion of the hash algorithm. * Therefore, the secret _must_ look like a bunch of random bytes. * Avoid "trivial" or structured data such as repeated sequences or a text document. * Whenever in doubt about the "randomness" of the blob of bytes, - * consider employing "XXH3_generateSecret()" instead (see below). + * consider employing @ref XXH3_generateSecret() instead (see below). * It will generate a proper high entropy secret derived from the blob of bytes. * Another advantage of using XXH3_generateSecret() is that * it guarantees that all bits within the initial blob of bytes * will impact every bit of the output. * This is not necessarily the case when using the blob of bytes directly * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); @@ -1123,9 +1235,10 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const */ /*! - * @brief The state struct for the XXH3 streaming API. + * @brief The opaque state struct for the XXH3 streaming API. * * @see XXH3_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH3_state_s XXH3_state_t; XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void); @@ -1144,15 +1257,20 @@ XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOE /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); @@ -1160,36 +1278,54 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* stateP /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits_withSeed()`. - * * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); /*! - * XXH3_64bits_reset_withSecret(): - * `secret` is referenced, it _must outlive_ the hash streaming session. - * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * `secret` is referenced, it _must outlive_ the hash streaming session. + * + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, * and the quality of produced hash values depends on secret's entropy * (secret's content should look like a bunch of random bytes). * When in doubt about the randomness of a candidate `secret`, * consider employing `XXH3_generateSecret()` instead (see below). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! * @brief Consumes a block of @p input to an @ref XXH3_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -1201,23 +1337,30 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_stat * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 64-bit hash value from that state. + * + * @note + * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1242,26 +1385,71 @@ typedef struct { } XXH128_hash_t; /*! - * @brief Unseeded 128-bit variant of XXH3 + * @brief Calculates 128-bit unseeded variant of XXH3 of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. * * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead * for shorter inputs. * - * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0, however + * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of `0`, however * it may have slightly better performance due to constant propagation of the * defaults. * - * @see - * XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms - * @see - * XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants - * @see - * XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version. + * @see XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len); -/*! @brief Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */ +/*! @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see XXH3_128bits(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */ +/*! + * @brief Calculates 128-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing @ref XXH3_generateSecret() instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ @@ -1281,36 +1469,65 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE cons /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits()`. * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits_withSeed()`. + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. * - * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). * + * @see @ref streaming_example "Streaming Example" */ -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH_64bits_reset_withSecret(). */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! @@ -1324,28 +1541,32 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_sta * * @pre * @p statePtr must not be `NULL`. - * @pre + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note * The memory between @p input and @p input + @p length must be valid, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 128-bit hash value from that state. + * + * @note + * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1355,18 +1576,27 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const X * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ /*! - * XXH128_isEqual(): - * Return: 1 if `h1` and `h2` are equal, 0 if they are not. + * @brief Check equality of two XXH128_hash_t values + * + * @param h1 The 128-bit hash value. + * @param h2 Another 128-bit hash value. + * + * @return `1` if `h1` and `h2` are equal. + * @return `0` if they are not. */ XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); /*! * @brief Compares two @ref XXH128_hash_t + * * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. * - * @return: >0 if *h128_1 > *h128_2 - * =0 if *h128_1 == *h128_2 - * <0 if *h128_1 < *h128_2 + * @param h128_1 Left-hand side value + * @param h128_2 Right-hand side value + * + * @return >0 if @p h128_1 > @p h128_2 + * @return =0 if @p h128_1 == @p h128_2 + * @return <0 if @p h128_1 < @p h128_2 */ XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2); @@ -1378,11 +1608,12 @@ typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical /*! * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t. * - * @param dst The @ref XXH128_canonical_t pointer to be stored to. + * @param dst The @ref XXH128_canonical_t pointer to be stored to. * @param hash The @ref XXH128_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash); @@ -1395,6 +1626,7 @@ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* ds * @p src must not be `NULL`. * * @return The converted hash. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src); @@ -1440,9 +1672,9 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE con struct XXH32_state_s { XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */ XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */ - XXH32_hash_t v[4]; /*!< Accumulator lanes */ - XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */ + XXH32_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[16]; /*!< Internal buffer for partial reads. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */ }; /* typedef'd to XXH32_state_t */ @@ -1463,9 +1695,9 @@ struct XXH32_state_s { */ struct XXH64_state_s { XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */ - XXH64_hash_t v[4]; /*!< Accumulator lanes */ - XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */ + XXH64_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[32]; /*!< Internal buffer for partial reads.. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/ XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ }; /* typedef'd to XXH64_state_t */ @@ -1473,8 +1705,7 @@ struct XXH64_state_s { #ifndef XXH_NO_XXH3 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ -# include -# define XXH_ALIGN(n) alignas(n) +# define XXH_ALIGN(n) _Alignas(n) #elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */ /* In C++ alignas() is a keyword */ # define XXH_ALIGN(n) alignas(n) @@ -1587,7 +1818,20 @@ struct XXH3_state_s { /*! - * simple alias to pre-selected XXH3_128bits variant + * @brief Calculates the 128-bit hash of @p data using XXH3. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p len is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 128-bit XXH3 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); @@ -1596,9 +1840,16 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, siz /* Symbols defined below must be considered tied to a specific library version. */ /*! - * XXH3_generateSecret(): + * @brief Derive a high-entropy secret from any user-defined content, named customSeed. + * + * @param secretBuffer A writable buffer for derived high-entropy secret data. + * @param secretSize Size of secretBuffer, in bytes. Must be >= XXH3_SECRET_SIZE_MIN. + * @param customSeed A user-defined content. + * @param customSeedSize Size of customSeed, in bytes. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. * - * Derive a high-entropy secret from any user-defined content, named customSeed. * The generated secret can be used in combination with `*_withSecret()` functions. * The `_withSecret()` variants are useful to provide a higher level of protection * than 64-bit seed, as it becomes much more difficult for an external actor to @@ -1651,6 +1902,9 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer /*! * @brief Generate the same secret as the _withSeed() variants. * + * @param secretBuffer A writable buffer of @ref XXH3_SECRET_DEFAULT_SIZE bytes + * @param seed The 64-bit seed to alter the hash result predictably. + * * The generated secret can be used in combination with *`*_withSecret()` and `_withSecretandSeed()` variants. * @@ -1670,7 +1924,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * }; * // Fast, caches the seeded secret for future uses. * class HashFast { - * unsigned char secret[XXH3_SECRET_SIZE_MIN]; + * unsigned char secret[XXH3_SECRET_DEFAULT_SIZE]; * public: * HashFast(XXH64_hash_t s) { * XXH3_generateSecret_fromSeed(secret, seed); @@ -1682,15 +1936,26 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * } * }; * @endcode - * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes - * @param seed The seed to seed the state. */ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed); /*! - * These variants generate hash values using either - * @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) - * or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX). + * @brief Maximum size of "short" key in bytes. + */ +#define XXH3_MIDSIZE_MAX 240 + +/*! + * @brief Calculates 64/128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * These variants generate hash values using either: + * - @p seed for "short" keys (< @ref XXH3_MIDSIZE_MAX = 240 bytes) + * - @p secret for "large" keys (>= @ref XXH3_MIDSIZE_MAX). * * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. * `_withSeed()` has to generate the secret on the fly for "large" keys. @@ -1717,22 +1982,71 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The memory segment to be hashed, at least @p len bytes in size. + * @param length The length of @p data, in bytes. + * @param secret The secret used to alter hash result predictably. + * @param secretSize The length of @p secret, in bytes (must be >= XXH3_SECRET_SIZE_MIN) + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(): contract is the same. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #ifndef XXH_NO_STREAM -/*! @copydoc XXH3_64bits_withSecretandSeed() */ +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + * + * Note: there was a bug in an earlier version of this function (<= v0.8.2) + * that would make it generate an incorrect hash value + * when @p seed == 0 and @p length < XXH3_MIDSIZE_MAX + * and @p secret is different from XXH3_generateSecret_fromSeed(). + * As stated in the contract, the correct hash result must be + * the same as XXH3_128bits_withSeed() when @p length <= XXH3_MIDSIZE_MAX. + * Results generated by this older version are wrong, hence not comparable. + */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #endif /* !XXH_NO_STREAM */ #endif /* !XXH_NO_XXH3 */ @@ -2100,15 +2414,15 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if XXH_NO_INLINE_HINTS /* disable inlining hints */ # if defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __attribute__((unused)) +# define XXH_FORCE_INLINE static __attribute__((__unused__)) # else # define XXH_FORCE_INLINE static # endif # define XXH_NO_INLINE static /* enable inlining hints */ #elif defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) -# define XXH_NO_INLINE static __attribute__((noinline)) +# define XXH_FORCE_INLINE static __inline__ __attribute__((__always_inline__, __unused__)) +# define XXH_NO_INLINE static __attribute__((__noinline__)) #elif defined(_MSC_VER) /* Visual Studio */ # define XXH_FORCE_INLINE static __forceinline # define XXH_NO_INLINE static __declspec(noinline) @@ -2121,12 +2435,34 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) # define XXH_NO_INLINE static #endif +#if defined(XXH_INLINE_ALL) +# define XXH_STATIC XXH_FORCE_INLINE +#else +# define XXH_STATIC static +#endif + #if XXH3_INLINE_SECRET # define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE #else # define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE #endif +#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ +# define XXH_RESTRICT /* disable */ +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined (__clang__)) \ + || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ + || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) +/* + * There are a LOT more compilers that recognize __restrict but this + * covers the major ones. + */ +# define XXH_RESTRICT __restrict +#else +# define XXH_RESTRICT /* disable */ +#endif /* ************************************* * Debug @@ -2206,10 +2542,14 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t xxh_u8; +# ifdef _AIX +# include +# else +# include +# endif + typedef uint8_t xxh_u8; #else - typedef unsigned char xxh_u8; + typedef unsigned char xxh_u8; #endif typedef XXH32_hash_t xxh_u32; @@ -2295,11 +2635,11 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; +typedef union { xxh_u32 u32; } __attribute__((__packed__)) unalign; #endif static xxh_u32 XXH_read32(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u32 xxh_unalign32; + typedef __attribute__((__aligned__(1))) xxh_u32 xxh_unalign32; return *((const xxh_unalign32*)ptr); } @@ -2445,6 +2785,9 @@ static int XXH_isLittleEndian(void) && XXH_HAS_BUILTIN(__builtin_rotateleft64) # define XXH_rotl32 __builtin_rotateleft32 # define XXH_rotl64 __builtin_rotateleft64 +#elif XXH_HAS_BUILTIN(__builtin_stdc_rotate_left) +# define XXH_rotl32 __builtin_stdc_rotate_left +# define XXH_rotl64 __builtin_stdc_rotate_left /* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ #elif defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) @@ -2590,7 +2933,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) #if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) /* * UGLY HACK: - * A compiler fence is the only thing that prevents GCC and Clang from + * A compiler fence is used to prevent GCC and Clang from * autovectorizing the XXH32 loop (pragmas and attributes don't work for some * reason) without globally disabling SSE4.1. * @@ -2651,6 +2994,61 @@ static xxh_u32 XXH32_avalanche(xxh_u32 hash) #define XXH_get32bits(p) XXH_readLE32_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH32(). + */ +XXH_FORCE_INLINE void +XXH32_initAccs(xxh_u32 *acc, xxh_u32 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + acc[1] = seed + XXH_PRIME32_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME32_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH32(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH32_consumeLong( + xxh_u32 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 15; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 16); + do { + acc[0] = XXH32_round(acc[0], XXH_get32bits(input)); input += 4; + acc[1] = XXH32_round(acc[1], XXH_get32bits(input)); input += 4; + acc[2] = XXH32_round(acc[2], XXH_get32bits(input)); input += 4; + acc[3] = XXH32_round(acc[3], XXH_get32bits(input)); input += 4; + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH32() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u32 +XXH32_mergeAccs(const xxh_u32 *acc) +{ + XXH_ASSERT(acc != NULL); + return XXH_rotl32(acc[0], 1) + XXH_rotl32(acc[1], 7) + + XXH_rotl32(acc[2], 12) + XXH_rotl32(acc[3], 18); +} + /*! * @internal * @brief Processes the last 0-15 bytes of @p ptr. @@ -2763,22 +3161,12 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment if (input==NULL) XXH_ASSERT(len == 0); if (len>=16) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 15; - xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - xxh_u32 v2 = seed + XXH_PRIME32_2; - xxh_u32 v3 = seed + 0; - xxh_u32 v4 = seed - XXH_PRIME32_1; + xxh_u32 acc[4]; + XXH32_initAccs(acc, seed); - do { - v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; - v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; - v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; - v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; - } while (input < limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) - + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + input = XXH32_consumeLong(acc, input, len, align); + + h32 = XXH32_mergeAccs(acc); } else { h32 = seed + XXH_PRIME32_5; } @@ -2834,10 +3222,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s { XXH_ASSERT(statePtr != NULL); memset(statePtr, 0, sizeof(*statePtr)); - statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - statePtr->v[1] = seed + XXH_PRIME32_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME32_1; + XXH32_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -2851,45 +3236,37 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len) return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len_32 += (XXH32_hash_t)len; + state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); - state->total_len_32 += (XXH32_hash_t)len; - state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); + XXH_ASSERT(state->bufferedSize < sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); - state->memsize += (XXH32_hash_t)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const xxh_u32* p32 = state->mem32; - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32)); - } - p += 16-state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer: complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* then process one round */ + (void)XXH32_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p <= bEnd-16) { - const xxh_u8* const limit = bEnd - 16; - - do { - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH32_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -2903,36 +3280,20 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) xxh_u32 h32; if (state->large_len) { - h32 = XXH_rotl32(state->v[0], 1) - + XXH_rotl32(state->v[1], 7) - + XXH_rotl32(state->v[2], 12) - + XXH_rotl32(state->v[3], 18); + h32 = XXH32_mergeAccs(state->acc); } else { - h32 = state->v[2] /* == seed */ + XXH_PRIME32_5; + h32 = state->acc[2] /* == seed */ + XXH_PRIME32_5; } h32 += state->total_len_32; - return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); + return XXH32_finalize(h32, state->buffer, state->bufferedSize, XXH_aligned); } #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/*! - * @ingroup XXH32_family - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * - * The canonical representation uses big endian convention, the same convention - * as human-readable numbers (large digits first). - * - * This way, hash values can be written into a file or buffer, remaining - * comparable across different systems. - * - * The following functions allow transformation of hash values to and from their - * canonical format. - */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); @@ -2987,11 +3348,11 @@ static xxh_u64 XXH_read64(const void* memPtr) * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; +typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((__packed__)) unalign64; #endif static xxh_u64 XXH_read64(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u64 xxh_unalign64; + typedef __attribute__((__aligned__(1))) xxh_u64 xxh_unalign64; return *((const xxh_unalign64*)ptr); } @@ -3110,6 +3471,23 @@ static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) acc += input * XXH_PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= XXH_PRIME64_1; +#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * DISABLE AUTOVECTORIZATION: + * A compiler fence is used to prevent GCC and Clang from + * autovectorizing the XXH64 loop (pragmas and attributes don't work for some + * reason) without globally disabling AVX512. + * + * Autovectorization of XXH64 tends to be detrimental, + * though the exact outcome may change depending on exact cpu and compiler version. + * For information, it has been reported as detrimental for Skylake-X, + * but possibly beneficial for Zen4. + * + * The default is to disable auto-vectorization, + * but you can select to enable it instead using `XXH_ENABLE_AUTOVECTORIZE` build variable. + */ + XXH_COMPILER_GUARD(acc); +#endif return acc; } @@ -3135,6 +3513,85 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) #define XXH_get64bits(p) XXH_readLE64_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH64(). + */ +XXH_FORCE_INLINE void +XXH64_initAccs(xxh_u64 *acc, xxh_u64 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + acc[1] = seed + XXH_PRIME64_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME64_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH64(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH64_consumeLong( + xxh_u64 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 31; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 32); + do { + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + acc[i] = XXH64_round(acc[i], XXH_get64bits(input)); + input += 8; + } + } else { + acc[0] = XXH64_round(acc[0], XXH_get64bits(input)); input += 8; + acc[1] = XXH64_round(acc[1], XXH_get64bits(input)); input += 8; + acc[2] = XXH64_round(acc[2], XXH_get64bits(input)); input += 8; + acc[3] = XXH64_round(acc[3], XXH_get64bits(input)); input += 8; + } + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH64() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u64 +XXH64_mergeAccs(const xxh_u64 *acc) +{ + XXH_ASSERT(acc != NULL); + { + xxh_u64 h64 = XXH_rotl64(acc[0], 1) + XXH_rotl64(acc[1], 7) + + XXH_rotl64(acc[2], 12) + XXH_rotl64(acc[3], 18); + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + h64 = XXH64_mergeRound(h64, acc[i]); + } + } else { + h64 = XXH64_mergeRound(h64, acc[0]); + h64 = XXH64_mergeRound(h64, acc[1]); + h64 = XXH64_mergeRound(h64, acc[2]); + h64 = XXH64_mergeRound(h64, acc[3]); + } + return h64; + } +} + /*! * @internal * @brief Processes the last 0-31 bytes of @p ptr. @@ -3150,7 +3607,7 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) * @return The finalized hash * @see XXH32_finalize(). */ -static XXH_PUREF xxh_u64 +XXH_STATIC XXH_PUREF xxh_u64 XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { if (ptr==NULL) XXH_ASSERT(len == 0); @@ -3200,27 +3657,13 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment xxh_u64 h64; if (input==NULL) XXH_ASSERT(len == 0); - if (len>=32) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 31; - xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - xxh_u64 v2 = seed + XXH_PRIME64_2; - xxh_u64 v3 = seed + 0; - xxh_u64 v4 = seed - XXH_PRIME64_1; + if (len>=32) { /* Process a large block of data */ + xxh_u64 acc[4]; + XXH64_initAccs(acc, seed); - do { - v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; - v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; - v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; - v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; - } while (inputv[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - statePtr->v[1] = seed + XXH_PRIME64_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME64_1; + XXH64_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -3292,42 +3732,36 @@ XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len += len; - state->total_len += len; + XXH_ASSERT(state->bufferedSize <= sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 32) { /* fill in tmp buffer */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); - state->memsize += (xxh_u32)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0)); - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1)); - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2)); - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3)); - p += 32 - state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer => complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* and process one round */ + (void)XXH64_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p+32 <= bEnd) { - const xxh_u8* const limit = bEnd - 32; - - do { - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8; - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8; - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8; - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH64_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -3341,18 +3775,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state xxh_u64 h64; if (state->total_len >= 32) { - h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18); - h64 = XXH64_mergeRound(h64, state->v[0]); - h64 = XXH64_mergeRound(h64, state->v[1]); - h64 = XXH64_mergeRound(h64, state->v[2]); - h64 = XXH64_mergeRound(h64, state->v[3]); + h64 = XXH64_mergeAccs(state->acc); } else { - h64 = state->v[2] /*seed*/ + XXH_PRIME64_5; + h64 = state->acc[2] /*seed*/ + XXH_PRIME64_5; } h64 += (xxh_u64) state->total_len; - return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); + return XXH64_finalize(h64, state->buffer, (size_t)state->total_len, XXH_aligned); } #endif /* !XXH_NO_STREAM */ @@ -3387,22 +3817,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can /* === Compiler specifics === */ -#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ -# define XXH_RESTRICT /* disable */ -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ -# define XXH_RESTRICT restrict -#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ - || (defined (__clang__)) \ - || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ - || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) -/* - * There are a LOT more compilers that recognize __restrict but this - * covers the major ones. - */ -# define XXH_RESTRICT __restrict -#else -# define XXH_RESTRICT /* disable */ -#endif #if (defined(__GNUC__) && (__GNUC__ >= 3)) \ || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ @@ -3416,7 +3830,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can #ifndef XXH_HAS_INCLUDE # ifdef __has_include -# define XXH_HAS_INCLUDE(x) __has_include(x) +/* + * Not defined as XXH_HAS_INCLUDE(x) (function-like) because + * this causes segfaults in Apple Clang 4.2 (on Mac OS X 10.7 Lion) + */ +# define XXH_HAS_INCLUDE __has_include # else # define XXH_HAS_INCLUDE(x) 0 # endif @@ -3437,6 +3855,8 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can # include # elif defined(__SSE2__) # include +# elif defined(__loongarch_sx) +# include # endif #endif @@ -3533,33 +3953,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can * implementation. */ # define XXH_VECTOR XXH_SCALAR -/*! - * @ingroup tuning - * @brief Possible values for @ref XXH_VECTOR. - * - * Note that these are actually implemented as macros. - * - * If this is not defined, it is detected automatically. - * internal macro XXH_X86DISPATCH overrides this. - */ -enum XXH_VECTOR_TYPE /* fake enum */ { - XXH_SCALAR = 0, /*!< Portable scalar version */ - XXH_SSE2 = 1, /*!< - * SSE2 for Pentium 4, Opteron, all x86_64. - * - * @note SSE2 is also guaranteed on Windows 10, macOS, and - * Android x86. - */ - XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ - XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ - XXH_NEON = 4, /*!< - * NEON for most ARMv7-A, all AArch64, and WASM SIMD128 - * via the SIMDeverywhere polyfill provided with the - * Emscripten SDK. - */ - XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ - XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */ -}; /*! * @ingroup tuning * @brief Selects the minimum alignment for XXH3's accumulators. @@ -3574,13 +3967,6 @@ enum XXH_VECTOR_TYPE /* fake enum */ { /* Actual definition */ #ifndef XXH_DOXYGEN -# define XXH_SCALAR 0 -# define XXH_SSE2 1 -# define XXH_AVX2 2 -# define XXH_AVX512 3 -# define XXH_NEON 4 -# define XXH_VSX 5 -# define XXH_SVE 6 #endif #ifndef XXH_VECTOR /* can be defined on command line */ @@ -3605,6 +3991,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { || (defined(__s390x__) && defined(__VEC__)) \ && defined(__GNUC__) /* TODO: IBM XL */ # define XXH_VECTOR XXH_VSX +# elif defined(__loongarch_sx) +# define XXH_VECTOR XXH_LSX # else # define XXH_VECTOR XXH_SCALAR # endif @@ -3642,6 +4030,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_ACC_ALIGN 64 # elif XXH_VECTOR == XXH_SVE /* sve */ # define XXH_ACC_ALIGN 64 +# elif XXH_VECTOR == XXH_LSX /* lsx */ +# define XXH_ACC_ALIGN 64 # endif #endif @@ -3655,7 +4045,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ { #endif #if defined(__GNUC__) || defined(__clang__) -# define XXH_ALIASING __attribute__((may_alias)) +# define XXH_ALIASING __attribute__((__may_alias__)) #else # define XXH_ALIASING /* nothing */ #endif @@ -4408,8 +4798,6 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, } } -#define XXH3_MIDSIZE_MAX 240 - XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -5281,6 +5669,71 @@ XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc, #endif +#if (XXH_VECTOR == XXH_LSX) +#define _LSX_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_lsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i *) acc; + const __m128i* const xinput = (const __m128i *) input; + const __m128i* const xsecret = (const __m128i *) secret; + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = __lsx_vld(xinput + i, 0); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + // __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = __lsx_vmulwev_d_wu(data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = __lsx_vshuf4i_w(data_vec, _LSX_SHUFFLE(1, 0, 3, 2)); + __m128i const sum = __lsx_vadd_d(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = __lsx_vadd_d(product, sum); + } + } +} +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lsx) + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_lsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i*) acc; + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = __lsx_vreplgr2vr_w((int)XXH_PRIME32_1); + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = __lsx_vsrli_d(acc_vec, 47); + __m128i const data_vec = __lsx_vxor_v(acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = __lsx_vsrli_d(data_key, 32); + __m128i const prod_lo = __lsx_vmulwev_d_wu(data_key, prime32); + __m128i const prod_hi = __lsx_vmulwev_d_wu(data_key_hi, prime32); + xacc[i] = __lsx_vadd_d(prod_lo, __lsx_vslli_d(prod_hi, 32)); + } + } +} + +#endif + /* scalar variants - universal */ #if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) @@ -5511,6 +5964,12 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#elif (XXH_VECTOR == XXH_LSX) +#define XXH3_accumulate_512 XXH3_accumulate_512_lsx +#define XXH3_accumulate XXH3_accumulate_lsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_lsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + #else /* scalar */ #define XXH3_accumulate_512 XXH3_accumulate_512_scalar @@ -5566,7 +6025,7 @@ XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret acc[1] ^ XXH_readLE64(secret+8) ); } -static XXH64_hash_t +static XXH_PUREF XXH64_hash_t XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) { xxh_u64 result64 = start; @@ -5593,6 +6052,15 @@ XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secre return XXH3_avalanche(result64); } +/* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + +static XXH_PUREF XXH64_hash_t +XXH3_finalizeLong_64b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 len) +{ + return XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, len * XXH_PRIME64_1); +} + #define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } @@ -5608,10 +6076,8 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); - /* do not align on 8, so that the secret is different from the accumulator */ -#define XXH_SECRET_MERGEACCS_START 11 XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, (const xxh_u8*)secret, (xxh_u64)len); } /* @@ -5747,7 +6213,7 @@ XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH /* === XXH3 streaming === */ #ifndef XXH_NO_STREAM /* - * Malloc's a pointer that is always aligned to align. + * Malloc's a pointer that is always aligned to @align. * * This must be freed with `XXH_alignedFree()`. * @@ -5815,8 +6281,12 @@ static void XXH_alignedFree(void* p) /*! * @brief Allocate an @ref XXH3_state_t. * - * Must be freed with XXH3_freeState(). - * @return An allocated XXH3_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH3_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH3_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) { @@ -5830,9 +6300,13 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) /*! * @brief Frees an @ref XXH3_state_t. * - * Must be allocated with XXH3_createState(). * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note Must be allocated with XXH3_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) { @@ -6111,9 +6585,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* if (state->totalLen > XXH3_MIDSIZE_MAX) { XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); - return XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, secret, (xxh_u64)state->totalLen); } /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ if (state->useSeed) @@ -6405,6 +6877,17 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, } } +static XXH_PUREF XXH128_hash_t +XXH3_finalizeLong_128b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, xxh_u64 len) +{ + XXH128_hash_t h128; + h128.low64 = XXH3_finalizeLong_64b(acc, secret, len); + h128.high64 = XXH3_mergeAccs(acc, secret + secretSize + - XXH_STRIPE_LEN - XXH_SECRET_MERGEACCS_START, + ~(len * XXH_PRIME64_2)); + return h128; +} + XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -6418,16 +6901,7 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)len * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + secretSize - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)len * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, secretSize, (xxh_u64)len); } /* @@ -6610,19 +7084,10 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_ XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + state->secretLimit + XXH_STRIPE_LEN - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, state->secretLimit + XXH_STRIPE_LEN, (xxh_u64)state->totalLen); } /* len <= XXH3_MIDSIZE_MAX : short code */ - if (state->seed) + if (state->useSeed) return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/11ae78c6aeb54ea574040393e7c6f916df12d849...a0d4dd425246cb967a7ce00b45da91995313e3f2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/11ae78c6aeb54ea574040393e7c6f916df12d849...a0d4dd425246cb967a7ce00b45da91995313e3f2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 20:05:36 2025 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Tue, 07 Jan 2025 15:05:36 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/int-index/modifiers-syntax Message-ID: <677d8910c6900_22791e2d981c47e@gitlab.mail> Vladislav Zavialov pushed new branch wip/int-index/modifiers-syntax at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/int-index/modifiers-syntax You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 23:16:02 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 18:16:02 -0500 Subject: [Git][ghc/ghc][master] Remove tmp files after toolchain check Message-ID: <677db5b27cb5b_2d2d8bbd3709684a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 1 changed file: - m4/ghc_toolchain.m4 Changes: ===================================== m4/ghc_toolchain.m4 ===================================== @@ -187,6 +187,7 @@ AC_DEFUN([VALIDATE_GHC_TOOLCHAIN],[ "$GHC_TOOLCHAIN_BIN" format --input="$1" --output="$o1" "$GHC_TOOLCHAIN_BIN" format --input="$2" --output="$o2" diff_output=`diff "$o1" "$o2" 2>&1` + rm -f "$o1" "$o2" if test -z "$diff_output"; then true else View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c12b6cf4e16b8af0db5a1cdea95d2ec4f54ea14 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6c12b6cf4e16b8af0db5a1cdea95d2ec4f54ea14 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 23:17:09 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 18:17:09 -0500 Subject: [Git][ghc/ghc][master] xxhash: bump to v0.8.3 Message-ID: <677db5f546d79_2d2d8bbd2f89941a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 1 changed file: - rts/xxhash.h Changes: ===================================== rts/xxhash.h ===================================== @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (C) 2012-2021 Yann Collet + * Copyright (C) 2012-2023 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -130,6 +130,7 @@ * } * @endcode * + * * @anchor streaming_example * **Streaming** * @@ -165,6 +166,77 @@ * } * @endcode * + * Streaming functions generate the xxHash value from an incremental input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + * + * + * @anchor canonical_representation_example + * **Canonical Representation** + * + * The default return values from XXH functions are unsigned 32, 64 and 128 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + * + * XXH32_canonicalFromHash(), XXH32_hashFromCanonical(), + * XXH64_canonicalFromHash(), XXH64_hashFromCanonical(), + * XXH128_canonicalFromHash(), XXH128_hashFromCanonical(), + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which prints XXH32_hash_t in human readable format + * void printXxh32(XXH32_hash_t hash) + * { + * XXH32_canonical_t cano; + * XXH32_canonicalFromHash(&cano, hash); + * size_t i; + * for(i = 0; i < sizeof(cano.digest); ++i) { + * printf("%02x", cano.digest[i]); + * } + * printf("\n"); + * } + * + * // Example for a function which converts XXH32_canonical_t to XXH32_hash_t + * XXH32_hash_t convertCanonicalToXxh32(XXH32_canonical_t cano) + * { + * XXH32_hash_t hash = XXH32_hashFromCanonical(&cano); + * return hash; + * } + * @endcode + * + * * @file xxhash.h * xxHash prototypes and implementation */ @@ -261,7 +333,7 @@ extern "C" { /* make all functions private */ # undef XXH_PUBLIC_API # if defined(__GNUC__) -# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# define XXH_PUBLIC_API static __inline __attribute__((__unused__)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # define XXH_PUBLIC_API static inline # elif defined(_MSC_VER) @@ -373,7 +445,7 @@ extern "C" { /*! @brief Marks a global symbol. */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -449,7 +521,7 @@ extern "C" { /* specific declaration modes for Windows */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -461,9 +533,9 @@ extern "C" { #endif #if defined (__GNUC__) -# define XXH_CONSTF __attribute__((const)) -# define XXH_PUREF __attribute__((pure)) -# define XXH_MALLOCF __attribute__((malloc)) +# define XXH_CONSTF __attribute__((__const__)) +# define XXH_PUREF __attribute__((__pure__)) +# define XXH_MALLOCF __attribute__((__malloc__)) #else # define XXH_CONSTF /* disable */ # define XXH_PUREF @@ -475,7 +547,7 @@ extern "C" { ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 8 -#define XXH_VERSION_RELEASE 2 +#define XXH_VERSION_RELEASE 3 /*! @brief Version number, encoded as two digits each */ #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) @@ -517,7 +589,11 @@ typedef uint32_t XXH32_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint32_t XXH32_hash_t; #else @@ -551,10 +627,6 @@ typedef uint32_t XXH32_hash_t; /*! * @brief Calculates the 32-bit hash of @p input using xxHash32. * - * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s - * - * See @ref single_shot_example "Single Shot Example" for an example. - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 32-bit seed to alter the hash's output predictably. @@ -564,63 +636,44 @@ typedef uint32_t XXH32_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 32-bit hash value. + * @return The calculated 32-bit xxHash32 value. * - * @see - * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); #ifndef XXH_NO_STREAM -/*! - * Streaming functions generate the xxHash value from an incremental input. - * This method is slower than single-call functions, due to state management. - * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. - * - * An XXH state must first be allocated using `XXH*_createState()`. - * - * Start a new hash by initializing the state with a seed using `XXH*_reset()`. - * - * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. - * - * The function returns an error code, with 0 meaning OK, and any other value - * meaning there is an error. - * - * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. - * This function returns the nn-bits hash as an int or long long. - * - * It's still possible to continue inserting input into the hash state after a - * digest, and generate new hash values later on by invoking `XXH*_digest()`. - * - * When done, release the state using `XXH*_freeState()`. - * - * @see streaming_example at the top of @ref xxhash.h for an example. - */ - /*! * @typedef struct XXH32_state_s XXH32_state_t * @brief The opaque state struct for the XXH32 streaming API. * * @see XXH32_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH32_state_s XXH32_state_t; /*! * @brief Allocates an @ref XXH32_state_t. * - * Must be freed with XXH32_freeState(). - * @return An allocated XXH32_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH32_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH32_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void); /*! * @brief Frees an @ref XXH32_state_t. * - * Must be allocated with XXH32_createState(). * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH32_createState(). + * + * @see @ref streaming_example "Streaming Example" + * */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); /*! @@ -636,23 +689,24 @@ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_ /*! * @brief Resets an @ref XXH32_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH32_update(). - * * @param statePtr The state struct to reset. * @param seed The 32-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH32_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH32_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -664,48 +718,36 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH32_state_t. * - * @note - * Calling XXH32_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash32 value from that state. + * @return The calculated 32-bit xxHash32 value from that state. + * + * @note + * Calling XXH32_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/* - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * This the simplest and fastest format for further post-processing. - * - * However, this leaves open the question of what is the order on the byte level, - * since little and big endian conventions will store the same number differently. - * - * The canonical representation settles this issue by mandating big-endian - * convention, the same convention as human-readable numbers (large digits first). - * - * When writing hash values to storage, sending them over a network, or printing - * them, it's highly recommended to use the canonical representation to ensure - * portability across a wider range of systems, present and future. - * - * The following functions allow transformation of hash values to and from - * canonical format. - */ - /*! * @brief Canonical (big endian) representation of @ref XXH32_hash_t. */ @@ -716,11 +758,13 @@ typedef struct { /*! * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t. * - * @param dst The @ref XXH32_canonical_t pointer to be stored to. + * @param dst The @ref XXH32_canonical_t pointer to be stored to. * @param hash The @ref XXH32_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); @@ -733,6 +777,8 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); @@ -794,7 +840,7 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni * As of writing this, only supported by clang. */ #if XXH_HAS_ATTRIBUTE(noescape) -# define XXH_NOESCAPE __attribute__((noescape)) +# define XXH_NOESCAPE __attribute__((__noescape__)) #else # define XXH_NOESCAPE #endif @@ -821,7 +867,11 @@ typedef uint64_t XXH64_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint64_t XXH64_hash_t; #else # include @@ -851,9 +901,6 @@ typedef uint64_t XXH64_hash_t; /*! * @brief Calculates the 64-bit hash of @p input using xxHash64. * - * This function usually runs faster on 64-bit systems, but slower on 32-bit - * systems (see benchmark). - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 64-bit seed to alter the hash's output predictably. @@ -863,13 +910,9 @@ typedef uint64_t XXH64_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 64-bit hash. + * @return The calculated 64-bit xxHash64 value. * - * @see - * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -879,23 +922,32 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size * @brief The opaque state struct for the XXH64 streaming API. * * @see XXH64_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ /*! * @brief Allocates an @ref XXH64_state_t. * - * Must be freed with XXH64_freeState(). - * @return An allocated XXH64_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH64_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH64_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void); /*! * @brief Frees an @ref XXH64_state_t. * - * Must be allocated with XXH64_createState(). * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH64_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); @@ -912,23 +964,24 @@ XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const /*! * @brief Resets an @ref XXH64_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH64_update(). - * * @param statePtr The state struct to reset. * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH64_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH64_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -940,23 +993,30 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH64_state_t. * - * @note - * Calling XXH64_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash64 value from that state. + * @return The calculated 64-bit xxHash64 value from that state. + * + * @note + * Calling XXH64_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -975,6 +1035,8 @@ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash); @@ -987,6 +1049,8 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src); @@ -1046,40 +1110,74 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const * * The API supports one-shot hashing, streaming mode, and custom secrets. */ + +/*! + * @ingroup tuning + * @brief Possible values for @ref XXH_VECTOR. + * + * Unless set explicitly, determined automatically. + */ +# define XXH_SCALAR 0 /*!< Portable scalar version */ +# define XXH_SSE2 1 /*!< SSE2 for Pentium 4, Opteron, all x86_64. */ +# define XXH_AVX2 2 /*!< AVX2 for Haswell and Bulldozer */ +# define XXH_AVX512 3 /*!< AVX512 for Skylake and Icelake */ +# define XXH_NEON 4 /*!< NEON for most ARMv7-A, all AArch64, and WASM SIMD128 */ +# define XXH_VSX 5 /*!< VSX and ZVector for POWER8/z13 (64-bit) */ +# define XXH_SVE 6 /*!< SVE for some ARMv8-A and ARMv9-A */ +# define XXH_LSX 7 /*!< LSX (128-bit SIMD) for LoongArch64 */ + + /*-********************************************************************** * XXH3 64-bit variant ************************************************************************/ /*! - * @brief 64-bit unseeded variant of XXH3. + * @brief Calculates 64-bit unseeded variant of XXH3 hash of @p input. * - * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however - * it may have slightly better performance due to constant propagation of the - * defaults. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. * - * @see - * XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms * @see * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants - * @see - * XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length); /*! - * @brief 64-bit seeded variant of XXH3 + * @brief Calculates 64-bit seeded variant of XXH3 hash of @p input. * - * This variant generates a custom secret on the fly based on default secret - * altered using the `seed` value. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. * - * While this operation is decently fast, note that it's not completely free. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. * * @note * seed == 0 produces the same results as @ref XXH3_64bits(). * - * @param input The data to hash - * @param length The length - * @param seed The 64-bit seed to alter the state. + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -1093,22 +1191,36 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const vo #define XXH3_SECRET_SIZE_MIN 136 /*! - * @brief 64-bit variant of XXH3 with a custom "secret". + * @brief Calculates 64-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. * * It's possible to provide any blob of bytes as a "secret" to generate the hash. * This makes it more difficult for an external actor to prepare an intentional collision. - * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). * However, the quality of the secret impacts the dispersion of the hash algorithm. * Therefore, the secret _must_ look like a bunch of random bytes. * Avoid "trivial" or structured data such as repeated sequences or a text document. * Whenever in doubt about the "randomness" of the blob of bytes, - * consider employing "XXH3_generateSecret()" instead (see below). + * consider employing @ref XXH3_generateSecret() instead (see below). * It will generate a proper high entropy secret derived from the blob of bytes. * Another advantage of using XXH3_generateSecret() is that * it guarantees that all bits within the initial blob of bytes * will impact every bit of the output. * This is not necessarily the case when using the blob of bytes directly * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); @@ -1123,9 +1235,10 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const */ /*! - * @brief The state struct for the XXH3 streaming API. + * @brief The opaque state struct for the XXH3 streaming API. * * @see XXH3_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH3_state_s XXH3_state_t; XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void); @@ -1144,15 +1257,20 @@ XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOE /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); @@ -1160,36 +1278,54 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* stateP /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits_withSeed()`. - * * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); /*! - * XXH3_64bits_reset_withSecret(): - * `secret` is referenced, it _must outlive_ the hash streaming session. - * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * `secret` is referenced, it _must outlive_ the hash streaming session. + * + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, * and the quality of produced hash values depends on secret's entropy * (secret's content should look like a bunch of random bytes). * When in doubt about the randomness of a candidate `secret`, * consider employing `XXH3_generateSecret()` instead (see below). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! * @brief Consumes a block of @p input to an @ref XXH3_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -1201,23 +1337,30 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_stat * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 64-bit hash value from that state. + * + * @note + * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1242,26 +1385,71 @@ typedef struct { } XXH128_hash_t; /*! - * @brief Unseeded 128-bit variant of XXH3 + * @brief Calculates 128-bit unseeded variant of XXH3 of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. * * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead * for shorter inputs. * - * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0, however + * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of `0`, however * it may have slightly better performance due to constant propagation of the * defaults. * - * @see - * XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms - * @see - * XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants - * @see - * XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version. + * @see XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len); -/*! @brief Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */ +/*! @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see XXH3_128bits(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */ +/*! + * @brief Calculates 128-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing @ref XXH3_generateSecret() instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ @@ -1281,36 +1469,65 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE cons /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits()`. * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits_withSeed()`. + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. * - * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). * + * @see @ref streaming_example "Streaming Example" */ -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH_64bits_reset_withSecret(). */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! @@ -1324,28 +1541,32 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_sta * * @pre * @p statePtr must not be `NULL`. - * @pre + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note * The memory between @p input and @p input + @p length must be valid, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 128-bit hash value from that state. + * + * @note + * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1355,18 +1576,27 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const X * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ /*! - * XXH128_isEqual(): - * Return: 1 if `h1` and `h2` are equal, 0 if they are not. + * @brief Check equality of two XXH128_hash_t values + * + * @param h1 The 128-bit hash value. + * @param h2 Another 128-bit hash value. + * + * @return `1` if `h1` and `h2` are equal. + * @return `0` if they are not. */ XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); /*! * @brief Compares two @ref XXH128_hash_t + * * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. * - * @return: >0 if *h128_1 > *h128_2 - * =0 if *h128_1 == *h128_2 - * <0 if *h128_1 < *h128_2 + * @param h128_1 Left-hand side value + * @param h128_2 Right-hand side value + * + * @return >0 if @p h128_1 > @p h128_2 + * @return =0 if @p h128_1 == @p h128_2 + * @return <0 if @p h128_1 < @p h128_2 */ XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2); @@ -1378,11 +1608,12 @@ typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical /*! * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t. * - * @param dst The @ref XXH128_canonical_t pointer to be stored to. + * @param dst The @ref XXH128_canonical_t pointer to be stored to. * @param hash The @ref XXH128_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash); @@ -1395,6 +1626,7 @@ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* ds * @p src must not be `NULL`. * * @return The converted hash. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src); @@ -1440,9 +1672,9 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE con struct XXH32_state_s { XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */ XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */ - XXH32_hash_t v[4]; /*!< Accumulator lanes */ - XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */ + XXH32_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[16]; /*!< Internal buffer for partial reads. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */ }; /* typedef'd to XXH32_state_t */ @@ -1463,9 +1695,9 @@ struct XXH32_state_s { */ struct XXH64_state_s { XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */ - XXH64_hash_t v[4]; /*!< Accumulator lanes */ - XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */ + XXH64_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[32]; /*!< Internal buffer for partial reads.. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/ XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ }; /* typedef'd to XXH64_state_t */ @@ -1473,8 +1705,7 @@ struct XXH64_state_s { #ifndef XXH_NO_XXH3 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ -# include -# define XXH_ALIGN(n) alignas(n) +# define XXH_ALIGN(n) _Alignas(n) #elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */ /* In C++ alignas() is a keyword */ # define XXH_ALIGN(n) alignas(n) @@ -1587,7 +1818,20 @@ struct XXH3_state_s { /*! - * simple alias to pre-selected XXH3_128bits variant + * @brief Calculates the 128-bit hash of @p data using XXH3. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p len is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 128-bit XXH3 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); @@ -1596,9 +1840,16 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, siz /* Symbols defined below must be considered tied to a specific library version. */ /*! - * XXH3_generateSecret(): + * @brief Derive a high-entropy secret from any user-defined content, named customSeed. + * + * @param secretBuffer A writable buffer for derived high-entropy secret data. + * @param secretSize Size of secretBuffer, in bytes. Must be >= XXH3_SECRET_SIZE_MIN. + * @param customSeed A user-defined content. + * @param customSeedSize Size of customSeed, in bytes. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. * - * Derive a high-entropy secret from any user-defined content, named customSeed. * The generated secret can be used in combination with `*_withSecret()` functions. * The `_withSecret()` variants are useful to provide a higher level of protection * than 64-bit seed, as it becomes much more difficult for an external actor to @@ -1651,6 +1902,9 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer /*! * @brief Generate the same secret as the _withSeed() variants. * + * @param secretBuffer A writable buffer of @ref XXH3_SECRET_DEFAULT_SIZE bytes + * @param seed The 64-bit seed to alter the hash result predictably. + * * The generated secret can be used in combination with *`*_withSecret()` and `_withSecretandSeed()` variants. * @@ -1670,7 +1924,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * }; * // Fast, caches the seeded secret for future uses. * class HashFast { - * unsigned char secret[XXH3_SECRET_SIZE_MIN]; + * unsigned char secret[XXH3_SECRET_DEFAULT_SIZE]; * public: * HashFast(XXH64_hash_t s) { * XXH3_generateSecret_fromSeed(secret, seed); @@ -1682,15 +1936,26 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * } * }; * @endcode - * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes - * @param seed The seed to seed the state. */ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed); /*! - * These variants generate hash values using either - * @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) - * or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX). + * @brief Maximum size of "short" key in bytes. + */ +#define XXH3_MIDSIZE_MAX 240 + +/*! + * @brief Calculates 64/128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * These variants generate hash values using either: + * - @p seed for "short" keys (< @ref XXH3_MIDSIZE_MAX = 240 bytes) + * - @p secret for "large" keys (>= @ref XXH3_MIDSIZE_MAX). * * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. * `_withSeed()` has to generate the secret on the fly for "large" keys. @@ -1717,22 +1982,71 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The memory segment to be hashed, at least @p len bytes in size. + * @param length The length of @p data, in bytes. + * @param secret The secret used to alter hash result predictably. + * @param secretSize The length of @p secret, in bytes (must be >= XXH3_SECRET_SIZE_MIN) + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(): contract is the same. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #ifndef XXH_NO_STREAM -/*! @copydoc XXH3_64bits_withSecretandSeed() */ +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + * + * Note: there was a bug in an earlier version of this function (<= v0.8.2) + * that would make it generate an incorrect hash value + * when @p seed == 0 and @p length < XXH3_MIDSIZE_MAX + * and @p secret is different from XXH3_generateSecret_fromSeed(). + * As stated in the contract, the correct hash result must be + * the same as XXH3_128bits_withSeed() when @p length <= XXH3_MIDSIZE_MAX. + * Results generated by this older version are wrong, hence not comparable. + */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #endif /* !XXH_NO_STREAM */ #endif /* !XXH_NO_XXH3 */ @@ -2100,15 +2414,15 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if XXH_NO_INLINE_HINTS /* disable inlining hints */ # if defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __attribute__((unused)) +# define XXH_FORCE_INLINE static __attribute__((__unused__)) # else # define XXH_FORCE_INLINE static # endif # define XXH_NO_INLINE static /* enable inlining hints */ #elif defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) -# define XXH_NO_INLINE static __attribute__((noinline)) +# define XXH_FORCE_INLINE static __inline__ __attribute__((__always_inline__, __unused__)) +# define XXH_NO_INLINE static __attribute__((__noinline__)) #elif defined(_MSC_VER) /* Visual Studio */ # define XXH_FORCE_INLINE static __forceinline # define XXH_NO_INLINE static __declspec(noinline) @@ -2121,12 +2435,34 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) # define XXH_NO_INLINE static #endif +#if defined(XXH_INLINE_ALL) +# define XXH_STATIC XXH_FORCE_INLINE +#else +# define XXH_STATIC static +#endif + #if XXH3_INLINE_SECRET # define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE #else # define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE #endif +#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ +# define XXH_RESTRICT /* disable */ +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined (__clang__)) \ + || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ + || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) +/* + * There are a LOT more compilers that recognize __restrict but this + * covers the major ones. + */ +# define XXH_RESTRICT __restrict +#else +# define XXH_RESTRICT /* disable */ +#endif /* ************************************* * Debug @@ -2206,10 +2542,14 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t xxh_u8; +# ifdef _AIX +# include +# else +# include +# endif + typedef uint8_t xxh_u8; #else - typedef unsigned char xxh_u8; + typedef unsigned char xxh_u8; #endif typedef XXH32_hash_t xxh_u32; @@ -2295,11 +2635,11 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; +typedef union { xxh_u32 u32; } __attribute__((__packed__)) unalign; #endif static xxh_u32 XXH_read32(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u32 xxh_unalign32; + typedef __attribute__((__aligned__(1))) xxh_u32 xxh_unalign32; return *((const xxh_unalign32*)ptr); } @@ -2445,6 +2785,9 @@ static int XXH_isLittleEndian(void) && XXH_HAS_BUILTIN(__builtin_rotateleft64) # define XXH_rotl32 __builtin_rotateleft32 # define XXH_rotl64 __builtin_rotateleft64 +#elif XXH_HAS_BUILTIN(__builtin_stdc_rotate_left) +# define XXH_rotl32 __builtin_stdc_rotate_left +# define XXH_rotl64 __builtin_stdc_rotate_left /* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ #elif defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) @@ -2590,7 +2933,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) #if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) /* * UGLY HACK: - * A compiler fence is the only thing that prevents GCC and Clang from + * A compiler fence is used to prevent GCC and Clang from * autovectorizing the XXH32 loop (pragmas and attributes don't work for some * reason) without globally disabling SSE4.1. * @@ -2651,6 +2994,61 @@ static xxh_u32 XXH32_avalanche(xxh_u32 hash) #define XXH_get32bits(p) XXH_readLE32_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH32(). + */ +XXH_FORCE_INLINE void +XXH32_initAccs(xxh_u32 *acc, xxh_u32 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + acc[1] = seed + XXH_PRIME32_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME32_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH32(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH32_consumeLong( + xxh_u32 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 15; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 16); + do { + acc[0] = XXH32_round(acc[0], XXH_get32bits(input)); input += 4; + acc[1] = XXH32_round(acc[1], XXH_get32bits(input)); input += 4; + acc[2] = XXH32_round(acc[2], XXH_get32bits(input)); input += 4; + acc[3] = XXH32_round(acc[3], XXH_get32bits(input)); input += 4; + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH32() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u32 +XXH32_mergeAccs(const xxh_u32 *acc) +{ + XXH_ASSERT(acc != NULL); + return XXH_rotl32(acc[0], 1) + XXH_rotl32(acc[1], 7) + + XXH_rotl32(acc[2], 12) + XXH_rotl32(acc[3], 18); +} + /*! * @internal * @brief Processes the last 0-15 bytes of @p ptr. @@ -2763,22 +3161,12 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment if (input==NULL) XXH_ASSERT(len == 0); if (len>=16) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 15; - xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - xxh_u32 v2 = seed + XXH_PRIME32_2; - xxh_u32 v3 = seed + 0; - xxh_u32 v4 = seed - XXH_PRIME32_1; + xxh_u32 acc[4]; + XXH32_initAccs(acc, seed); - do { - v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; - v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; - v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; - v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; - } while (input < limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) - + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + input = XXH32_consumeLong(acc, input, len, align); + + h32 = XXH32_mergeAccs(acc); } else { h32 = seed + XXH_PRIME32_5; } @@ -2834,10 +3222,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s { XXH_ASSERT(statePtr != NULL); memset(statePtr, 0, sizeof(*statePtr)); - statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - statePtr->v[1] = seed + XXH_PRIME32_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME32_1; + XXH32_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -2851,45 +3236,37 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len) return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len_32 += (XXH32_hash_t)len; + state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); - state->total_len_32 += (XXH32_hash_t)len; - state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); + XXH_ASSERT(state->bufferedSize < sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); - state->memsize += (XXH32_hash_t)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const xxh_u32* p32 = state->mem32; - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32)); - } - p += 16-state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer: complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* then process one round */ + (void)XXH32_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p <= bEnd-16) { - const xxh_u8* const limit = bEnd - 16; - - do { - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH32_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -2903,36 +3280,20 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) xxh_u32 h32; if (state->large_len) { - h32 = XXH_rotl32(state->v[0], 1) - + XXH_rotl32(state->v[1], 7) - + XXH_rotl32(state->v[2], 12) - + XXH_rotl32(state->v[3], 18); + h32 = XXH32_mergeAccs(state->acc); } else { - h32 = state->v[2] /* == seed */ + XXH_PRIME32_5; + h32 = state->acc[2] /* == seed */ + XXH_PRIME32_5; } h32 += state->total_len_32; - return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); + return XXH32_finalize(h32, state->buffer, state->bufferedSize, XXH_aligned); } #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/*! - * @ingroup XXH32_family - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * - * The canonical representation uses big endian convention, the same convention - * as human-readable numbers (large digits first). - * - * This way, hash values can be written into a file or buffer, remaining - * comparable across different systems. - * - * The following functions allow transformation of hash values to and from their - * canonical format. - */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); @@ -2987,11 +3348,11 @@ static xxh_u64 XXH_read64(const void* memPtr) * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; +typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((__packed__)) unalign64; #endif static xxh_u64 XXH_read64(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u64 xxh_unalign64; + typedef __attribute__((__aligned__(1))) xxh_u64 xxh_unalign64; return *((const xxh_unalign64*)ptr); } @@ -3110,6 +3471,23 @@ static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) acc += input * XXH_PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= XXH_PRIME64_1; +#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * DISABLE AUTOVECTORIZATION: + * A compiler fence is used to prevent GCC and Clang from + * autovectorizing the XXH64 loop (pragmas and attributes don't work for some + * reason) without globally disabling AVX512. + * + * Autovectorization of XXH64 tends to be detrimental, + * though the exact outcome may change depending on exact cpu and compiler version. + * For information, it has been reported as detrimental for Skylake-X, + * but possibly beneficial for Zen4. + * + * The default is to disable auto-vectorization, + * but you can select to enable it instead using `XXH_ENABLE_AUTOVECTORIZE` build variable. + */ + XXH_COMPILER_GUARD(acc); +#endif return acc; } @@ -3135,6 +3513,85 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) #define XXH_get64bits(p) XXH_readLE64_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH64(). + */ +XXH_FORCE_INLINE void +XXH64_initAccs(xxh_u64 *acc, xxh_u64 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + acc[1] = seed + XXH_PRIME64_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME64_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH64(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH64_consumeLong( + xxh_u64 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 31; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 32); + do { + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + acc[i] = XXH64_round(acc[i], XXH_get64bits(input)); + input += 8; + } + } else { + acc[0] = XXH64_round(acc[0], XXH_get64bits(input)); input += 8; + acc[1] = XXH64_round(acc[1], XXH_get64bits(input)); input += 8; + acc[2] = XXH64_round(acc[2], XXH_get64bits(input)); input += 8; + acc[3] = XXH64_round(acc[3], XXH_get64bits(input)); input += 8; + } + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH64() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u64 +XXH64_mergeAccs(const xxh_u64 *acc) +{ + XXH_ASSERT(acc != NULL); + { + xxh_u64 h64 = XXH_rotl64(acc[0], 1) + XXH_rotl64(acc[1], 7) + + XXH_rotl64(acc[2], 12) + XXH_rotl64(acc[3], 18); + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + h64 = XXH64_mergeRound(h64, acc[i]); + } + } else { + h64 = XXH64_mergeRound(h64, acc[0]); + h64 = XXH64_mergeRound(h64, acc[1]); + h64 = XXH64_mergeRound(h64, acc[2]); + h64 = XXH64_mergeRound(h64, acc[3]); + } + return h64; + } +} + /*! * @internal * @brief Processes the last 0-31 bytes of @p ptr. @@ -3150,7 +3607,7 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) * @return The finalized hash * @see XXH32_finalize(). */ -static XXH_PUREF xxh_u64 +XXH_STATIC XXH_PUREF xxh_u64 XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { if (ptr==NULL) XXH_ASSERT(len == 0); @@ -3200,27 +3657,13 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment xxh_u64 h64; if (input==NULL) XXH_ASSERT(len == 0); - if (len>=32) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 31; - xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - xxh_u64 v2 = seed + XXH_PRIME64_2; - xxh_u64 v3 = seed + 0; - xxh_u64 v4 = seed - XXH_PRIME64_1; + if (len>=32) { /* Process a large block of data */ + xxh_u64 acc[4]; + XXH64_initAccs(acc, seed); - do { - v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; - v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; - v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; - v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; - } while (inputv[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - statePtr->v[1] = seed + XXH_PRIME64_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME64_1; + XXH64_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -3292,42 +3732,36 @@ XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len += len; - state->total_len += len; + XXH_ASSERT(state->bufferedSize <= sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 32) { /* fill in tmp buffer */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); - state->memsize += (xxh_u32)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0)); - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1)); - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2)); - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3)); - p += 32 - state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer => complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* and process one round */ + (void)XXH64_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p+32 <= bEnd) { - const xxh_u8* const limit = bEnd - 32; - - do { - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8; - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8; - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8; - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH64_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -3341,18 +3775,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state xxh_u64 h64; if (state->total_len >= 32) { - h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18); - h64 = XXH64_mergeRound(h64, state->v[0]); - h64 = XXH64_mergeRound(h64, state->v[1]); - h64 = XXH64_mergeRound(h64, state->v[2]); - h64 = XXH64_mergeRound(h64, state->v[3]); + h64 = XXH64_mergeAccs(state->acc); } else { - h64 = state->v[2] /*seed*/ + XXH_PRIME64_5; + h64 = state->acc[2] /*seed*/ + XXH_PRIME64_5; } h64 += (xxh_u64) state->total_len; - return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); + return XXH64_finalize(h64, state->buffer, (size_t)state->total_len, XXH_aligned); } #endif /* !XXH_NO_STREAM */ @@ -3387,22 +3817,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can /* === Compiler specifics === */ -#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ -# define XXH_RESTRICT /* disable */ -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ -# define XXH_RESTRICT restrict -#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ - || (defined (__clang__)) \ - || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ - || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) -/* - * There are a LOT more compilers that recognize __restrict but this - * covers the major ones. - */ -# define XXH_RESTRICT __restrict -#else -# define XXH_RESTRICT /* disable */ -#endif #if (defined(__GNUC__) && (__GNUC__ >= 3)) \ || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ @@ -3416,7 +3830,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can #ifndef XXH_HAS_INCLUDE # ifdef __has_include -# define XXH_HAS_INCLUDE(x) __has_include(x) +/* + * Not defined as XXH_HAS_INCLUDE(x) (function-like) because + * this causes segfaults in Apple Clang 4.2 (on Mac OS X 10.7 Lion) + */ +# define XXH_HAS_INCLUDE __has_include # else # define XXH_HAS_INCLUDE(x) 0 # endif @@ -3437,6 +3855,8 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can # include # elif defined(__SSE2__) # include +# elif defined(__loongarch_sx) +# include # endif #endif @@ -3533,33 +3953,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can * implementation. */ # define XXH_VECTOR XXH_SCALAR -/*! - * @ingroup tuning - * @brief Possible values for @ref XXH_VECTOR. - * - * Note that these are actually implemented as macros. - * - * If this is not defined, it is detected automatically. - * internal macro XXH_X86DISPATCH overrides this. - */ -enum XXH_VECTOR_TYPE /* fake enum */ { - XXH_SCALAR = 0, /*!< Portable scalar version */ - XXH_SSE2 = 1, /*!< - * SSE2 for Pentium 4, Opteron, all x86_64. - * - * @note SSE2 is also guaranteed on Windows 10, macOS, and - * Android x86. - */ - XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ - XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ - XXH_NEON = 4, /*!< - * NEON for most ARMv7-A, all AArch64, and WASM SIMD128 - * via the SIMDeverywhere polyfill provided with the - * Emscripten SDK. - */ - XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ - XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */ -}; /*! * @ingroup tuning * @brief Selects the minimum alignment for XXH3's accumulators. @@ -3574,13 +3967,6 @@ enum XXH_VECTOR_TYPE /* fake enum */ { /* Actual definition */ #ifndef XXH_DOXYGEN -# define XXH_SCALAR 0 -# define XXH_SSE2 1 -# define XXH_AVX2 2 -# define XXH_AVX512 3 -# define XXH_NEON 4 -# define XXH_VSX 5 -# define XXH_SVE 6 #endif #ifndef XXH_VECTOR /* can be defined on command line */ @@ -3605,6 +3991,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { || (defined(__s390x__) && defined(__VEC__)) \ && defined(__GNUC__) /* TODO: IBM XL */ # define XXH_VECTOR XXH_VSX +# elif defined(__loongarch_sx) +# define XXH_VECTOR XXH_LSX # else # define XXH_VECTOR XXH_SCALAR # endif @@ -3642,6 +4030,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_ACC_ALIGN 64 # elif XXH_VECTOR == XXH_SVE /* sve */ # define XXH_ACC_ALIGN 64 +# elif XXH_VECTOR == XXH_LSX /* lsx */ +# define XXH_ACC_ALIGN 64 # endif #endif @@ -3655,7 +4045,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ { #endif #if defined(__GNUC__) || defined(__clang__) -# define XXH_ALIASING __attribute__((may_alias)) +# define XXH_ALIASING __attribute__((__may_alias__)) #else # define XXH_ALIASING /* nothing */ #endif @@ -4408,8 +4798,6 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, } } -#define XXH3_MIDSIZE_MAX 240 - XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -5281,6 +5669,71 @@ XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc, #endif +#if (XXH_VECTOR == XXH_LSX) +#define _LSX_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_lsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i *) acc; + const __m128i* const xinput = (const __m128i *) input; + const __m128i* const xsecret = (const __m128i *) secret; + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = __lsx_vld(xinput + i, 0); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + // __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = __lsx_vmulwev_d_wu(data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = __lsx_vshuf4i_w(data_vec, _LSX_SHUFFLE(1, 0, 3, 2)); + __m128i const sum = __lsx_vadd_d(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = __lsx_vadd_d(product, sum); + } + } +} +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lsx) + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_lsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i*) acc; + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = __lsx_vreplgr2vr_w((int)XXH_PRIME32_1); + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = __lsx_vsrli_d(acc_vec, 47); + __m128i const data_vec = __lsx_vxor_v(acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = __lsx_vsrli_d(data_key, 32); + __m128i const prod_lo = __lsx_vmulwev_d_wu(data_key, prime32); + __m128i const prod_hi = __lsx_vmulwev_d_wu(data_key_hi, prime32); + xacc[i] = __lsx_vadd_d(prod_lo, __lsx_vslli_d(prod_hi, 32)); + } + } +} + +#endif + /* scalar variants - universal */ #if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) @@ -5511,6 +5964,12 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#elif (XXH_VECTOR == XXH_LSX) +#define XXH3_accumulate_512 XXH3_accumulate_512_lsx +#define XXH3_accumulate XXH3_accumulate_lsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_lsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + #else /* scalar */ #define XXH3_accumulate_512 XXH3_accumulate_512_scalar @@ -5566,7 +6025,7 @@ XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret acc[1] ^ XXH_readLE64(secret+8) ); } -static XXH64_hash_t +static XXH_PUREF XXH64_hash_t XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) { xxh_u64 result64 = start; @@ -5593,6 +6052,15 @@ XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secre return XXH3_avalanche(result64); } +/* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + +static XXH_PUREF XXH64_hash_t +XXH3_finalizeLong_64b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 len) +{ + return XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, len * XXH_PRIME64_1); +} + #define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } @@ -5608,10 +6076,8 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); - /* do not align on 8, so that the secret is different from the accumulator */ -#define XXH_SECRET_MERGEACCS_START 11 XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, (const xxh_u8*)secret, (xxh_u64)len); } /* @@ -5747,7 +6213,7 @@ XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH /* === XXH3 streaming === */ #ifndef XXH_NO_STREAM /* - * Malloc's a pointer that is always aligned to align. + * Malloc's a pointer that is always aligned to @align. * * This must be freed with `XXH_alignedFree()`. * @@ -5815,8 +6281,12 @@ static void XXH_alignedFree(void* p) /*! * @brief Allocate an @ref XXH3_state_t. * - * Must be freed with XXH3_freeState(). - * @return An allocated XXH3_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH3_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH3_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) { @@ -5830,9 +6300,13 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) /*! * @brief Frees an @ref XXH3_state_t. * - * Must be allocated with XXH3_createState(). * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note Must be allocated with XXH3_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) { @@ -6111,9 +6585,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* if (state->totalLen > XXH3_MIDSIZE_MAX) { XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); - return XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, secret, (xxh_u64)state->totalLen); } /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ if (state->useSeed) @@ -6405,6 +6877,17 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, } } +static XXH_PUREF XXH128_hash_t +XXH3_finalizeLong_128b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, xxh_u64 len) +{ + XXH128_hash_t h128; + h128.low64 = XXH3_finalizeLong_64b(acc, secret, len); + h128.high64 = XXH3_mergeAccs(acc, secret + secretSize + - XXH_STRIPE_LEN - XXH_SECRET_MERGEACCS_START, + ~(len * XXH_PRIME64_2)); + return h128; +} + XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -6418,16 +6901,7 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)len * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + secretSize - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)len * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, secretSize, (xxh_u64)len); } /* @@ -6610,19 +7084,10 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_ XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + state->secretLimit + XXH_STRIPE_LEN - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, state->secretLimit + XXH_STRIPE_LEN, (xxh_u64)state->totalLen); } /* len <= XXH3_MIDSIZE_MAX : short code */ - if (state->seed) + if (state->useSeed) return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/42826a8941ecedd329844b675e26d30bdb6cd46b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/42826a8941ecedd329844b675e26d30bdb6cd46b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 7 23:17:59 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 07 Jan 2025 18:17:59 -0500 Subject: [Git][ghc/ghc][master] Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted Message-ID: <677db627dace6_2d2d811248f499663@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 1 changed file: - compiler/GHC/Tc/Solver/Solve.hs Changes: ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -1432,7 +1432,7 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1 }) ; wanted <- TcS.zonkSimples simples1 -- Plugin requires zonked inputs ; traceTcS "Running plugins (" (vcat [ text "Given:" <+> ppr given - , text "Watned:" <+> ppr wanted ]) + , text "Wanted:" <+> ppr wanted ]) ; p <- runTcPluginSolvers solvers (given, bagToList wanted) ; let (_, solved_wanted) = pluginSolvedCts p (_, unsolved_wanted) = pluginInputCts p View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/185f17e47e72e268496e16e1b6e9df71505a5bbc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/185f17e47e72e268496e16e1b6e9df71505a5bbc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 03:22:18 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Tue, 07 Jan 2025 22:22:18 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] 37 commits: Remove unnecessary irrefutable patterns from NonEmpty functions Message-ID: <677def6a72bd2_221bfa9b84a825976@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 11b858dc by Patrick at 2025-01-08T03:22:06+00:00 relax newType instance check - - - - - 5d87b095 by Patrick at 2025-01-08T03:22:06+00:00 include constructor in kind-checking for data family instance - - - - - 0c382962 by Patrick at 2025-01-08T03:22:06+00:00 add test case for T25611 - - - - - 79100e78 by Patrick at 2025-01-08T03:22:06+00:00 add test for T25593 - - - - - a064c390 by Patrick at 2025-01-08T03:22:06+00:00 add test for T25593 - - - - - 760a7629 by Patrick at 2025-01-08T03:22:06+00:00 Fix T25593 - - - - - 7b47c6d9 by Patrick at 2025-01-08T03:22:06+00:00 add test to ensure kind specialization is working as Note [Kind inference for data family instances] - - - - - 17a60f5b by Patrick at 2025-01-08T03:22:06+00:00 update test InstanceConKindSpecializationDataFamily - - - - - 926bba7d by Patrick at 2025-01-08T03:22:06+00:00 update test InstanceConKindSpecializationDataFamily - - - - - 00823469 by Patrick at 2025-01-08T03:22:06+00:00 Update Note [Implementation of UnliftedNewtypes] - - - - - 963986b5 by Patrick at 2025-01-08T03:22:06+00:00 format - - - - - 19918bb0 by Patrick at 2025-01-08T03:22:06+00:00 update Test `UnliftedNewtypesFamilyKindFail2`, `UnliftedNewtypesInstanceFail` for additional warning introduced by reintroduce datafam decls in kind check. - - - - - 83d0d1fc by Patrick at 2025-01-08T03:22:06+00:00 update comment - - - - - 7da9d04c by Patrick at 2025-01-08T03:22:06+00:00 Change UnliftedNewtypesUnassociatedFamilyFail to UnliftedNewtypesUnassociatedFamilyInfer. - - - - - b667ee13 by Patrick at 2025-01-08T03:22:06+00:00 cleanup - - - - - ec87c201 by Patrick at 2025-01-08T03:22:06+00:00 Only kcConDecls for (A) newtype or (B) H98 style - - - - - 6de08068 by Patrick at 2025-01-08T03:22:06+00:00 add isH98orNewType for clarity - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/ghc.cabal.in - docs/users_guide/phases.rst - ghc/ghc-bin.cabal.in - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Warnings.hs - libraries/Cabal - libraries/Win32 - libraries/array - libraries/base/base.cabal.in - libraries/base/changelog.md - libraries/base/src/Data/List/NonEmpty.hs - libraries/binary - libraries/bytestring - libraries/deepseq - libraries/directory - libraries/exceptions - libraries/file-io - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7f82a95c93813af98ba939f180999bd5e12b6e2...6de080686037bab0196c098edfc6867f4d57997f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c7f82a95c93813af98ba939f180999bd5e12b6e2...6de080686037bab0196c098edfc6867f4d57997f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 03:34:52 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Tue, 07 Jan 2025 22:34:52 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] tidy up Message-ID: <677df25cbaa6d_221bfab50e7826310@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 06dcb99b by Patrick at 2025-01-08T11:34:17+08:00 tidy up - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -715,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig hs_cons new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -743,7 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data + ; let flav = newOrDataToFlavour $ dataDefnConsNewOrData hs_cons ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. @@ -919,7 +918,6 @@ tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) - -> NewOrData -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -927,7 +925,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig hs_cons new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -943,18 +941,18 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig -- Add constraints from the data constructors -- Fix #25611 -- See Note [Kind inference for data family instances] - ; when isH98orNewType $ kcConDecls new_or_data res_kind hs_cons + ; when isH98orNewType $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1006,12 +1004,13 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons isH98orNewType = case hs_cons of NewTypeCon{} -> True - DataTypeCons _ cons -> isH98 cons - isH98 cons = flip any (unLoc <$> cons) $ \case - ConDeclH98{} -> True - _ -> False + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False + -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), -- and Note [Implementation of UnliftedDatatypes]. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06dcb99b6ec47f78ef9b3b2cdf309050d8639c0c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06dcb99b6ec47f78ef9b3b2cdf309050d8639c0c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 04:38:01 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Tue, 07 Jan 2025 23:38:01 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Check we defaults the result kind of the data instance correctly Message-ID: <677e012921ae7_221bfa126d4e0315fd@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 9f236601 by Patrick at 2025-01-08T12:37:07+08:00 Check we defaults the result kind of the data instance correctly - - - - - 3 changed files: - compiler/GHC/Tc/TyCl/Instance.hs - testsuite/tests/indexed-types/should_compile/all.T - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1015,9 +1015,10 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), -- and Note [Implementation of UnliftedDatatypes]. tc_kind_sig Nothing - = do { unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes + = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes + ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes ; case new_or_data of - NewType -> newOpenTypeKind + NewType | unlifted_newtypes -> newOpenTypeKind DataType | unlifted_datatypes -> newOpenTypeKind _ -> pure liftedTypeKind } ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -311,3 +311,4 @@ test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) test('T25611', normal, compile, ['']) +test('dataInstanceKindsDefaults', normal, compile, ['']) ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,16 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module dataInstanceKindsDefaults where + +import Data.Kind + +-- this test check if we defaults the kind of the data instance correctly +-- error would be caught by the validity checker `checkNewDataCon` from `GHC.Tc.TyCl` + +data family D :: k -> k +newtype instance D a = MkD a + +data family B :: k -> k +data instance B a = MkB a + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f2366010330664990206a2784689500db78739e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f2366010330664990206a2784689500db78739e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 04:41:36 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Tue, 07 Jan 2025 23:41:36 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <677e0200632c3_221bfa1314cf43195f@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 177df06f by Brandon Chinn at 2025-01-07T19:55:45-08:00 Require alex >= 3.5.2 (#25623) - - - - - 6 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in - hadrian/cabal.project Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: eb4d3389fd62e4f7321a0c8799014ec1f4da0708 + DOCKER_REV: f8b8b8910097a88185835e0c929b8bb03fadfe61 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/ci.sh ===================================== @@ -8,9 +8,9 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-04T21:29:42Z" MIN_HAPPY_VERSION="1.20" -MIN_ALEX_VERSION="3.2.6" +MIN_ALEX_VERSION="3.5.2.0" TOP="$(pwd)" if [ ! -d "$TOP/.gitlab" ]; then ===================================== .gitlab/darwin/nix/sources.json ===================================== @@ -17,10 +17,10 @@ "homepage": "", "owner": "nixos", "repo": "nixpkgs", - "rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60", + "rev": "07f572aeeaef429c75f4f867b35dc3acae3b5517", "sha256": "1anwxmjpm21msnnlrjdz19w31bxnbpn4kgf93sn3npihi7wf4a8h", "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/2893f56de08021cffd9b6b6dfc70fd9ccd51eb60.tar.gz", + "url": "https://github.com/nixos/nixpkgs/archive/07f572aeeaef429c75f4f867b35dc3acae3b5517.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-04T21:29:42Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/177df06fef34c3f29496611239ab59dd444abcde -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/177df06fef34c3f29496611239ab59dd444abcde You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 04:46:18 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Tue, 07 Jan 2025 23:46:18 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] add more examples to dataInstanceKindsDefaults Message-ID: <677e031a29aba_221bfa14d6060323e8@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 99d1a41c by Patrick at 2025-01-08T12:46:09+08:00 add more examples to dataInstanceKindsDefaults - - - - - 1 changed file: - testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs Changes: ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -1,16 +1,22 @@ {-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, TypeOperators, ConstraintKinds #-} -module dataInstanceKindsDefaults where +module DataInstanceKindsDefaults where import Data.Kind -- this test check if we defaults the kind of the data instance correctly -- error would be caught by the validity checker `checkNewDataCon` from `GHC.Tc.TyCl` -data family D :: k -> k -newtype instance D a = MkD a +data family A :: k -> k +newtype instance A a = MkA a data family B :: k -> k data instance B a = MkB a +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99d1a41cc24b90de35dd07eeee7eb75fcdfc401b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/99d1a41cc24b90de35dd07eeee7eb75fcdfc401b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 07:13:38 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 08 Jan 2025 02:13:38 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] arrange the fix to 25593 to another branch Message-ID: <677e25a27e62b_221bfa231c160334e3@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: db9d9ee3 by Patrick at 2025-01-08T15:13:22+08:00 arrange the fix to 25593 to another branch - - - - - 3 changed files: - − testsuite/tests/indexed-types/should_fail/T25593.hs - − testsuite/tests/indexed-types/should_fail/T25593.stderr - testsuite/tests/indexed-types/should_fail/all.T Changes: ===================================== testsuite/tests/indexed-types/should_fail/T25593.hs deleted ===================================== @@ -1,8 +0,0 @@ -{-# LANGUAGE MagicHash #-} -{-# LANGUAGE TypeFamilies #-} -import GHC.Exts - -data family A s a :: UnliftedType -newtype instance A s Int = A_Int (MutVar# s Int) - -newtype B s = B (MutVar# s Int) ===================================== testsuite/tests/indexed-types/should_fail/T25593.stderr deleted ===================================== @@ -1,11 +0,0 @@ -T25593.hs:6:1: error: [GHC-55233] - • Newtype instance has non-* return kind ‘UnliftedType’ - • In the newtype instance declaration for ‘A’ - Suggested fix: - Perhaps you intended to use the ‘UnliftedNewtypes’ extension - -T25593.hs:8:1: error: [GHC-55233] - • Newtype has non-* return kind ‘UnliftedType’ - • In the newtype declaration for ‘B’ - Suggested fix: - Perhaps you intended to use the ‘UnliftedNewtypes’ extension \ No newline at end of file ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,5 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) -test('T25593', normal, compile_fail, ['']) \ No newline at end of file +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/db9d9ee3ddc2ecd3053fac6c4f7bd132f082a54c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/db9d9ee3ddc2ecd3053fac6c4f7bd132f082a54c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 07:22:19 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Wed, 08 Jan 2025 02:22:19 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <677e27abbd4ce_221bfa23fe8bc360ed@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: d3b93b1d by Brandon Chinn at 2025-01-07T23:22:05-08:00 Require alex >= 3.5.2 (#25623) - - - - - 6 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in - hadrian/cabal.project Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: eb4d3389fd62e4f7321a0c8799014ec1f4da0708 + DOCKER_REV: f8b8b8910097a88185835e0c929b8bb03fadfe61 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/ci.sh ===================================== @@ -8,9 +8,9 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-04T21:29:42Z" MIN_HAPPY_VERSION="1.20" -MIN_ALEX_VERSION="3.2.6" +MIN_ALEX_VERSION="3.5.2.0" TOP="$(pwd)" if [ ! -d "$TOP/.gitlab" ]; then ===================================== .gitlab/darwin/nix/sources.json ===================================== @@ -17,10 +17,10 @@ "homepage": "", "owner": "nixos", "repo": "nixpkgs", - "rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60", - "sha256": "1anwxmjpm21msnnlrjdz19w31bxnbpn4kgf93sn3npihi7wf4a8h", + "rev": "07f572aeeaef429c75f4f867b35dc3acae3b5517", + "sha256": "", "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/2893f56de08021cffd9b6b6dfc70fd9ccd51eb60.tar.gz", + "url": "https://github.com/nixos/nixpkgs/archive/07f572aeeaef429c75f4f867b35dc3acae3b5517.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-04T21:29:42Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3b93b1dc713f9396b0a29cb9b25e6fc5f4c5771 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3b93b1dc713f9396b0a29cb9b25e6fc5f4c5771 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 09:16:47 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 08 Jan 2025 04:16:47 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update Note [Kind inference for data family instances] Message-ID: <677e427f47d0_221bfa3357930404cc@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: b79bf9fc by Patrick at 2025-01-08T17:16:38+08:00 update Note [Kind inference for data family instances] - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1198,26 +1198,28 @@ constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: in data/newtype family instance declarations, we take +the /data constructor/ declarations into accound for Haskell-98 style +data-instance and newtype-instance declarations. But for general +GADT-style data-instance declarations, we are looking only at the data +instance /header/. Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We treat Haskell-98 style data-instance decls differently, by taking + the data constructors into account, since there are no GADT + issues. * Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. + specialisation, so like Haskell-98 definitions we can take the + data constructors into account. + +* With UnliftedNewtypes or UnliftedDatatypes, looking at the data + constructors is necessary to infer the kind of result type for certain + cases. Otherwise addtional kind signatures are required(see #25611). + -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +We are balancing between well rounded kind inference and the implementation +simplicity. See #25611, #18891 and !4419 for more discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b79bf9fcae7ebd7d0f76aab721fb9b97d68ad163 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b79bf9fcae7ebd7d0f76aab721fb9b97d68ad163 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 10:44:04 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 08 Jan 2025 05:44:04 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] format Message-ID: <677e56f491f09_3415de80f368446fb@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 09a5916c by Patrick at 2025-01-08T18:43:53+08:00 format - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -941,11 +941,10 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the data constructors -- Fix #25611 -- See Note [Kind inference for data family instances] - ; when isH98orNewType $ kcConDecls lhs_applied_kind hs_cons + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there @@ -1005,13 +1004,12 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name new_or_data = dataDefnConsNewOrData hs_cons - isH98orNewType = case hs_cons of + is_H98_or_newtype = case hs_cons of NewTypeCon{} -> True DataTypeCons _ cons -> all isH98 cons isH98 (L _ (ConDeclH98 {})) = True isH98 _ = False - -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), -- and Note [Implementation of UnliftedDatatypes]. tc_kind_sig Nothing View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/09a5916cbaff500fd60b392519e6990645b3858e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/09a5916cbaff500fd60b392519e6990645b3858e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 10:55:39 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 08 Jan 2025 05:55:39 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] 6 commits: warnings: Find out if a qualified name is in the interactive scope directly Message-ID: <677e59abe1fa8_3415debda650486f4@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 17ed5b64 by Rodrigo Mesquita at 2025-01-08T10:55:31+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/82a818a72248753949ec5d099143ebaa459bd291...17ed5b64676b9b96ede07bbcd9591e8140690cea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/82a818a72248753949ec5d099143ebaa459bd291...17ed5b64676b9b96ede07bbcd9591e8140690cea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 12:47:07 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 08 Jan 2025 07:47:07 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/t25571 Message-ID: <677e73cbb9d7f_26c6ec4b436c99585@gitlab.mail> Matthew Pickering pushed new branch wip/t25571 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/t25571 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 13:24:52 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 08 Jan 2025 08:24:52 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Remove tmp files after toolchain check Message-ID: <677e7ca42ba7f_26c6ecb08a74107639@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 956f8410 by Ben Gamari at 2025-01-08T08:24:04-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 16 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/cbits/genSym.c - docs/users_guide/using-optimisation.rst - m4/ghc_toolchain.m4 - rts/xxhash.h - + testsuite/tests/core-to-stg/T25284/A.hs - + testsuite/tests/core-to-stg/T25284/B.hs - + testsuite/tests/core-to-stg/T25284/Cls.hs - + testsuite/tests/core-to-stg/T25284/Main.hs - + testsuite/tests/core-to-stg/T25284/T25284.stdout - + testsuite/tests/core-to-stg/T25284/all.T Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2051,6 +2051,16 @@ conceptually. See also Note [Floats and FloatDecision] for how we maintain whole groups of floats and how far they go. +Note [Controlling Speculative Evaluation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Most of the time, speculative evaluation has a positive effect on performance, +but we have found a case where speculative evaluation of dictionary functions +leads to a performance regression #25284. + +Therefore we have some flags to control it. See the optimization section in +the User's Guide for the description of these flags and when to use them. + Note [Floats and FloatDecision] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We have a special datatype `Floats` for modelling a telescope of `FloatingBind` @@ -2275,7 +2285,15 @@ mkNonRecFloat env lev bndr rhs } is_hnf = exprIsHNF rhs - ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs + cfg = cpe_config env + + ok_for_spec = exprOkForSpecEval call_ok_for_spec rhs + -- See Note [Controlling Speculative Evaluation] + call_ok_for_spec x + | is_rec_call x = False + | not (cp_specEval cfg) = False + | not (cp_specEvalDFun cfg) && isDFunId x = False + | otherwise = True is_rec_call = (`elemUnVarSet` cpe_rec_ids env) -- See Note [Pin evaluatedness on floats] @@ -2517,6 +2535,11 @@ data CorePrepConfig = CorePrepConfig -- ^ Configuration for arity analysis ('exprEtaExpandArity'). -- See Note [Eta expansion of arguments in CorePrep] -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead + , cp_specEval :: !Bool + -- ^ Whether to perform speculative evaluation + -- See Note [Controlling Speculative Evaluation] + , cp_specEvalDFun :: !Bool + -- ^ Whether to perform speculative evaluation on DFuns } data CorePrepEnv ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -24,6 +24,8 @@ initCorePrepConfig hsc_env = do , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags then Just (initArityOpts dflags) else Nothing + , cp_specEval = gopt Opt_SpecEval dflags + , cp_specEvalDFun = gopt Opt_SpecEvalDictFun dflags } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1287,6 +1287,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] -- RegsGraph suffers performance regression. See #7679 -- , ([2], Opt_StaticArgumentTransformation) -- Static Argument Transformation needs investigation. See #9374 + , ([0,1,2], Opt_SpecEval) + , ([0,1,2], Opt_SpecEvalDictFun) ] ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -674,6 +674,9 @@ data GeneralFlag | Opt_NumConstantFolding | Opt_CoreConstantFolding | Opt_FastPAPCalls -- #6084 + | Opt_SpecEval + | Opt_SpecEvalDictFun -- See Note [Controlling Speculative Evaluation] + -- Inference flags | Opt_DoTagInferenceChecks @@ -912,6 +915,8 @@ optimisationFlags = EnumSet.fromList , Opt_WorkerWrapper , Opt_WorkerWrapperUnlift , Opt_SolveConstantDicts + , Opt_SpecEval + , Opt_SpecEvalDictFun ] -- | The set of flags which affect code generation and can change a program's ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2544,6 +2544,8 @@ fFlagsDeps = [ flagSpec "num-constant-folding" Opt_NumConstantFolding, flagSpec "core-constant-folding" Opt_CoreConstantFolding, flagSpec "fast-pap-calls" Opt_FastPAPCalls, + flagSpec "spec-eval" Opt_SpecEval, + flagSpec "spec-eval-dictfun" Opt_SpecEvalDictFun, flagSpec "cmm-control-flow" Opt_CmmControlFlow, flagSpec "show-warning-groups" Opt_ShowWarnGroups, flagSpec "hide-source-paths" Opt_HideSourcePaths, ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -1432,7 +1432,7 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1 }) ; wanted <- TcS.zonkSimples simples1 -- Plugin requires zonked inputs ; traceTcS "Running plugins (" (vcat [ text "Given:" <+> ppr given - , text "Watned:" <+> ppr wanted ]) + , text "Wanted:" <+> ppr wanted ]) ; p <- runTcPluginSolvers solvers (given, bagToList wanted) ; let (_, solved_wanted) = pluginSolvedCts p (_, unsolved_wanted) = pluginInputCts p ===================================== compiler/cbits/genSym.c ===================================== @@ -9,6 +9,18 @@ // // The CPP is thus about the RTS version GHC is linked against, and not the // version of the GHC being built. -#if !MIN_VERSION_GLASGOW_HASKELL(9,9,0,0) + +#if MIN_VERSION_GLASGOW_HASKELL(9,9,0,0) +// Unique64 patch was present in 9.10 and later +#define HAVE_UNIQUE64 1 +#elif !MIN_VERSION_GLASGOW_HASKELL(9,9,0,0) && MIN_VERSION_GLASGOW_HASKELL(9,8,4,0) +// Unique64 patch was backported to 9.8.4 +#define HAVE_UNIQUE64 1 +#elif !MIN_VERSION_GLASGOW_HASKELL(9,9,0,0) && MIN_VERSION_GLASGOW_HASKELL(9,6,7,0) +// Unique64 patch was backported to 9.6.7 +#define HAVE_UNIQUE64 1 +#endif + +#if !defined(HAVE_UNIQUE64) HsWord64 ghc_unique_counter64 = 0; #endif ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -405,6 +405,55 @@ as such you shouldn't need to set any of them explicitly. A flag intermediate language, where it is able to common up some subexpressions that differ in their types, but not their representation. +.. ghc-flag:: -fspec-eval + :shortdesc: Enables speculative evaluation. + :type: dynamic + :category: + :reverse: -fno-spec-eval + + :default: on + :since: 9.14.1 + + Enables speculative evaluation which usually results in fewer allocations. + Enabling speculative evaluation should not cause performance regressions. + If you encounter any, please open a ticket. + + Note that disabling this flag will switch off speculative evaluation + completely, causing :ghc-flag:`-fspec-eval-dictfun` to have + no effect. + +.. ghc-flag:: -fspec-eval-dictfun + :shortdesc: Enables speculative evaluation of dictionary functions. + :type: dynamic + :category: + :reverse: -fno-spec-eval-dictfun + + :default: on + :since: 9.14.1 + + Enables speculative (strict) evaluation of dictionary functions. + + This is best explained with an example :: + + instance C a => D a where ... + + g :: D a => a -> Int + g x = ... + + f :: C a => a -> Int + f x = g x + + Function `f` has to pass a `D a` dictionary to `g`, and uses a dictionary + function `C a => D a` to compute it. If speculative evaluation for + dictionary functions is enabled, this dictionary is computed + strictly. + + Speculative evalation of dictionary functions can lead to slightly better + performance, because a thunk is avoided. However, it results in unnecessary + computation and allocation if the dictionary goes unused. This causes + a significant increase in allocation if the dictionary is large. + See (:ghc-ticket:`25284`). + .. ghc-flag:: -fdicts-cheap :shortdesc: Make dictionary-valued expressions seem cheap to the optimiser. :type: dynamic ===================================== m4/ghc_toolchain.m4 ===================================== @@ -187,6 +187,7 @@ AC_DEFUN([VALIDATE_GHC_TOOLCHAIN],[ "$GHC_TOOLCHAIN_BIN" format --input="$1" --output="$o1" "$GHC_TOOLCHAIN_BIN" format --input="$2" --output="$o2" diff_output=`diff "$o1" "$o2" 2>&1` + rm -f "$o1" "$o2" if test -z "$diff_output"; then true else ===================================== rts/xxhash.h ===================================== @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (C) 2012-2021 Yann Collet + * Copyright (C) 2012-2023 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -130,6 +130,7 @@ * } * @endcode * + * * @anchor streaming_example * **Streaming** * @@ -165,6 +166,77 @@ * } * @endcode * + * Streaming functions generate the xxHash value from an incremental input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + * + * + * @anchor canonical_representation_example + * **Canonical Representation** + * + * The default return values from XXH functions are unsigned 32, 64 and 128 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + * + * XXH32_canonicalFromHash(), XXH32_hashFromCanonical(), + * XXH64_canonicalFromHash(), XXH64_hashFromCanonical(), + * XXH128_canonicalFromHash(), XXH128_hashFromCanonical(), + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which prints XXH32_hash_t in human readable format + * void printXxh32(XXH32_hash_t hash) + * { + * XXH32_canonical_t cano; + * XXH32_canonicalFromHash(&cano, hash); + * size_t i; + * for(i = 0; i < sizeof(cano.digest); ++i) { + * printf("%02x", cano.digest[i]); + * } + * printf("\n"); + * } + * + * // Example for a function which converts XXH32_canonical_t to XXH32_hash_t + * XXH32_hash_t convertCanonicalToXxh32(XXH32_canonical_t cano) + * { + * XXH32_hash_t hash = XXH32_hashFromCanonical(&cano); + * return hash; + * } + * @endcode + * + * * @file xxhash.h * xxHash prototypes and implementation */ @@ -261,7 +333,7 @@ extern "C" { /* make all functions private */ # undef XXH_PUBLIC_API # if defined(__GNUC__) -# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# define XXH_PUBLIC_API static __inline __attribute__((__unused__)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # define XXH_PUBLIC_API static inline # elif defined(_MSC_VER) @@ -373,7 +445,7 @@ extern "C" { /*! @brief Marks a global symbol. */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -449,7 +521,7 @@ extern "C" { /* specific declaration modes for Windows */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -461,9 +533,9 @@ extern "C" { #endif #if defined (__GNUC__) -# define XXH_CONSTF __attribute__((const)) -# define XXH_PUREF __attribute__((pure)) -# define XXH_MALLOCF __attribute__((malloc)) +# define XXH_CONSTF __attribute__((__const__)) +# define XXH_PUREF __attribute__((__pure__)) +# define XXH_MALLOCF __attribute__((__malloc__)) #else # define XXH_CONSTF /* disable */ # define XXH_PUREF @@ -475,7 +547,7 @@ extern "C" { ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 8 -#define XXH_VERSION_RELEASE 2 +#define XXH_VERSION_RELEASE 3 /*! @brief Version number, encoded as two digits each */ #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) @@ -517,7 +589,11 @@ typedef uint32_t XXH32_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint32_t XXH32_hash_t; #else @@ -551,10 +627,6 @@ typedef uint32_t XXH32_hash_t; /*! * @brief Calculates the 32-bit hash of @p input using xxHash32. * - * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s - * - * See @ref single_shot_example "Single Shot Example" for an example. - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 32-bit seed to alter the hash's output predictably. @@ -564,63 +636,44 @@ typedef uint32_t XXH32_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 32-bit hash value. + * @return The calculated 32-bit xxHash32 value. * - * @see - * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); #ifndef XXH_NO_STREAM -/*! - * Streaming functions generate the xxHash value from an incremental input. - * This method is slower than single-call functions, due to state management. - * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. - * - * An XXH state must first be allocated using `XXH*_createState()`. - * - * Start a new hash by initializing the state with a seed using `XXH*_reset()`. - * - * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. - * - * The function returns an error code, with 0 meaning OK, and any other value - * meaning there is an error. - * - * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. - * This function returns the nn-bits hash as an int or long long. - * - * It's still possible to continue inserting input into the hash state after a - * digest, and generate new hash values later on by invoking `XXH*_digest()`. - * - * When done, release the state using `XXH*_freeState()`. - * - * @see streaming_example at the top of @ref xxhash.h for an example. - */ - /*! * @typedef struct XXH32_state_s XXH32_state_t * @brief The opaque state struct for the XXH32 streaming API. * * @see XXH32_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH32_state_s XXH32_state_t; /*! * @brief Allocates an @ref XXH32_state_t. * - * Must be freed with XXH32_freeState(). - * @return An allocated XXH32_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH32_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH32_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void); /*! * @brief Frees an @ref XXH32_state_t. * - * Must be allocated with XXH32_createState(). * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH32_createState(). + * + * @see @ref streaming_example "Streaming Example" + * */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); /*! @@ -636,23 +689,24 @@ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_ /*! * @brief Resets an @ref XXH32_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH32_update(). - * * @param statePtr The state struct to reset. * @param seed The 32-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH32_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH32_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -664,48 +718,36 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH32_state_t. * - * @note - * Calling XXH32_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash32 value from that state. + * @return The calculated 32-bit xxHash32 value from that state. + * + * @note + * Calling XXH32_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/* - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * This the simplest and fastest format for further post-processing. - * - * However, this leaves open the question of what is the order on the byte level, - * since little and big endian conventions will store the same number differently. - * - * The canonical representation settles this issue by mandating big-endian - * convention, the same convention as human-readable numbers (large digits first). - * - * When writing hash values to storage, sending them over a network, or printing - * them, it's highly recommended to use the canonical representation to ensure - * portability across a wider range of systems, present and future. - * - * The following functions allow transformation of hash values to and from - * canonical format. - */ - /*! * @brief Canonical (big endian) representation of @ref XXH32_hash_t. */ @@ -716,11 +758,13 @@ typedef struct { /*! * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t. * - * @param dst The @ref XXH32_canonical_t pointer to be stored to. + * @param dst The @ref XXH32_canonical_t pointer to be stored to. * @param hash The @ref XXH32_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); @@ -733,6 +777,8 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); @@ -794,7 +840,7 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni * As of writing this, only supported by clang. */ #if XXH_HAS_ATTRIBUTE(noescape) -# define XXH_NOESCAPE __attribute__((noescape)) +# define XXH_NOESCAPE __attribute__((__noescape__)) #else # define XXH_NOESCAPE #endif @@ -821,7 +867,11 @@ typedef uint64_t XXH64_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint64_t XXH64_hash_t; #else # include @@ -851,9 +901,6 @@ typedef uint64_t XXH64_hash_t; /*! * @brief Calculates the 64-bit hash of @p input using xxHash64. * - * This function usually runs faster on 64-bit systems, but slower on 32-bit - * systems (see benchmark). - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 64-bit seed to alter the hash's output predictably. @@ -863,13 +910,9 @@ typedef uint64_t XXH64_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 64-bit hash. + * @return The calculated 64-bit xxHash64 value. * - * @see - * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -879,23 +922,32 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size * @brief The opaque state struct for the XXH64 streaming API. * * @see XXH64_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ /*! * @brief Allocates an @ref XXH64_state_t. * - * Must be freed with XXH64_freeState(). - * @return An allocated XXH64_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH64_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH64_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void); /*! * @brief Frees an @ref XXH64_state_t. * - * Must be allocated with XXH64_createState(). * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH64_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); @@ -912,23 +964,24 @@ XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const /*! * @brief Resets an @ref XXH64_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH64_update(). - * * @param statePtr The state struct to reset. * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH64_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH64_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -940,23 +993,30 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH64_state_t. * - * @note - * Calling XXH64_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash64 value from that state. + * @return The calculated 64-bit xxHash64 value from that state. + * + * @note + * Calling XXH64_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -975,6 +1035,8 @@ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash); @@ -987,6 +1049,8 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src); @@ -1046,40 +1110,74 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const * * The API supports one-shot hashing, streaming mode, and custom secrets. */ + +/*! + * @ingroup tuning + * @brief Possible values for @ref XXH_VECTOR. + * + * Unless set explicitly, determined automatically. + */ +# define XXH_SCALAR 0 /*!< Portable scalar version */ +# define XXH_SSE2 1 /*!< SSE2 for Pentium 4, Opteron, all x86_64. */ +# define XXH_AVX2 2 /*!< AVX2 for Haswell and Bulldozer */ +# define XXH_AVX512 3 /*!< AVX512 for Skylake and Icelake */ +# define XXH_NEON 4 /*!< NEON for most ARMv7-A, all AArch64, and WASM SIMD128 */ +# define XXH_VSX 5 /*!< VSX and ZVector for POWER8/z13 (64-bit) */ +# define XXH_SVE 6 /*!< SVE for some ARMv8-A and ARMv9-A */ +# define XXH_LSX 7 /*!< LSX (128-bit SIMD) for LoongArch64 */ + + /*-********************************************************************** * XXH3 64-bit variant ************************************************************************/ /*! - * @brief 64-bit unseeded variant of XXH3. + * @brief Calculates 64-bit unseeded variant of XXH3 hash of @p input. * - * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however - * it may have slightly better performance due to constant propagation of the - * defaults. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. * - * @see - * XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms * @see * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants - * @see - * XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length); /*! - * @brief 64-bit seeded variant of XXH3 + * @brief Calculates 64-bit seeded variant of XXH3 hash of @p input. * - * This variant generates a custom secret on the fly based on default secret - * altered using the `seed` value. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. * - * While this operation is decently fast, note that it's not completely free. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. * * @note * seed == 0 produces the same results as @ref XXH3_64bits(). * - * @param input The data to hash - * @param length The length - * @param seed The 64-bit seed to alter the state. + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -1093,22 +1191,36 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const vo #define XXH3_SECRET_SIZE_MIN 136 /*! - * @brief 64-bit variant of XXH3 with a custom "secret". + * @brief Calculates 64-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. * * It's possible to provide any blob of bytes as a "secret" to generate the hash. * This makes it more difficult for an external actor to prepare an intentional collision. - * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). * However, the quality of the secret impacts the dispersion of the hash algorithm. * Therefore, the secret _must_ look like a bunch of random bytes. * Avoid "trivial" or structured data such as repeated sequences or a text document. * Whenever in doubt about the "randomness" of the blob of bytes, - * consider employing "XXH3_generateSecret()" instead (see below). + * consider employing @ref XXH3_generateSecret() instead (see below). * It will generate a proper high entropy secret derived from the blob of bytes. * Another advantage of using XXH3_generateSecret() is that * it guarantees that all bits within the initial blob of bytes * will impact every bit of the output. * This is not necessarily the case when using the blob of bytes directly * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); @@ -1123,9 +1235,10 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const */ /*! - * @brief The state struct for the XXH3 streaming API. + * @brief The opaque state struct for the XXH3 streaming API. * * @see XXH3_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH3_state_s XXH3_state_t; XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void); @@ -1144,15 +1257,20 @@ XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOE /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); @@ -1160,36 +1278,54 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* stateP /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits_withSeed()`. - * * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); /*! - * XXH3_64bits_reset_withSecret(): - * `secret` is referenced, it _must outlive_ the hash streaming session. - * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * `secret` is referenced, it _must outlive_ the hash streaming session. + * + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, * and the quality of produced hash values depends on secret's entropy * (secret's content should look like a bunch of random bytes). * When in doubt about the randomness of a candidate `secret`, * consider employing `XXH3_generateSecret()` instead (see below). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! * @brief Consumes a block of @p input to an @ref XXH3_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -1201,23 +1337,30 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_stat * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 64-bit hash value from that state. + * + * @note + * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1242,26 +1385,71 @@ typedef struct { } XXH128_hash_t; /*! - * @brief Unseeded 128-bit variant of XXH3 + * @brief Calculates 128-bit unseeded variant of XXH3 of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. * * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead * for shorter inputs. * - * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0, however + * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of `0`, however * it may have slightly better performance due to constant propagation of the * defaults. * - * @see - * XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms - * @see - * XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants - * @see - * XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version. + * @see XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len); -/*! @brief Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */ +/*! @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see XXH3_128bits(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */ +/*! + * @brief Calculates 128-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing @ref XXH3_generateSecret() instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ @@ -1281,36 +1469,65 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE cons /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits()`. * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits_withSeed()`. + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. * - * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). * + * @see @ref streaming_example "Streaming Example" */ -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH_64bits_reset_withSecret(). */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! @@ -1324,28 +1541,32 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_sta * * @pre * @p statePtr must not be `NULL`. - * @pre + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note * The memory between @p input and @p input + @p length must be valid, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 128-bit hash value from that state. + * + * @note + * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1355,18 +1576,27 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const X * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ /*! - * XXH128_isEqual(): - * Return: 1 if `h1` and `h2` are equal, 0 if they are not. + * @brief Check equality of two XXH128_hash_t values + * + * @param h1 The 128-bit hash value. + * @param h2 Another 128-bit hash value. + * + * @return `1` if `h1` and `h2` are equal. + * @return `0` if they are not. */ XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); /*! * @brief Compares two @ref XXH128_hash_t + * * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. * - * @return: >0 if *h128_1 > *h128_2 - * =0 if *h128_1 == *h128_2 - * <0 if *h128_1 < *h128_2 + * @param h128_1 Left-hand side value + * @param h128_2 Right-hand side value + * + * @return >0 if @p h128_1 > @p h128_2 + * @return =0 if @p h128_1 == @p h128_2 + * @return <0 if @p h128_1 < @p h128_2 */ XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2); @@ -1378,11 +1608,12 @@ typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical /*! * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t. * - * @param dst The @ref XXH128_canonical_t pointer to be stored to. + * @param dst The @ref XXH128_canonical_t pointer to be stored to. * @param hash The @ref XXH128_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash); @@ -1395,6 +1626,7 @@ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* ds * @p src must not be `NULL`. * * @return The converted hash. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src); @@ -1440,9 +1672,9 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE con struct XXH32_state_s { XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */ XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */ - XXH32_hash_t v[4]; /*!< Accumulator lanes */ - XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */ + XXH32_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[16]; /*!< Internal buffer for partial reads. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */ }; /* typedef'd to XXH32_state_t */ @@ -1463,9 +1695,9 @@ struct XXH32_state_s { */ struct XXH64_state_s { XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */ - XXH64_hash_t v[4]; /*!< Accumulator lanes */ - XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */ + XXH64_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[32]; /*!< Internal buffer for partial reads.. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/ XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ }; /* typedef'd to XXH64_state_t */ @@ -1473,8 +1705,7 @@ struct XXH64_state_s { #ifndef XXH_NO_XXH3 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ -# include -# define XXH_ALIGN(n) alignas(n) +# define XXH_ALIGN(n) _Alignas(n) #elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */ /* In C++ alignas() is a keyword */ # define XXH_ALIGN(n) alignas(n) @@ -1587,7 +1818,20 @@ struct XXH3_state_s { /*! - * simple alias to pre-selected XXH3_128bits variant + * @brief Calculates the 128-bit hash of @p data using XXH3. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p len is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 128-bit XXH3 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); @@ -1596,9 +1840,16 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, siz /* Symbols defined below must be considered tied to a specific library version. */ /*! - * XXH3_generateSecret(): + * @brief Derive a high-entropy secret from any user-defined content, named customSeed. + * + * @param secretBuffer A writable buffer for derived high-entropy secret data. + * @param secretSize Size of secretBuffer, in bytes. Must be >= XXH3_SECRET_SIZE_MIN. + * @param customSeed A user-defined content. + * @param customSeedSize Size of customSeed, in bytes. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. * - * Derive a high-entropy secret from any user-defined content, named customSeed. * The generated secret can be used in combination with `*_withSecret()` functions. * The `_withSecret()` variants are useful to provide a higher level of protection * than 64-bit seed, as it becomes much more difficult for an external actor to @@ -1651,6 +1902,9 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer /*! * @brief Generate the same secret as the _withSeed() variants. * + * @param secretBuffer A writable buffer of @ref XXH3_SECRET_DEFAULT_SIZE bytes + * @param seed The 64-bit seed to alter the hash result predictably. + * * The generated secret can be used in combination with *`*_withSecret()` and `_withSecretandSeed()` variants. * @@ -1670,7 +1924,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * }; * // Fast, caches the seeded secret for future uses. * class HashFast { - * unsigned char secret[XXH3_SECRET_SIZE_MIN]; + * unsigned char secret[XXH3_SECRET_DEFAULT_SIZE]; * public: * HashFast(XXH64_hash_t s) { * XXH3_generateSecret_fromSeed(secret, seed); @@ -1682,15 +1936,26 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * } * }; * @endcode - * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes - * @param seed The seed to seed the state. */ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed); /*! - * These variants generate hash values using either - * @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) - * or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX). + * @brief Maximum size of "short" key in bytes. + */ +#define XXH3_MIDSIZE_MAX 240 + +/*! + * @brief Calculates 64/128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * These variants generate hash values using either: + * - @p seed for "short" keys (< @ref XXH3_MIDSIZE_MAX = 240 bytes) + * - @p secret for "large" keys (>= @ref XXH3_MIDSIZE_MAX). * * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. * `_withSeed()` has to generate the secret on the fly for "large" keys. @@ -1717,22 +1982,71 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The memory segment to be hashed, at least @p len bytes in size. + * @param length The length of @p data, in bytes. + * @param secret The secret used to alter hash result predictably. + * @param secretSize The length of @p secret, in bytes (must be >= XXH3_SECRET_SIZE_MIN) + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(): contract is the same. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #ifndef XXH_NO_STREAM -/*! @copydoc XXH3_64bits_withSecretandSeed() */ +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + * + * Note: there was a bug in an earlier version of this function (<= v0.8.2) + * that would make it generate an incorrect hash value + * when @p seed == 0 and @p length < XXH3_MIDSIZE_MAX + * and @p secret is different from XXH3_generateSecret_fromSeed(). + * As stated in the contract, the correct hash result must be + * the same as XXH3_128bits_withSeed() when @p length <= XXH3_MIDSIZE_MAX. + * Results generated by this older version are wrong, hence not comparable. + */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #endif /* !XXH_NO_STREAM */ #endif /* !XXH_NO_XXH3 */ @@ -2100,15 +2414,15 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if XXH_NO_INLINE_HINTS /* disable inlining hints */ # if defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __attribute__((unused)) +# define XXH_FORCE_INLINE static __attribute__((__unused__)) # else # define XXH_FORCE_INLINE static # endif # define XXH_NO_INLINE static /* enable inlining hints */ #elif defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) -# define XXH_NO_INLINE static __attribute__((noinline)) +# define XXH_FORCE_INLINE static __inline__ __attribute__((__always_inline__, __unused__)) +# define XXH_NO_INLINE static __attribute__((__noinline__)) #elif defined(_MSC_VER) /* Visual Studio */ # define XXH_FORCE_INLINE static __forceinline # define XXH_NO_INLINE static __declspec(noinline) @@ -2121,12 +2435,34 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) # define XXH_NO_INLINE static #endif +#if defined(XXH_INLINE_ALL) +# define XXH_STATIC XXH_FORCE_INLINE +#else +# define XXH_STATIC static +#endif + #if XXH3_INLINE_SECRET # define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE #else # define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE #endif +#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ +# define XXH_RESTRICT /* disable */ +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined (__clang__)) \ + || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ + || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) +/* + * There are a LOT more compilers that recognize __restrict but this + * covers the major ones. + */ +# define XXH_RESTRICT __restrict +#else +# define XXH_RESTRICT /* disable */ +#endif /* ************************************* * Debug @@ -2206,10 +2542,14 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t xxh_u8; +# ifdef _AIX +# include +# else +# include +# endif + typedef uint8_t xxh_u8; #else - typedef unsigned char xxh_u8; + typedef unsigned char xxh_u8; #endif typedef XXH32_hash_t xxh_u32; @@ -2295,11 +2635,11 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; +typedef union { xxh_u32 u32; } __attribute__((__packed__)) unalign; #endif static xxh_u32 XXH_read32(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u32 xxh_unalign32; + typedef __attribute__((__aligned__(1))) xxh_u32 xxh_unalign32; return *((const xxh_unalign32*)ptr); } @@ -2445,6 +2785,9 @@ static int XXH_isLittleEndian(void) && XXH_HAS_BUILTIN(__builtin_rotateleft64) # define XXH_rotl32 __builtin_rotateleft32 # define XXH_rotl64 __builtin_rotateleft64 +#elif XXH_HAS_BUILTIN(__builtin_stdc_rotate_left) +# define XXH_rotl32 __builtin_stdc_rotate_left +# define XXH_rotl64 __builtin_stdc_rotate_left /* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ #elif defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) @@ -2590,7 +2933,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) #if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) /* * UGLY HACK: - * A compiler fence is the only thing that prevents GCC and Clang from + * A compiler fence is used to prevent GCC and Clang from * autovectorizing the XXH32 loop (pragmas and attributes don't work for some * reason) without globally disabling SSE4.1. * @@ -2651,6 +2994,61 @@ static xxh_u32 XXH32_avalanche(xxh_u32 hash) #define XXH_get32bits(p) XXH_readLE32_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH32(). + */ +XXH_FORCE_INLINE void +XXH32_initAccs(xxh_u32 *acc, xxh_u32 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + acc[1] = seed + XXH_PRIME32_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME32_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH32(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH32_consumeLong( + xxh_u32 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 15; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 16); + do { + acc[0] = XXH32_round(acc[0], XXH_get32bits(input)); input += 4; + acc[1] = XXH32_round(acc[1], XXH_get32bits(input)); input += 4; + acc[2] = XXH32_round(acc[2], XXH_get32bits(input)); input += 4; + acc[3] = XXH32_round(acc[3], XXH_get32bits(input)); input += 4; + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH32() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u32 +XXH32_mergeAccs(const xxh_u32 *acc) +{ + XXH_ASSERT(acc != NULL); + return XXH_rotl32(acc[0], 1) + XXH_rotl32(acc[1], 7) + + XXH_rotl32(acc[2], 12) + XXH_rotl32(acc[3], 18); +} + /*! * @internal * @brief Processes the last 0-15 bytes of @p ptr. @@ -2763,22 +3161,12 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment if (input==NULL) XXH_ASSERT(len == 0); if (len>=16) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 15; - xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - xxh_u32 v2 = seed + XXH_PRIME32_2; - xxh_u32 v3 = seed + 0; - xxh_u32 v4 = seed - XXH_PRIME32_1; + xxh_u32 acc[4]; + XXH32_initAccs(acc, seed); - do { - v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; - v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; - v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; - v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; - } while (input < limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) - + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + input = XXH32_consumeLong(acc, input, len, align); + + h32 = XXH32_mergeAccs(acc); } else { h32 = seed + XXH_PRIME32_5; } @@ -2834,10 +3222,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s { XXH_ASSERT(statePtr != NULL); memset(statePtr, 0, sizeof(*statePtr)); - statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - statePtr->v[1] = seed + XXH_PRIME32_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME32_1; + XXH32_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -2851,45 +3236,37 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len) return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len_32 += (XXH32_hash_t)len; + state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); - state->total_len_32 += (XXH32_hash_t)len; - state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); + XXH_ASSERT(state->bufferedSize < sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); - state->memsize += (XXH32_hash_t)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const xxh_u32* p32 = state->mem32; - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32)); - } - p += 16-state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer: complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* then process one round */ + (void)XXH32_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p <= bEnd-16) { - const xxh_u8* const limit = bEnd - 16; - - do { - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH32_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -2903,36 +3280,20 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) xxh_u32 h32; if (state->large_len) { - h32 = XXH_rotl32(state->v[0], 1) - + XXH_rotl32(state->v[1], 7) - + XXH_rotl32(state->v[2], 12) - + XXH_rotl32(state->v[3], 18); + h32 = XXH32_mergeAccs(state->acc); } else { - h32 = state->v[2] /* == seed */ + XXH_PRIME32_5; + h32 = state->acc[2] /* == seed */ + XXH_PRIME32_5; } h32 += state->total_len_32; - return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); + return XXH32_finalize(h32, state->buffer, state->bufferedSize, XXH_aligned); } #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/*! - * @ingroup XXH32_family - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * - * The canonical representation uses big endian convention, the same convention - * as human-readable numbers (large digits first). - * - * This way, hash values can be written into a file or buffer, remaining - * comparable across different systems. - * - * The following functions allow transformation of hash values to and from their - * canonical format. - */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); @@ -2987,11 +3348,11 @@ static xxh_u64 XXH_read64(const void* memPtr) * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; +typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((__packed__)) unalign64; #endif static xxh_u64 XXH_read64(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u64 xxh_unalign64; + typedef __attribute__((__aligned__(1))) xxh_u64 xxh_unalign64; return *((const xxh_unalign64*)ptr); } @@ -3110,6 +3471,23 @@ static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) acc += input * XXH_PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= XXH_PRIME64_1; +#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * DISABLE AUTOVECTORIZATION: + * A compiler fence is used to prevent GCC and Clang from + * autovectorizing the XXH64 loop (pragmas and attributes don't work for some + * reason) without globally disabling AVX512. + * + * Autovectorization of XXH64 tends to be detrimental, + * though the exact outcome may change depending on exact cpu and compiler version. + * For information, it has been reported as detrimental for Skylake-X, + * but possibly beneficial for Zen4. + * + * The default is to disable auto-vectorization, + * but you can select to enable it instead using `XXH_ENABLE_AUTOVECTORIZE` build variable. + */ + XXH_COMPILER_GUARD(acc); +#endif return acc; } @@ -3135,6 +3513,85 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) #define XXH_get64bits(p) XXH_readLE64_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH64(). + */ +XXH_FORCE_INLINE void +XXH64_initAccs(xxh_u64 *acc, xxh_u64 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + acc[1] = seed + XXH_PRIME64_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME64_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH64(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH64_consumeLong( + xxh_u64 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 31; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 32); + do { + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + acc[i] = XXH64_round(acc[i], XXH_get64bits(input)); + input += 8; + } + } else { + acc[0] = XXH64_round(acc[0], XXH_get64bits(input)); input += 8; + acc[1] = XXH64_round(acc[1], XXH_get64bits(input)); input += 8; + acc[2] = XXH64_round(acc[2], XXH_get64bits(input)); input += 8; + acc[3] = XXH64_round(acc[3], XXH_get64bits(input)); input += 8; + } + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH64() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u64 +XXH64_mergeAccs(const xxh_u64 *acc) +{ + XXH_ASSERT(acc != NULL); + { + xxh_u64 h64 = XXH_rotl64(acc[0], 1) + XXH_rotl64(acc[1], 7) + + XXH_rotl64(acc[2], 12) + XXH_rotl64(acc[3], 18); + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + h64 = XXH64_mergeRound(h64, acc[i]); + } + } else { + h64 = XXH64_mergeRound(h64, acc[0]); + h64 = XXH64_mergeRound(h64, acc[1]); + h64 = XXH64_mergeRound(h64, acc[2]); + h64 = XXH64_mergeRound(h64, acc[3]); + } + return h64; + } +} + /*! * @internal * @brief Processes the last 0-31 bytes of @p ptr. @@ -3150,7 +3607,7 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) * @return The finalized hash * @see XXH32_finalize(). */ -static XXH_PUREF xxh_u64 +XXH_STATIC XXH_PUREF xxh_u64 XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { if (ptr==NULL) XXH_ASSERT(len == 0); @@ -3200,27 +3657,13 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment xxh_u64 h64; if (input==NULL) XXH_ASSERT(len == 0); - if (len>=32) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 31; - xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - xxh_u64 v2 = seed + XXH_PRIME64_2; - xxh_u64 v3 = seed + 0; - xxh_u64 v4 = seed - XXH_PRIME64_1; + if (len>=32) { /* Process a large block of data */ + xxh_u64 acc[4]; + XXH64_initAccs(acc, seed); - do { - v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; - v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; - v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; - v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; - } while (inputv[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - statePtr->v[1] = seed + XXH_PRIME64_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME64_1; + XXH64_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -3292,42 +3732,36 @@ XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len += len; - state->total_len += len; + XXH_ASSERT(state->bufferedSize <= sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 32) { /* fill in tmp buffer */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); - state->memsize += (xxh_u32)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0)); - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1)); - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2)); - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3)); - p += 32 - state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer => complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* and process one round */ + (void)XXH64_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p+32 <= bEnd) { - const xxh_u8* const limit = bEnd - 32; - - do { - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8; - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8; - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8; - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH64_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -3341,18 +3775,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state xxh_u64 h64; if (state->total_len >= 32) { - h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18); - h64 = XXH64_mergeRound(h64, state->v[0]); - h64 = XXH64_mergeRound(h64, state->v[1]); - h64 = XXH64_mergeRound(h64, state->v[2]); - h64 = XXH64_mergeRound(h64, state->v[3]); + h64 = XXH64_mergeAccs(state->acc); } else { - h64 = state->v[2] /*seed*/ + XXH_PRIME64_5; + h64 = state->acc[2] /*seed*/ + XXH_PRIME64_5; } h64 += (xxh_u64) state->total_len; - return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); + return XXH64_finalize(h64, state->buffer, (size_t)state->total_len, XXH_aligned); } #endif /* !XXH_NO_STREAM */ @@ -3387,22 +3817,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can /* === Compiler specifics === */ -#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ -# define XXH_RESTRICT /* disable */ -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ -# define XXH_RESTRICT restrict -#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ - || (defined (__clang__)) \ - || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ - || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) -/* - * There are a LOT more compilers that recognize __restrict but this - * covers the major ones. - */ -# define XXH_RESTRICT __restrict -#else -# define XXH_RESTRICT /* disable */ -#endif #if (defined(__GNUC__) && (__GNUC__ >= 3)) \ || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ @@ -3416,7 +3830,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can #ifndef XXH_HAS_INCLUDE # ifdef __has_include -# define XXH_HAS_INCLUDE(x) __has_include(x) +/* + * Not defined as XXH_HAS_INCLUDE(x) (function-like) because + * this causes segfaults in Apple Clang 4.2 (on Mac OS X 10.7 Lion) + */ +# define XXH_HAS_INCLUDE __has_include # else # define XXH_HAS_INCLUDE(x) 0 # endif @@ -3437,6 +3855,8 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can # include # elif defined(__SSE2__) # include +# elif defined(__loongarch_sx) +# include # endif #endif @@ -3533,33 +3953,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can * implementation. */ # define XXH_VECTOR XXH_SCALAR -/*! - * @ingroup tuning - * @brief Possible values for @ref XXH_VECTOR. - * - * Note that these are actually implemented as macros. - * - * If this is not defined, it is detected automatically. - * internal macro XXH_X86DISPATCH overrides this. - */ -enum XXH_VECTOR_TYPE /* fake enum */ { - XXH_SCALAR = 0, /*!< Portable scalar version */ - XXH_SSE2 = 1, /*!< - * SSE2 for Pentium 4, Opteron, all x86_64. - * - * @note SSE2 is also guaranteed on Windows 10, macOS, and - * Android x86. - */ - XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ - XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ - XXH_NEON = 4, /*!< - * NEON for most ARMv7-A, all AArch64, and WASM SIMD128 - * via the SIMDeverywhere polyfill provided with the - * Emscripten SDK. - */ - XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ - XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */ -}; /*! * @ingroup tuning * @brief Selects the minimum alignment for XXH3's accumulators. @@ -3574,13 +3967,6 @@ enum XXH_VECTOR_TYPE /* fake enum */ { /* Actual definition */ #ifndef XXH_DOXYGEN -# define XXH_SCALAR 0 -# define XXH_SSE2 1 -# define XXH_AVX2 2 -# define XXH_AVX512 3 -# define XXH_NEON 4 -# define XXH_VSX 5 -# define XXH_SVE 6 #endif #ifndef XXH_VECTOR /* can be defined on command line */ @@ -3605,6 +3991,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { || (defined(__s390x__) && defined(__VEC__)) \ && defined(__GNUC__) /* TODO: IBM XL */ # define XXH_VECTOR XXH_VSX +# elif defined(__loongarch_sx) +# define XXH_VECTOR XXH_LSX # else # define XXH_VECTOR XXH_SCALAR # endif @@ -3642,6 +4030,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_ACC_ALIGN 64 # elif XXH_VECTOR == XXH_SVE /* sve */ # define XXH_ACC_ALIGN 64 +# elif XXH_VECTOR == XXH_LSX /* lsx */ +# define XXH_ACC_ALIGN 64 # endif #endif @@ -3655,7 +4045,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ { #endif #if defined(__GNUC__) || defined(__clang__) -# define XXH_ALIASING __attribute__((may_alias)) +# define XXH_ALIASING __attribute__((__may_alias__)) #else # define XXH_ALIASING /* nothing */ #endif @@ -4408,8 +4798,6 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, } } -#define XXH3_MIDSIZE_MAX 240 - XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -5281,6 +5669,71 @@ XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc, #endif +#if (XXH_VECTOR == XXH_LSX) +#define _LSX_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_lsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i *) acc; + const __m128i* const xinput = (const __m128i *) input; + const __m128i* const xsecret = (const __m128i *) secret; + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = __lsx_vld(xinput + i, 0); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + // __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = __lsx_vmulwev_d_wu(data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = __lsx_vshuf4i_w(data_vec, _LSX_SHUFFLE(1, 0, 3, 2)); + __m128i const sum = __lsx_vadd_d(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = __lsx_vadd_d(product, sum); + } + } +} +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lsx) + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_lsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i*) acc; + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = __lsx_vreplgr2vr_w((int)XXH_PRIME32_1); + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = __lsx_vsrli_d(acc_vec, 47); + __m128i const data_vec = __lsx_vxor_v(acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = __lsx_vsrli_d(data_key, 32); + __m128i const prod_lo = __lsx_vmulwev_d_wu(data_key, prime32); + __m128i const prod_hi = __lsx_vmulwev_d_wu(data_key_hi, prime32); + xacc[i] = __lsx_vadd_d(prod_lo, __lsx_vslli_d(prod_hi, 32)); + } + } +} + +#endif + /* scalar variants - universal */ #if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) @@ -5511,6 +5964,12 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#elif (XXH_VECTOR == XXH_LSX) +#define XXH3_accumulate_512 XXH3_accumulate_512_lsx +#define XXH3_accumulate XXH3_accumulate_lsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_lsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + #else /* scalar */ #define XXH3_accumulate_512 XXH3_accumulate_512_scalar @@ -5566,7 +6025,7 @@ XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret acc[1] ^ XXH_readLE64(secret+8) ); } -static XXH64_hash_t +static XXH_PUREF XXH64_hash_t XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) { xxh_u64 result64 = start; @@ -5593,6 +6052,15 @@ XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secre return XXH3_avalanche(result64); } +/* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + +static XXH_PUREF XXH64_hash_t +XXH3_finalizeLong_64b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 len) +{ + return XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, len * XXH_PRIME64_1); +} + #define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } @@ -5608,10 +6076,8 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); - /* do not align on 8, so that the secret is different from the accumulator */ -#define XXH_SECRET_MERGEACCS_START 11 XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, (const xxh_u8*)secret, (xxh_u64)len); } /* @@ -5747,7 +6213,7 @@ XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH /* === XXH3 streaming === */ #ifndef XXH_NO_STREAM /* - * Malloc's a pointer that is always aligned to align. + * Malloc's a pointer that is always aligned to @align. * * This must be freed with `XXH_alignedFree()`. * @@ -5815,8 +6281,12 @@ static void XXH_alignedFree(void* p) /*! * @brief Allocate an @ref XXH3_state_t. * - * Must be freed with XXH3_freeState(). - * @return An allocated XXH3_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH3_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH3_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) { @@ -5830,9 +6300,13 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) /*! * @brief Frees an @ref XXH3_state_t. * - * Must be allocated with XXH3_createState(). * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note Must be allocated with XXH3_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) { @@ -6111,9 +6585,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* if (state->totalLen > XXH3_MIDSIZE_MAX) { XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); - return XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, secret, (xxh_u64)state->totalLen); } /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ if (state->useSeed) @@ -6405,6 +6877,17 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, } } +static XXH_PUREF XXH128_hash_t +XXH3_finalizeLong_128b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, xxh_u64 len) +{ + XXH128_hash_t h128; + h128.low64 = XXH3_finalizeLong_64b(acc, secret, len); + h128.high64 = XXH3_mergeAccs(acc, secret + secretSize + - XXH_STRIPE_LEN - XXH_SECRET_MERGEACCS_START, + ~(len * XXH_PRIME64_2)); + return h128; +} + XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -6418,16 +6901,7 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)len * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + secretSize - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)len * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, secretSize, (xxh_u64)len); } /* @@ -6610,19 +7084,10 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_ XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + state->secretLimit + XXH_STRIPE_LEN - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, state->secretLimit + XXH_STRIPE_LEN, (xxh_u64)state->totalLen); } /* len <= XXH3_MIDSIZE_MAX : short code */ - if (state->seed) + if (state->useSeed) return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); ===================================== testsuite/tests/core-to-stg/T25284/A.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fspec-eval-dictfun #-} +module A (testX) where + +import qualified Cls + +-- this creates the big dictionary strictly because of speculative evaluation +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/B.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fno-spec-eval-dictfun #-} +module B (testX) where + +import qualified Cls + +-- this creates the big dictionary lazily +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/Cls.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE UndecidableInstances #-} + +module Cls where + +class HasConst a where constVal :: a + +instance Cls.HasConst Word where constVal = 123 + +instance Cls.HasConst Int where constVal = 456 + +-- this class has a big dictionary +class HasConst10 a where + constA :: a + constInt1 :: a -> Int + constInt1 _ = 1 + constInt2 :: a -> Int + constInt2 _ = 2 + constInt3 :: a -> Int + constInt3 _ = 3 + constInt4 :: a -> Int + constInt4 _ = 4 + constInt5 :: a -> Int + constInt5 _ = 5 + constInt6 :: a -> Int + constInt6 _ = 6 + constInt7 :: a -> Int + constInt7 _ = 7 + constInt8 :: a -> Int + constInt8 _ = 8 + constInt9 :: a -> Int + constInt9 _ = 9 + +instance HasConst a => HasConst10 a where + constA = constVal + +-- this doesn't use the big dictionary most of the time +printConst :: forall a. (Show a, HasConst10 a) + => a -> Int -> IO () +printConst x 5000 = print @a constA >> print (constInt8 x) +printConst _ _ = pure () ===================================== testsuite/tests/core-to-stg/T25284/Main.hs ===================================== @@ -0,0 +1,57 @@ +{- + + This tests that speculative evaluation for dictionary functions works as + expected, with a large dictionary that goes unused. + + - Module A: dictfun speculative evaluation enabled + - Module B: dictfun speculative evaluation disabled + + Speculative evaluation causes the unused large dictionary to be allocated + strictly in module A, so we expect more allocations than in module B. + + -} +module Main where + +import qualified A +import qualified B +import qualified Cls + +import Data.Word +import System.Mem (performGC) +import GHC.Stats +import Control.Monad + +{-# NOINLINE getAllocated #-} +getAllocated :: IO Word64 +getAllocated = do + performGC + allocated_bytes <$> getRTSStats + +main :: IO () +main = do + -- warm up (just in case) + _ <- testMain A.testX + _ <- testMain B.testX + + -- for real + a_alloc <- testMain A.testX + b_alloc <- testMain B.testX + + -- expect B to allocate less than A + let alloc_ratio :: Double + alloc_ratio = fromIntegral b_alloc / fromIntegral a_alloc + putStrLn ("expected alloc: " ++ show (alloc_ratio < 0.7)) + +iter :: (Int -> IO ()) -> Int -> Int -> IO () +iter m !i !j + | i < j = m i >> iter m (i+1) j + | otherwise = pure () + +{-# NOINLINE testMain #-} +testMain :: (forall b. (Show b, Cls.HasConst b) => b -> Int -> IO ()) + -> IO Word64 +testMain f = do + alloc0 <- getAllocated + iter (\i -> f (0::Int) i >> f (0::Word) i) 1 100000 + alloc1 <- getAllocated + pure (alloc1 - alloc0) ===================================== testsuite/tests/core-to-stg/T25284/T25284.stdout ===================================== @@ -0,0 +1,17 @@ +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +expected alloc: True ===================================== testsuite/tests/core-to-stg/T25284/all.T ===================================== @@ -0,0 +1,6 @@ +test('T25284', + [js_skip, # allocation counters aren't available on the JS backend + extra_files(['Main.hs', 'A.hs', 'B.hs', 'Cls.hs']), + extra_run_opts('+RTS -T -RTS')], + multimod_compile_and_run, + ['Main', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a0d4dd425246cb967a7ce00b45da91995313e3f2...956f841060f900e374f60bb7d78d6b862e4593fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a0d4dd425246cb967a7ce00b45da91995313e3f2...956f841060f900e374f60bb7d78d6b862e4593fd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 14:53:39 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 08 Jan 2025 09:53:39 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update Note [Kind inference for data family instances] Message-ID: <677e9173eb6f_d8376bcebc297e@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: c25bac01 by Patrick at 2025-01-08T22:51:56+08:00 update Note [Kind inference for data family instances] - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1196,28 +1196,43 @@ constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we take -the /data constructor/ declarations into accound for Haskell-98 style -data-instance and newtype-instance declarations. But for general -GADT-style data-instance declarations, we are looking only at the data -instance /header/. +DESIGN CHOICE: in a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for + * Haskell-98 style data instance declarations + * All newtype instance declarations + For H-98 style declarations there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from H-98. -Observations: -* We treat Haskell-98 style data-instance decls differently, by taking - the data constructors into account, since there are no GADT - issues. +* We /ignore/ the data constructors for + * GADT-style data instance declarations + Here the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we can take the - data constructors into account. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. +Observations: * With UnliftedNewtypes or UnliftedDatatypes, looking at the data - constructors is necessary to infer the kind of result type for certain - cases. Otherwise addtional kind signatures are required(see #25611). - - -We are balancing between well rounded kind inference and the implementation -simplicity. See #25611, #18891 and !4419 for more discussion of this issue. + constructors is necessary to infer the kind of result type for + certain cases. Otherwise addtional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors. + * Without UnliftedNewtypes, it is accepted since `Fix f` is defaulted + to Type. + * But with UnliftedNewtypes, `Fix f` is defaulted to `TYPE a` where + a is not scoped over the data constructor. Then header `Fix f :: TYPE a` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence we need to look at the data constructor to infer `Fix f :: TYPE` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well rounded kind inference +and the implementation simplicity. See #25611, #18891 and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c25bac01f724132dd8a96aa44837ad18fa2e5484 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c25bac01f724132dd8a96aa44837ad18fa2e5484 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 15:22:59 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Wed, 08 Jan 2025 10:22:59 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add HsConFieldSpec Message-ID: <677e9853614b5_d837674da886718@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: a3b685b8 by Sjoerd Visscher at 2025-01-08T16:22:31+01:00 Add HsConFieldSpec - - - - - 24 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - utils/check-exact/ExactPrint.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/Rename.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -881,11 +881,11 @@ pprConDecl (ConDeclH98 { con_name = L _ con where -- In ppr_details: let's not print the multiplicities (they are always 1, by -- definition) as they do not appear in an actual declaration. - ppr_details (InfixCon t1 t2) = hsep [ppr (hsScaledThing t1), + ppr_details (InfixCon t1 t2) = hsep [pprHsConFieldSpecNoMult t1, pprInfixOcc con, - ppr (hsScaledThing t2)] + pprHsConFieldSpecNoMult t2] ppr_details (PrefixCon _ tys) = hsep (pprPrefixOcc con - : map (pprHsType . unLoc . hsScaledThing) tys) + : map pprHsConFieldSpecNoMult tys) ppr_details (RecCon fields) = pprPrefixOcc con <+> pprConDeclFields (unLoc fields) @@ -896,7 +896,7 @@ pprConDecl (ConDeclGADT { con_names = cons, con_bndrs = L _ outer_bndrs <+> (sep [pprHsOuterSigTyVarBndrs outer_bndrs <+> pprLHsContext mcxt, sep (ppr_args args ++ [ppr res_ty]) ]) where - ppr_args (PrefixConGADT _ args) = map (\(HsScaled arr t) -> ppr t <+> ppr_arr arr) args + ppr_args (PrefixConGADT _ args) = map (pprHsConFieldSpecWith (\arr tyDoc -> tyDoc <+> ppr_arr arr)) args ppr_args (RecConGADT _ fields) = [pprConDeclFields (unLoc fields) <+> arrow] -- Display linear arrows as unrestricted with -XNoLinearTypes ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -535,7 +535,7 @@ deriving instance Data (HsTyLit GhcPs) deriving instance Data (HsTyLit GhcRn) deriving instance Data (HsTyLit GhcTc) --- deriving instance (Data mult, DataIdLR p p) => Data (HsArrowOf mult p) +-- deriving instance (Data mult, DataIdLR p p, Typeable on) => Data (HsMultAnnOn on mult p) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsType GhcPs)) GhcPs) deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsType GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcRn)) GhcRn) @@ -545,7 +545,7 @@ deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsExpr deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcTc)) GhcTc) --- deriving instance (DataIdLR p p) => Data (HsScaled p a) +-- deriving instance (DataIdLR p p, Typeable on) => Data (HsScaled on p a) deriving instance Data thing => Data (HsScaled OnArrow GhcPs thing) deriving instance Data thing => Data (HsScaled OnRecField GhcPs thing) deriving instance (Data thing, Typeable on) => Data (HsScaled on GhcRn thing) @@ -561,6 +561,12 @@ deriving instance Data (ConDeclField GhcPs) deriving instance Data (ConDeclField GhcRn) deriving instance Data (ConDeclField GhcTc) +-- deriving instance (DataIdLR p p, Typeable on) => Data (HsConFieldSpec on p) +deriving instance Data (HsConFieldSpec OnArrow GhcPs) +deriving instance Data (HsConFieldSpec OnRecField GhcPs) +deriving instance Typeable on => Data (HsConFieldSpec on GhcRn) +deriving instance Typeable on => Data (HsConFieldSpec on GhcTc) + -- deriving instance (DataId p) => Data (FieldOcc p) deriving instance Data (FieldOcc GhcPs) deriving instance Data (FieldOcc GhcRn) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -25,11 +25,11 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( Mult, HsScaled(..), - hsMultIsLinear, hsScaledThing, hsScaledToHsTypes, + hsMultIsLinear, hsScaledThing, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, EpLinearArrow(..), - hsLinear, hsNoMultAnn, isUnrestricted, + hsNoMultAnn, isUnrestricted, pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, @@ -61,6 +61,8 @@ module GHC.Hs.Type ( ConDeclField(..), LConDeclField, pprConDeclFields, HsConDetails(..), noTypeArgs, + HsConFieldSpec(..), pprHsConFieldSpecWith, pprHsConFieldSpecNoMult, + hsPlainTypeField, hsConFieldSpecToHsTypes, FieldOcc(..), LFieldOcc, mkFieldOcc, fieldOccRdrName, fieldOccLRdrName, @@ -541,14 +543,8 @@ type instance XExplicitMult _ _ GhcTc = NoExtField type instance XXMultAnnOn _ _ (GhcPass _) = DataConCantHappen -hsLinear :: a -> HsScaled OnArrow GhcPs a -hsLinear = HsScaled (HsLinearAnn noAnn) - -hsNoMultAnn :: a -> HsScaled OnRecField GhcPs a -hsNoMultAnn = HsScaled (HsUnannotated HsUnannOne noAnn) - -hsScaledToHsTypes :: HsScaled on GhcRn (LHsType GhcRn) -> [LHsType GhcRn] -hsScaledToHsTypes (HsScaled arr t) = [multAnnToHsType arr, t] +hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => HsMultAnnOn on (LHsType GhcPs) GhcPs +hsNoMultAnn = HsUnannotated HsUnannOne noAnn isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (multAnnToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName @@ -582,16 +578,17 @@ type instance XXConDeclField (GhcPass _) = DataConCantHappen instance OutputableBndrId p => Outputable (ConDeclField (GhcPass p)) where - ppr (ConDeclField _ fld_n (HsScaled fld_mult fld_ty) _) = ppr_names fld_n <+> ppr_mult <+> ppr fld_ty + ppr (ConDeclField _ fld_n cfs _) = ppr_names fld_n <+> pprHsConFieldSpecWith ppr_mult cfs where ppr_names :: [LFieldOcc (GhcPass p)] -> SDoc ppr_names [n] = pprPrefixOcc n ppr_names ns = sep (punctuate comma (map pprPrefixOcc ns)) - ppr_mult = case fld_mult of - HsUnannotated _ _ -> dcolon - HsLinearAnn _ -> text "%1" <+> dcolon - HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon + ppr_mult :: HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc + ppr_mult mult tyDoc = case mult of + HsUnannotated _ _ -> dcolon <+> tyDoc + HsLinearAnn _ -> text "%1" <+> dcolon <+> tyDoc + HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon <+> tyDoc --------------------- hsWcScopedTvs :: LHsSigWcType GhcRn -> [Name] @@ -726,7 +723,7 @@ splitHsFunType :: LHsType (GhcPass p) -> ( ([EpToken "("], [EpToken ")"]) , EpAnnComments -- The locations of any parens and -- comments discarded - , [HsScaled OnArrow (GhcPass p) (LHsType (GhcPass p))], LHsType (GhcPass p)) + , [HsConFieldSpec OnArrow (GhcPass p)], LHsType (GhcPass p)) splitHsFunType ty = go ty where go (L l (HsParTy (op,cp) ty)) @@ -737,7 +734,7 @@ splitHsFunType ty = go ty go (L ll (HsFunTy _ mult x y)) | (anns, csy, args, res) <- splitHsFunType y - = (anns, csy S.<> epAnnComments ll, HsScaled mult x:args, res) + = (anns, csy S.<> epAnnComments ll, CFS NoSrcUnpack NoSrcStrict mult x:args, res) go other = (noAnn, emptyComments, [], other) @@ -1297,6 +1294,18 @@ instance (Outputable tyarg, Outputable arg, Outputable rec) ppr (RecCon rec) = text "RecCon:" <+> ppr rec ppr (InfixCon l r) = text "InfixCon:" <+> ppr [l, r] +pprHsConFieldSpecWith :: (OutputableBndrId p) => (HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc) -> HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecWith ppr_mult (CFS prag mark mult ty) = ppr_mult mult (ppr prag <+> ppr mark <> ppr ty) + +pprHsConFieldSpecNoMult :: (OutputableBndrId p) => HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecNoMult = pprHsConFieldSpecWith (\_ d -> d) + +hsPlainTypeField :: LHsType GhcPs -> HsConFieldSpec OnArrow GhcPs +hsPlainTypeField = CFS NoSrcUnpack NoSrcStrict (HsLinearAnn noAnn) + +hsConFieldSpecToHsTypes :: HsConFieldSpec on GhcRn -> [LHsType GhcRn] +hsConFieldSpecToHsTypes (CFS _ _ arr t) = [multAnnToHsType arr, t] + instance Outputable (XRecGhc (IdGhcP p)) => Outputable (FieldOcc (GhcPass p)) where ppr = ppr . foLabel ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -430,14 +430,14 @@ conArgDocs (ConDeclGADT{con_g_args = args, con_res_ty = res_ty}) = h98ConArgDocs :: HsConDeclH98Details GhcRn -> IntMap (HsDoc GhcRn) h98ConArgDocs con_args = case con_args of - PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args - InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (hsScaledThing arg1) - , unLoc (hsScaledThing arg2) ] + PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args + InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (cfs_type arg1) + , unLoc (cfs_type arg2) ] RecCon _ -> IM.empty gadtConArgDocs :: HsConDeclGADTDetails GhcRn -> HsType GhcRn -> IntMap (HsDoc GhcRn) gadtConArgDocs con_args res_ty = case con_args of - PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args ++ [res_ty] + PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args ++ [res_ty] RecConGADT _ _ -> con_arg_docs 1 [res_ty] con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn) ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -920,17 +920,13 @@ repSrcStrictness SrcLazy = rep2 sourceLazyName [] repSrcStrictness SrcStrict = rep2 sourceStrictName [] repSrcStrictness NoSrcStrict = rep2 noSourceStrictnessName [] -repBangTy :: LBangType GhcRn -> MetaM (Core (M TH.BangType)) -repBangTy ty = do - MkC u <- repSrcUnpackedness su' - MkC s <- repSrcStrictness ss' +repConFieldSpec :: HsConFieldSpec on GhcRn -> MetaM (Core (M TH.BangType)) +repConFieldSpec (CFS su ss _ ty') = do + MkC u <- repSrcUnpackedness su + MkC s <- repSrcStrictness ss MkC b <- rep2 bangName [u, s] MkC t <- repLTy ty' rep2 bangTypeName [b, t] - where - (su', ss', ty') = case unLoc ty of - HsBangTy _ (HsBang su ss) ty -> (su, ss, ty) - _ -> (NoSrcUnpack, NoSrcStrict, ty) ------------------------------------------------------- -- Deriving clauses @@ -2838,8 +2834,8 @@ repH98DataCon con details rep2 normalCName [unC con', unC arg_tys] InfixCon st1 st2 -> do verifyLinearFields [st1, st2] - arg1 <- repBangTy (hsScaledThing st1) - arg2 <- repBangTy (hsScaledThing st2) + arg1 <- repConFieldSpec st1 + arg2 <- repConFieldSpec st2 rep2 infixCName [unC arg1, unC con', unC arg2] RecCon ips -> do arg_vtys <- repRecConArgs ips @@ -2865,33 +2861,33 @@ repGadtDataCons cons details res_ty -- TH currently only supports linear constructors. -- We also accept the (->) arrow when -XLinearTypes is off, because this -- denotes a linear field. -verifyLinearFields :: [HsScaled on GhcRn (LHsType GhcRn)] -> MetaM () +verifyLinearFields :: [HsConFieldSpec on GhcRn] -> MetaM () verifyLinearFields ps = do linear <- lift $ xoptM LangExt.LinearTypes - let allGood = all (hsMultIsLinear linear) ps + let allGood = all (hsMultIsLinear linear . cfs_multiplicity) ps unless allGood $ notHandled ThNonLinearDataCon -- Desugar the arguments in a data constructor declared with prefix syntax. -repPrefixConArgs :: [HsScaled OnArrow GhcRn (LHsType GhcRn)] +repPrefixConArgs :: [HsConFieldSpec OnArrow GhcRn] -> MetaM (Core [M TH.BangType]) repPrefixConArgs ps = do verifyLinearFields ps - repListM bangTypeTyConName repBangTy (map hsScaledThing ps) + repListM bangTypeTyConName repConFieldSpec ps -- Desugar the arguments in a data constructor declared with record syntax. repRecConArgs :: LocatedL [LConDeclField GhcRn] -> MetaM (Core [M TH.VarBangType]) repRecConArgs lips = do let ips = map unLoc (unLoc lips) - verifyLinearFields (map cd_fld_type ips) + verifyLinearFields (map cd_fld_spec ips) args <- concatMapM rep_ip ips coreListM varBangTypeTyConName args where - rep_ip ip = mapM (rep_one_ip (hsScaledThing $ cd_fld_type ip)) (cd_fld_names ip) + rep_ip ip = mapM (rep_one_ip (cd_fld_spec ip)) (cd_fld_names ip) - rep_one_ip :: LBangType GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) + rep_one_ip :: HsConFieldSpec OnRecField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) rep_one_ip t n = do { MkC v <- lookupOcc (unLoc . foLabel $ unLoc n) - ; MkC ty <- repBangTy t + ; MkC ty <- repConFieldSpec t ; rep2 varBangTypeName [v,ty] } ------------ Types ------------------- ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1789,8 +1789,8 @@ instance ToHie (LocatedA (ConDecl GhcRn)) where PrefixCon _ xs -> scaled_args_scope xs InfixCon a b -> scaled_args_scope [a, b] RecCon x -> mkScope x - where scaled_args_scope :: [HsScaled on GhcRn (LHsType GhcRn)] -> Scope - scaled_args_scope = foldr combineScopes NoScope . map (mkScope . hsScaledThing) + where scaled_args_scope :: [HsConFieldSpec on GhcRn] -> Scope + scaled_args_scope = foldr combineScopes NoScope . map (mkScope . cfs_type) instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where toHie (L span decls) = concatM $ @@ -1798,6 +1798,9 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where , toHie decls ] +instance ToHie (HsConFieldSpec on GhcRn) where + toHie (CFS _ _ w t) = concatM [toHie (multAnnToHsType w), toHie t] + instance ToHie (TScoped (HsWildCardBndrs GhcRn (LocatedA (HsSigType GhcRn)))) where toHie (TS sc (HsWC names a)) = concatM $ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names @@ -2000,7 +2003,7 @@ instance HiePass p => ToHie (LocatedC [LocatedA (HsExpr (GhcPass p))]) where instance ToHie (LocatedA (ConDeclField GhcRn)) where toHie (L span field) = concatM $ makeNode field (locA span) : case field of ConDeclField _ fields typ doc -> - [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ hsScaledThing typ)) fields + [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ cfs_type typ)) fields , toHie typ , toHie doc ] ===================================== compiler/GHC/Parser.y ===================================== @@ -2598,7 +2598,7 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (HsScaled (HsUnannotated HsUnannOne (epUniTok $2)) $3) + (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3) Nothing))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -72,6 +72,7 @@ module GHC.Parser.PostProcess ( mkMultTy, mkMultAnn, mkMultField, + mkConFieldSpec, -- Token location mkTokenLocation, @@ -2337,11 +2338,11 @@ dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) -- Normal prefix constructor, e.g. data T = MkT A B C dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) - = PrefixCon noTypeArgs (map hsLinear (toList flds)) + = PrefixCon noTypeArgs (map hsPlainTypeField (toList flds)) -- Infix constructor, e.g. data T = Int :! Bool dataConBuilderDetails (L (EpAnn _ _ csl) (InfixDataConBuilder (L (EpAnn anc ann csll) lhs) _ rhs)) - = InfixCon (hsLinear (L (EpAnn anc ann (csl Semi.<> csll)) lhs)) (hsLinear rhs) + = InfixCon (hsPlainTypeField (L (EpAnn anc ann (csl Semi.<> csll)) lhs)) (hsPlainTypeField rhs) instance DisambTD DataConBuilder where @@ -2409,7 +2410,7 @@ checkNotPromotedDataCon IsPromoted (L l name) = mkUnboxedSumCon :: LHsType GhcPs -> ConTag -> Arity -> (LocatedN RdrName, HsConDeclH98Details GhcPs) mkUnboxedSumCon t tag arity = - (noLocA (getRdrName (sumDataCon tag arity)), PrefixCon noTypeArgs [hsLinear t]) + (noLocA (getRdrName (sumDataCon tag arity)), PrefixCon noTypeArgs [hsPlainTypeField t]) {- Note [Ambiguous syntactic categories] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3519,15 +3520,19 @@ mkMultAnn pct t@(L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) pct1 = epTokenWidenR pct (locA (getLoc t)) mkMultAnn pct t = HsMultAnn pct t -mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsScaled OnRecField GhcPs (LBangType GhcPs) +mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnRecField GhcPs mkMultField pct (L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) col t -- See #18888 for the use of (SourceText "1") above - = HsScaled (HsLinearAnn (pct1, col)) t + = mkConFieldSpec (HsLinearAnn (pct1, col)) t where -- The location of "%" combined with the location of "1". pct1 :: EpToken "%1" pct1 = epTokenWidenR pct (locA (getLoc t)) -mkMultField pct mult col t = HsScaled (HsExplicitMult (pct, col) mult) t +mkMultField pct mult col t = mkConFieldSpec (HsExplicitMult (pct, col) mult) t + +mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs +mkConFieldSpec mult (L _ (HsBangTy _ (HsBang unp str) t)) = CFS unp str mult t +mkConFieldSpec mult t = CFS NoSrcUnpack NoSrcStrict mult t mkTokenLocation :: SrcSpan -> TokenLocation mkTokenLocation (UnhelpfulSpan _) = NoTokenLoc ===================================== compiler/GHC/Parser/PostProcess/Haddock.hs ===================================== @@ -788,12 +788,12 @@ getConDoc l = extendHdkA l $ liftHdkA $ getPrevNextDoc l -- Add documentation comment to a data constructor field. -- Used for PrefixCon and InfixCon. addHaddockConDeclFieldTy - :: HsScaled on GhcPs (LHsType GhcPs) - -> HdkA (HsScaled on GhcPs (LHsType GhcPs)) -addHaddockConDeclFieldTy (HsScaled mult (L l t)) = + :: HsConFieldSpec on GhcPs + -> HdkA (HsConFieldSpec on GhcPs) +addHaddockConDeclFieldTy (CFS unpack strict mult (L l t)) = extendHdkA (locA l) $ liftHdkA $ do mDoc <- getPrevNextDoc (locA l) - return (HsScaled mult (mkLHsDocTy (L l t) mDoc)) + return (CFS unpack strict mult (mkLHsDocTy (L l t) mDoc)) -- Add documentation comment to a data constructor field. -- Used for RecCon. @@ -909,6 +909,9 @@ We implement this in two steps: instance HasHaddock a => HasHaddock (HsScaled on GhcPs a) where addHaddock (HsScaled mult a) = HsScaled mult <$> addHaddock a +instance HasHaddock (HsConFieldSpec on GhcPs) where + addHaddock (CFS unp str mult a) = CFS unp str mult <$> addHaddock a + instance HasHaddock a => HasHaddock (HsWildCardBndrs GhcPs a) where addHaddock (HsWC _ t) = HsWC noExtField <$> addHaddock t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Rename.HsType ( lookupField, mkHsOpTyRn, rnLTyVar, - rnScaledLHsType, + rnHsConFieldSpec, -- Precence related stuff NegationHandling(..), @@ -450,16 +450,16 @@ rnLHsType ctxt ty = rnLHsTyKi (mkTyKiEnv ctxt TypeLevel RnTypeBody) ty rnLHsTypes :: HsDocContext -> [LHsType GhcPs] -> RnM ([LHsType GhcRn], FreeVars) rnLHsTypes doc tys = mapFvRn (rnLHsType doc) tys -rnScaledLHsType :: HsDocContext -> HsScaled on GhcPs (LHsType GhcPs) - -> RnM (HsScaled on GhcRn (LHsType GhcRn), FreeVars) -rnScaledLHsType doc = rnScaledLHsTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) +rnHsConFieldSpec :: HsDocContext -> HsConFieldSpec on GhcPs + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpec doc = rnHsConFieldSpecTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) -rnScaledLHsTyKi :: RnTyKiEnv -> HsScaled on GhcPs (LHsType GhcPs) - -> RnM (HsScaled on GhcRn (LHsType GhcRn), FreeVars) -rnScaledLHsTyKi env (HsScaled w ty) = do +rnHsConFieldSpecTyKi :: RnTyKiEnv -> HsConFieldSpec on GhcPs + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpecTyKi env (CFS unp str w ty) = do (w' , fvs_w) <- rnHsMultAnnOn env w (ty', fvs) <- rnLHsTyKi env ty - return (HsScaled w' ty', fvs `plusFV` fvs_w) + return (CFS unp str w' ty', fvs `plusFV` fvs_w) rnHsType :: HsDocContext -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) @@ -1339,7 +1339,7 @@ rnField :: FastStringEnv FieldLabel -> RnTyKiEnv -> LConDeclField GhcPs -> RnM (LConDeclField GhcRn, FreeVars) rnField fl_env env (L l (ConDeclField _ names ty haddock_doc)) = do { let new_names = map (fmap (lookupField fl_env)) names - ; (new_ty, fvs) <- rnScaledLHsTyKi env ty + ; (new_ty, fvs) <- rnHsConFieldSpecTyKi env ty ; haddock_doc' <- traverse rnLHsDoc haddock_doc ; return (L l (ConDeclField noExtField new_names new_ty haddock_doc') , fvs) } @@ -2035,7 +2035,7 @@ extractConDeclGADTDetailsTyVars :: HsConDeclGADTDetails GhcPs -> FreeKiTyVars -> FreeKiTyVars extractConDeclGADTDetailsTyVars con_args = case con_args of PrefixConGADT _ args -> extract_scaled_ltys args - RecConGADT _ (L _ flds) -> extract_scaled_ltys $ map (cd_fld_type . unLoc) $ flds + RecConGADT _ (L _ flds) -> extract_scaled_ltys $ map (cd_fld_spec . unLoc) $ flds -- | Get type/kind variables mentioned in the kind signature, preserving -- left-to-right order: @@ -2051,13 +2051,13 @@ extractDataDefnKindVars (HsDataDefn { dd_kindSig = ksig }) extract_lctxt :: LHsContext GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lctxt ctxt = extract_ltys (unLoc ctxt) -extract_scaled_ltys :: [HsScaled on GhcPs (LHsType GhcPs)] +extract_scaled_ltys :: [HsConFieldSpec on GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_scaled_ltys args acc = foldr extract_scaled_lty acc args -extract_scaled_lty :: HsScaled on GhcPs (LHsType GhcPs) +extract_scaled_lty :: HsConFieldSpec on GhcPs -> FreeKiTyVars -> FreeKiTyVars -extract_scaled_lty (HsScaled m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc +extract_scaled_lty (CFS _ _ m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc extract_ltys :: [LHsType GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_ltys tys acc = foldr extract_lty acc tys @@ -2068,7 +2068,7 @@ extract_lty (L _ ty) acc HsTyVar _ _ ltv -> extract_tv ltv acc HsBangTy _ _ ty -> extract_lty ty acc HsRecTy _ flds -> foldr (extract_scaled_lty - . cd_fld_type . unLoc) acc + . cd_fld_spec . unLoc) acc flds HsAppTy _ ty1 ty2 -> extract_lty ty1 $ extract_lty ty2 acc ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1928,9 +1928,7 @@ rnDataDefn doc (HsDataDefn { dd_cType = cType, dd_ctxt = context, dd_cons = cond has_labelled_fields _ = False has_strictness_flags condecl - = any (is_strict . getBangStrictness . hsScaledThing) (con_args condecl) - - is_strict (HsSrcBang _ (HsBang _ s)) = isSrcStrict s + = any (isSrcStrict . cfs_bang) (con_args condecl) con_args (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = args con_args (ConDeclH98 { con_args = PrefixCon _ args }) = args @@ -2483,11 +2481,11 @@ rnConDeclH98Details :: -> HsConDeclH98Details GhcPs -> RnM (HsConDeclH98Details GhcRn, FreeVars) rnConDeclH98Details _ doc (PrefixCon _ tys) - = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys + = do { (new_tys, fvs) <- mapFvRn (rnHsConFieldSpec doc) tys ; return (PrefixCon noTypeArgs new_tys, fvs) } rnConDeclH98Details _ doc (InfixCon ty1 ty2) - = do { (new_ty1, fvs1) <- rnScaledLHsType doc ty1 - ; (new_ty2, fvs2) <- rnScaledLHsType doc ty2 + = do { (new_ty1, fvs1) <- rnHsConFieldSpec doc ty1 + ; (new_ty2, fvs2) <- rnHsConFieldSpec doc ty2 ; return (InfixCon new_ty1 new_ty2, fvs1 `plusFV` fvs2) } rnConDeclH98Details con doc (RecCon flds) = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds @@ -2499,7 +2497,7 @@ rnConDeclGADTDetails :: -> HsConDeclGADTDetails GhcPs -> RnM (HsConDeclGADTDetails GhcRn, FreeVars) rnConDeclGADTDetails _ doc (PrefixConGADT _ tys) - = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys + = do { (new_tys, fvs) <- mapFvRn (rnHsConFieldSpec doc) tys ; return (PrefixConGADT noExtField new_tys, fvs) } rnConDeclGADTDetails con doc (RecConGADT _ flds) = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -283,7 +283,7 @@ no_anon_wc_ty lty = go lty HsKindSig _ ty kind -> go ty && go kind HsDocTy _ ty _ -> go ty HsBangTy _ _ ty -> go ty - HsRecTy _ flds -> gos $ concatMap (hsScaledToHsTypes . cd_fld_type . unLoc) flds + HsRecTy _ flds -> gos $ concatMap (hsConFieldSpecToHsTypes . cd_fld_spec . unLoc) flds HsExplicitListTy _ _ tys -> gos tys HsExplicitTupleTy _ _ tys -> gos tys HsForAllTy { hst_tele = tele ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -112,6 +112,7 @@ import Data.List.NonEmpty ( NonEmpty(..) ) import qualified Data.List.NonEmpty as NE import Data.Traversable ( for ) import Data.Tuple( swap ) +import GHC.Types.SourceText (SourceText(NoSourceText)) -- TODO: temp {- ************************************************************************ @@ -1799,11 +1800,11 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled on GhcRn (LHsType GhcRn)] -> TcM () +kcConArgTys :: NewOrData -> TcKind -> [HsConFieldSpec on GhcRn] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) + ; forM_ arg_tys (\(CFS _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -1813,14 +1814,14 @@ kcConH98Args new_or_data res_kind con_args = case con_args of PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ - map (cd_fld_type . unLoc) flds + map (cd_fld_spec . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () kcConGADTArgs new_or_data res_kind con_args = case con_args of PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ - map (cd_fld_type . unLoc) flds + map (cd_fld_spec . unLoc) flds kcConDecls :: Foldable f => NewOrData @@ -3893,7 +3894,7 @@ tcConIsInfixGADT con details RecConGADT{} -> return False PrefixConGADT _ arg_tys -- See Note [Infix GADT constructors] | isSymOcc (getOccName con) - , [_ty1,_ty2] <- map hsScaledThing arg_tys + , [_ty1,_ty2] <- arg_tys -> do { fix_env <- getFixityEnv ; return (con `elemNameEnv` fix_env) } | otherwise -> return False @@ -3924,13 +3925,13 @@ tcConGADTArgs exp_kind (RecConGADT _ fields) tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes - -> HsScaled on GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) -tcConArg exp_kind (HsScaled w bty) + -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) +tcConArg exp_kind (CFS unp str w bty) = do { traceTc "tcConArg 1" (ppr bty) ; arg_ty <- tcCheckLHsTypeInContext (getBangType bty) exp_kind ; w' <- tcDataConMult w ; traceTc "tcConArg 2" (ppr bty) - ; return (Scaled w' arg_ty, getBangStrictness bty) } + ; return (Scaled w' arg_ty, HsSrcBang NoSourceText (HsBang unp str)) } tcRecConDeclFields :: ContextKind -> LocatedL [LConDeclField GhcRn] @@ -3939,7 +3940,7 @@ tcRecConDeclFields exp_kind fields = mapM (tcConArg exp_kind) btys where -- We need a one-to-one mapping from field_names to btys - combined = map (\(L _ f) -> (cd_fld_names f, cd_fld_type f)) + combined = map (\(L _ f) -> (cd_fld_names f, cd_fld_spec f)) (unLoc fields) explode (ns,ty) = zip ns (repeat ty) exploded = concatMap explode combined ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -3,6 +3,7 @@ {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE DataKinds #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -689,7 +690,7 @@ cvtConstr :: TH.Name -- ^ name of first constructor of parent type cvtConstr _ do_con_name (NormalC c strtys) = do { c' <- do_con_name c ; tys' <- mapM cvt_arg strtys - ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing (PrefixCon noTypeArgs (map hsLinear tys')) } + ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing (PrefixCon noTypeArgs tys') } cvtConstr parent_con do_con_name (RecC c varstrtys) = do { c' <- do_con_name c @@ -702,7 +703,7 @@ cvtConstr _ do_con_name (InfixC st1 c st2) ; st1' <- cvt_arg st1 ; st2' <- cvt_arg st2 ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing - (InfixCon (hsLinear st1') (hsLinear st2')) } + (InfixCon st1' st2') } cvtConstr parent_con do_con_name (ForallC tvs ctxt con) = do { tvs' <- cvtTvs tvs @@ -741,7 +742,7 @@ cvtConstr _ do_con_name (GadtC c strtys ty) = case nonEmpty c of { c' <- mapM do_con_name c ; args <- mapM cvt_arg strtys ; ty' <- cvtType ty - ; mk_gadt_decl c' (PrefixConGADT noExtField $ map hsLinear args) ty'} + ; mk_gadt_decl c' (PrefixConGADT noExtField args) ty'} cvtConstr parent_con do_con_name (RecGadtC c varstrtys ty) = case nonEmpty c of Nothing -> failWith RecGadtNoCons @@ -775,13 +776,13 @@ cvtSrcStrictness NoSourceStrictness = NoSrcStrict cvtSrcStrictness SourceLazy = SrcLazy cvtSrcStrictness SourceStrict = SrcStrict -cvt_arg :: (TH.Bang, TH.Type) -> CvtM (LHsType GhcPs) +cvt_arg :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) cvt_arg (Bang su ss, ty) = do { ty'' <- cvtType ty ; let ty' = parenthesizeHsType appPrec ty'' su' = cvtSrcUnpackedness su ss' = cvtSrcStrictness ss - ; returnLA $ HsBangTy (noAnn, NoSourceText) (HsBang su' ss') ty' } + ; return $ CFS su' ss' hsNoMultAnn ty' } cvt_id_arg :: TH.Name -- ^ parent constructor name -> (TH.Name, TH.Bang, TH.Type) -> CvtM (LConDeclField GhcPs) @@ -792,7 +793,7 @@ cvt_id_arg parent_con (i, str, ty) { cd_fld_ext = noExtField , cd_fld_names = [L (l2l li) $ FieldOcc noExtField (L li i')] - , cd_fld_type = hsNoMultAnn ty' + , cd_fld_spec = ty' , cd_fld_doc = Nothing} } cvtDerivs :: [TH.DerivClause] -> CvtM (HsDeriving GhcPs) ===================================== compiler/Language/Haskell/Syntax/Decls.hs ===================================== @@ -1122,7 +1122,7 @@ or contexts in two parts: -- | The arguments in a Haskell98-style data constructor. type HsConDeclH98Details pass - = HsConDetails Void (HsScaled OnArrow pass (LBangType pass)) (XRec pass [LConDeclField pass]) + = HsConDetails Void (HsConFieldSpec OnArrow pass) (XRec pass [LConDeclField pass]) -- The Void argument to HsConDetails here is a reflection of the fact that -- type applications are not allowed in data constructor declarations. @@ -1133,7 +1133,7 @@ type HsConDeclH98Details pass -- derived Show instances—see Note [Infix GADT constructors] in -- GHC.Tc.TyCl—but that is an orthogonal concern.) data HsConDeclGADTDetails pass - = PrefixConGADT !(XPrefixConGADT pass) [HsScaled OnArrow pass (LBangType pass)] + = PrefixConGADT !(XPrefixConGADT pass) [HsConFieldSpec OnArrow pass] | RecConGADT !(XRecConGADT pass) (XRec pass [LConDeclField pass]) | XConDeclGADTDetails !(XXConDeclGADTDetails pass) ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -23,7 +23,7 @@ GHC.Hs.Type: Abstract syntax: user-defined types -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* module Language.Haskell.Syntax.Type ( HsScaled(..), - hsMultIsLinear, hsScaledThing, hsScaledGeneralize, + hsMultIsLinear, hsScaledThing, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), pattern HsUnrestrictedArrow, XUnannotated, XLinearAnn, XExplicitMult, XXMultAnnOn, @@ -57,6 +57,7 @@ module Language.Haskell.Syntax.Type ( ConDeclField(..), LConDeclField, HsConDetails(..), noTypeArgs, + HsConFieldSpec(..), hsConFieldSpecGeneralize, FieldOcc(..), LFieldOcc, @@ -67,7 +68,7 @@ module Language.Haskell.Syntax.Type ( import {-# SOURCE #-} Language.Haskell.Syntax.Expr ( HsUntypedSplice ) -import Language.Haskell.Syntax.Basic ( HsBang(..) ) +import Language.Haskell.Syntax.Basic ( HsBang(..), SrcStrictness, SrcUnpackedness ) import Language.Haskell.Syntax.Extension import Language.Haskell.Syntax.Specificity @@ -983,13 +984,10 @@ type family XXMultAnnOn (on :: HsMultAnnOnWhat) mult p data HsScaled on pass a = HsScaled (HsMultAnnOn on (LHsType pass) pass) a deriving (Functor) -hsScaledGeneralize :: HsScaled on pass a -> HsScaled on1 pass a -hsScaledGeneralize = unsafeCoerce - -hsMultIsLinear :: Bool -> HsScaled on pass a -> Bool -hsMultIsLinear _ (HsScaled (HsUnannotated HsUnannOne _) _) = True -hsMultIsLinear linear (HsScaled (HsUnannotated HsUnannMany _) _) = not linear -hsMultIsLinear _ (HsScaled HsLinearAnn{} _) = True +hsMultIsLinear :: Bool -> HsMultAnnOn on mult pass -> Bool +hsMultIsLinear _ (HsUnannotated HsUnannOne _) = True +hsMultIsLinear linear (HsUnannotated HsUnannMany _) = not linear +hsMultIsLinear _ HsLinearAnn{} = True hsMultIsLinear _ _ = False hsScaledThing :: HsScaled on pass a -> a @@ -1098,7 +1096,7 @@ data ConDeclField pass -- Record fields have Haddock docs on them = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_type :: HsScaled OnRecField pass (LBangType pass), + cd_fld_spec :: HsConFieldSpec OnRecField pass, cd_fld_doc :: Maybe (LHsDoc pass)} | XConDeclField !(XXConDeclField pass) @@ -1129,6 +1127,15 @@ data HsConDetails tyarg arg rec noTypeArgs :: [Void] noTypeArgs = [] +data HsConFieldSpec on pass + = CFS { cfs_unpack :: SrcUnpackedness + , cfs_bang :: SrcStrictness + , cfs_multiplicity :: HsMultAnnOn on (LHsType pass) pass + , cfs_type :: LHsType pass } + +hsConFieldSpecGeneralize :: HsConFieldSpec on pass -> HsConFieldSpec on1 pass +hsConFieldSpecGeneralize = unsafeCoerce + {- Note [ConDeclField pass] ~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4448,13 +4448,29 @@ instance (ExactPrint a) => ExactPrint (HsScaled OnArrow GhcPs a) where arr' <- markArrow arr return (HsScaled arr' t') -instance (ExactPrint a) => ExactPrint (HsScaled OnRecField GhcPs a) where +-- instance (ExactPrint a) => ExactPrint (HsScaled OnRecField GhcPs a) where +-- getAnnotationEntry = const NoEntryVal +-- setAnnotationAnchor a _ _ _ = a +-- exact (HsScaled mult t) = do +-- mult' <- markRecFieldMult mult +-- t' <- markAnnotated t +-- return (HsScaled mult' t') + +instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (HsScaled mult t) = do + exact (CFS unp str arr t) = do + t' <- markAnnotated t + arr' <- markArrow arr + return (CFS unp str arr' t') + +instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where + getAnnotationEntry = const NoEntryVal + setAnnotationAnchor a _ _ _ = a + exact (CFS unp str mult t) = do mult' <- markRecFieldMult mult t' <- markAnnotated t - return (HsScaled mult' t') + return (CFS unp str mult' t') -- --------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs ===================================== @@ -295,14 +295,14 @@ ppCtor sDocContext dat subdocs con at ConDeclH98{con_args = con_args'} = -- AZ:TODO get rid of the concatMap concatMap (lookupCon sDocContext subdocs) [con_name con] ++ f con_args' where - f :: HsConDetails v (HsScaled on GhcRn (LHsType GhcRn)) (LocatedL [LocatedA (ConDeclField GhcRn)]) -> [String] - f (PrefixCon _ args) = [typeSig name $ (map hsScaledThing args) ++ [resType]] + f :: HsConDetails v (HsConFieldSpec on GhcRn) (LocatedL [LocatedA (ConDeclField GhcRn)]) -> [String] + f (PrefixCon _ args) = [typeSig name $ (map cfs_type args) ++ [resType]] f (InfixCon a1 a2) = f $ PrefixCon [] [a1, a2] f (RecCon (L _ recs)) = - f (PrefixCon [] $ map (cd_fld_type . unLoc) recs) + f (PrefixCon [] $ map (cd_fld_spec . unLoc) recs) ++ concat [ (concatMap (lookupCon sDocContext subdocs . noLocA . unLoc . foLabel . unLoc) (cd_fld_names r)) - ++ [out sDocContext (map (foExt . unLoc) $ cd_fld_names r) `typeSig` [resType, hsScaledThing $ cd_fld_type r]] + ++ [out sDocContext (map (foExt . unLoc) $ cd_fld_names r) `typeSig` [resType, cfs_type $ cd_fld_spec r]] | r <- map unLoc recs ] @@ -356,8 +356,8 @@ ppCtor Nothing -> tau_ty tau_ty = foldr mkFunTy res_ty $ case args of - PrefixConGADT _ pos_args -> map hsScaledThing pos_args - RecConGADT _ (L _ flds) -> map (hsScaledThing . cd_fld_type . unL) flds + PrefixConGADT _ pos_args -> map cfs_type pos_args + RecConGADT _ (L _ flds) -> map (cfs_type . cd_fld_spec . unL) flds mkFunTy a b = noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) a b) ppFixity :: SDocContext -> (Name, Fixity) -> [String] ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -964,7 +964,7 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = hsep [ header_ , ppOcc - , hsep (map (ppLParendType unicode . hsScaledThing) args) + , hsep (map (ppLParendType unicode . cfs_type) args) ] -- Record constructor, e.g. 'Identity { runIdentity :: a }' RecCon _ -> header_ <+> ppOcc @@ -974,9 +974,9 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = | otherwise -> hsep [ header_ - , ppLParendType unicode (hsScaledThing arg1) + , ppLParendType unicode (cfs_type arg1) , ppOccInfix - , ppLParendType unicode (hsScaledThing arg2) + , ppLParendType unicode (cfs_type arg2) ] ConDeclGADT{} | hasArgDocs || not (isEmpty fieldPart) -> ppOcc @@ -993,15 +993,15 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = -- GADT record declarations RecConGADT _ _ -> doConstrArgsWithDocs [] -- GADT prefix data constructors - PrefixConGADT _ args | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing args) + PrefixConGADT _ args | hasArgDocs -> doConstrArgsWithDocs (map cfs_type args) _ -> empty ConDeclH98{con_args = con_args'} -> case con_args' of -- H98 record declarations RecCon (L _ fields) -> doRecordFields fields -- H98 prefix data constructors - PrefixCon _ args | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing args) + PrefixCon _ args | hasArgDocs -> doConstrArgsWithDocs (map cfs_type args) -- H98 infix data constructor - InfixCon arg1 arg2 | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing [arg1, arg2]) + InfixCon arg1 arg2 | hasArgDocs -> doConstrArgsWithDocs (map cfs_type [arg1, arg2]) _ -> empty doRecordFields fields = @@ -1035,7 +1035,7 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = decltt ( cat (punctuate comma (map (ppBinder . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode ltype (dcolon unicode) - <+> ppLType unicode (hsScaledThing ltype) + <+> ppLType unicode (cfs_type ltype) ) <-> rDoc mbDoc where @@ -1047,8 +1047,8 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd -ppRecFieldMultAnn :: Bool -> HsScaled on DocNameI a -> LaTeX -> LaTeX -ppRecFieldMultAnn unicode (HsScaled arr _) following = case arr of +ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX +ppRecFieldMultAnn unicode (CFS _ _ arr _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1350,7 +1350,7 @@ ppShortConstrParts summary dataInst con unicode qual = in case det of -- Prefix constructor, e.g. 'Just a' PrefixCon _ args -> - ( header_ <+> hsep (ppOcc : map (ppLParendType unicode qual HideEmptyContexts . hsScaledThing) args) + ( header_ <+> hsep (ppOcc : map (ppLParendType unicode qual HideEmptyContexts . cfs_type) args) , noHtml , noHtml ) @@ -1368,9 +1368,9 @@ ppShortConstrParts summary dataInst con unicode qual = InfixCon arg1 arg2 -> ( header_ <+> hsep - [ ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg1) + [ ppLParendType unicode qual HideEmptyContexts (cfs_type arg1) , ppOccInfix - , ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg2) + , ppLParendType unicode qual HideEmptyContexts (cfs_type arg2) ] , noHtml , noHtml @@ -1431,7 +1431,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = | otherwise -> hsep [ header_ <+> ppOcc - , hsep (map (ppLParendType unicode qual HideEmptyContexts . hsScaledThing) args) + , hsep (map (ppLParendType unicode qual HideEmptyContexts . cfs_type) args) , fixity ] -- Record constructor, e.g. 'Identity { runIdentity :: a }' @@ -1441,9 +1441,9 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = | hasArgDocs -> header_ <+> ppOcc <+> fixity | otherwise -> hsep - [ header_ <+> ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg1) + [ header_ <+> ppLParendType unicode qual HideEmptyContexts (cfs_type arg1) , ppOccInfix - , ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg2) + , ppLParendType unicode qual HideEmptyContexts (cfs_type arg2) , fixity ] -- GADT constructor, e.g. 'Foo :: Int -> Foo' @@ -1483,7 +1483,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = doConstrArgsWithDocs args = subFields pkg qual $ case con of ConDeclH98{} -> [ (ppLParendType unicode qual HideEmptyContexts arg, mdoc, []) - | (i, arg) <- zip [0 ..] (map hsScaledThing args) + | (i, arg) <- zip [0 ..] (map cfs_type args) , let mdoc = Map.lookup i argDocs ] ConDeclGADT{} -> @@ -1543,7 +1543,7 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = ] ) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) - <+> ppLType unicode qual HideEmptyContexts (hsScaledThing ltype) + <+> ppLType unicode qual HideEmptyContexts (cfs_type ltype) , mbDoc , [] ) @@ -1555,8 +1555,8 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd -ppRecFieldMultAnn :: Unicode -> Qualification -> HsScaled on DocNameI a -> Html -> Html -ppRecFieldMultAnn unicode qual (HsScaled arr _) following = case arr of +ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html +ppRecFieldMultAnn unicode qual (CFS _ _ arr _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following @@ -1565,7 +1565,7 @@ ppShortField :: Bool -> Unicode -> Qualification -> ConDeclField DocNameI -> Htm ppShortField summary unicode qual (ConDeclField _ names ltype _) = hsep (punctuate comma (map ((ppBinder summary) . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) - <+> ppLType unicode qual HideEmptyContexts (hsScaledThing ltype) + <+> ppLType unicode qual HideEmptyContexts (cfs_type ltype) -- | Pretty print an expanded pattern (for bundled patterns) ppSideBySidePat ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -494,13 +494,10 @@ synifyDataCon use_gadt_syntax dc = linear_tys = zipWith - ( \(Scaled mult ty) bang -> + ( \(Scaled mult ty) (HsSrcBang _ (HsBang unp str)) -> let tySyn = synifyType WithinType [] ty multSyn = synifyMultRec [] mult - bangTy = case bang of - (HsSrcBang _ (HsBang NoSrcUnpack NoSrcStrict)) -> tySyn - (HsSrcBang src bang') -> noLocA $ HsBangTy (noAnn, src) bang' tySyn - in HsScaled multSyn bangTy + in CFS unp str multSyn tySyn ) arg_tys (dataConSrcBangs dc) @@ -518,15 +515,15 @@ synifyDataCon use_gadt_syntax dc = mk_h98_arg_tys = case (use_named_field_syntax, use_infix_syntax) of (True, True) -> Left "synifyDataCon: contradiction!" (True, False) -> return $ RecCon (noLocA field_tys) - (False, False) -> return $ PrefixCon noTypeArgs (map hsScaledGeneralize linear_tys) - (False, True) -> case map hsScaledGeneralize linear_tys of + (False, False) -> return $ PrefixCon noTypeArgs (map hsConFieldSpecGeneralize linear_tys) + (False, True) -> case map hsConFieldSpecGeneralize linear_tys of [a, b] -> return $ InfixCon a b _ -> Left "synifyDataCon: infix with non-2 args?" mk_gadt_arg_tys :: HsConDeclGADTDetails GhcRn mk_gadt_arg_tys | use_named_field_syntax = RecConGADT noExtField (noLocA field_tys) - | otherwise = PrefixConGADT noExtField (map hsScaledGeneralize linear_tys) + | otherwise = PrefixConGADT noExtField (map hsConFieldSpecGeneralize linear_tys) in -- finally we get synifyDataCon's result! if use_gadt_syntax ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -220,7 +220,7 @@ getGADTConType -- tau_ty :: LHsType DocNameI tau_ty = case args of RecConGADT _ flds -> mkFunTy (noLocA (HsRecTy noAnn (unLoc flds))) res_ty - PrefixConGADT _ pos_args -> foldr mkFunTy res_ty (map hsScaledThing pos_args) + PrefixConGADT _ pos_args -> foldr mkFunTy res_ty (map cfs_type pos_args) mkFunTy :: LHsType DocNameI -> LHsType DocNameI -> LHsType DocNameI mkFunTy a b = noLocA (HsFunTy noAnn (HsUnrestrictedArrow noExtField) a b) @@ -361,8 +361,8 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] field_avail (L _ (ConDeclField _ fs _ _)) = all (\f -> (unLoc . foLabel . unLoc $ f) `elem` names) fs - field_types :: [LConDeclField GhcRn] -> [HsScaled OnArrow GhcRn (LBangType GhcRn)] - field_types flds = [hsScaledGeneralize t | L _ (ConDeclField _ _ t _) <- flds] + field_types :: [LConDeclField GhcRn] -> [HsConFieldSpec OnArrow GhcRn] + field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t _) <- flds] keep _ = Nothing restrictDecls :: [Name] -> [LSig GhcRn] -> [LSig GhcRn] @@ -513,7 +513,7 @@ reparenBndrKind v at XBndrKind{} = v -- | Add parenthesis around the types in a 'ConDeclField' (see 'reparenTypePrec') reparenConDeclField :: XRecCond a => ConDeclField a -> ConDeclField a -reparenConDeclField (ConDeclField x n t d) = ConDeclField x n (fmap reparenLType t) d +reparenConDeclField (ConDeclField x n (CFS unp str m t) d) = ConDeclField x n (CFS unp str m (reparenLType t)) d reparenConDeclField c at XConDeclField{} = c ------------------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Create.hs ===================================== @@ -962,12 +962,12 @@ extractPatternSyn nm t tvs cons = let args = case con of ConDeclH98{con_args = con_args'} -> case con_args' of - PrefixCon _ args' -> map hsScaledThing args' - RecCon (L _ fields) -> hsScaledThing . cd_fld_type . unLoc <$> fields - InfixCon arg1 arg2 -> map hsScaledThing [arg1, arg2] + PrefixCon _ args' -> map cfs_type args' + RecCon (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields + InfixCon arg1 arg2 -> map cfs_type [arg1, arg2] ConDeclGADT{con_g_args = con_args'} -> case con_args' of - PrefixConGADT _ args' -> map hsScaledThing args' - RecConGADT _ (L _ fields) -> hsScaledThing . cd_fld_type . unLoc <$> fields + PrefixConGADT _ args' -> map cfs_type args' + RecConGADT _ (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields typ = longArrow args (data_ty con) typ' = case con of @@ -999,7 +999,7 @@ extractRecSel nm t tvs (L _ con : rest) = case getRecConArgs_maybe con of Just (L _ fields) | ((l, L _ (ConDeclField _ _nn ty _)) : _) <- matching_fields fields -> - pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (getBangType $ hsScaledThing ty)))))) + pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (cfs_type ty)))))) -- TODO : was getBangType $ hsScaledThing ty _ -> extractRecSel nm t tvs rest where matching_fields :: [LConDeclField GhcRn] -> [(SrcSpan, LConDeclField GhcRn)] ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -718,10 +718,10 @@ renameCon } ) -renameHsScaled - :: HsScaled on GhcRn (LHsType GhcRn) - -> RnM (HsScaled on DocNameI (LHsType DocNameI)) -renameHsScaled (HsScaled w ty) = HsScaled <$> renameMultAnnOn w <*> renameLType ty +renameHsConFieldSpec + :: HsConFieldSpec on GhcRn + -> RnM (HsConFieldSpec on DocNameI) +renameHsConFieldSpec (CFS unp str w ty) = CFS unp str <$> renameMultAnnOn w <*> renameLType ty renameH98Details :: HsConDeclH98Details GhcRn @@ -729,10 +729,10 @@ renameH98Details renameH98Details (RecCon (L l fields)) = do fields' <- mapM renameConDeclFieldField fields return (RecCon (L (locA l) fields')) -renameH98Details (PrefixCon ts ps) = PrefixCon ts <$> mapM renameHsScaled ps +renameH98Details (PrefixCon ts ps) = PrefixCon ts <$> mapM renameHsConFieldSpec ps renameH98Details (InfixCon a b) = do - a' <- renameHsScaled a - b' <- renameHsScaled b + a' <- renameHsConFieldSpec a + b' <- renameHsConFieldSpec b return (InfixCon a' b') renameGADTDetails @@ -741,12 +741,12 @@ renameGADTDetails renameGADTDetails (RecConGADT _ (L l fields)) = do fields' <- mapM renameConDeclFieldField fields return (RecConGADT noExtField (L (locA l) fields')) -renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsScaled ps +renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsConFieldSpec ps renameConDeclFieldField :: LConDeclField GhcRn -> RnM (LConDeclField DocNameI) renameConDeclFieldField (L l (ConDeclField _ names t doc)) = do names' <- mapM renameLFieldOcc names - t' <- renameHsScaled t + t' <- renameHsConFieldSpec t doc' <- mapM renameLDocHsSyn doc return $ L (locA l) (ConDeclField noExtField names' t' doc') View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3b685b803182a1399196d016321995823dfc98d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a3b685b803182a1399196d016321995823dfc98d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 15:29:26 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 08 Jan 2025 10:29:26 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] adding test case UnliftedNewtypesRunTypeRepPoly Message-ID: <677e99d6b7207_d837697d8bc85bc@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 8997776e by Patrick at 2025-01-08T23:29:14+08:00 adding test case UnliftedNewtypesRunTypeRepPoly - - - - - 2 changed files: - + testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs ===================================== @@ -0,0 +1,32 @@ +{-# LANGUAGE GADTSyntax #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE RankNTypes #-} + +module UnliftedNewtypesRunTypeRepPoly where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -934,3 +934,4 @@ test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) test('T25597', normal, compile, ['']) test('InstanceConKindSpecializationDataFamily', normal, compile, ['']) +test('UnliftedNewtypesRunTypeRepPoly', normal, compile, ['']) \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8997776ef9c9a52d2ac10b96460780f4850062b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8997776ef9c9a52d2ac10b96460780f4850062b1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 15:45:43 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 08 Jan 2025 10:45:43 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] rename etaExpandAlgTyCon -> maybeEtaExpandAlgTyCon and introduce... Message-ID: <677e9da75e677_d8376b5a65889e@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 17e8b4e5 by Patrick at 2025-01-08T23:45:32+08:00 rename etaExpandAlgTyCon -> maybeEtaExpandAlgTyCon and introduce etaExpandAlgTyCon to expand unconditionally - - - - - 3 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour $ dataDefnConsNewOrData hs_cons - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/17e8b4e5e94172ee266ab2f6ceba219ce76cce4c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/17e8b4e5e94172ee266ab2f6ceba219ce76cce4c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 16:27:23 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Wed, 08 Jan 2025 11:27:23 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <677ea76b1da5f_16b20f110f308757c@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 4e768618 by Brandon Chinn at 2025-01-08T08:27:12-08:00 Require alex >= 3.5.2 (#25623) - - - - - 6 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in - hadrian/cabal.project Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: eb4d3389fd62e4f7321a0c8799014ec1f4da0708 + DOCKER_REV: f8b8b8910097a88185835e0c929b8bb03fadfe61 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/ci.sh ===================================== @@ -8,9 +8,9 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-04T21:29:42Z" MIN_HAPPY_VERSION="1.20" -MIN_ALEX_VERSION="3.2.6" +MIN_ALEX_VERSION="3.5.2.0" TOP="$(pwd)" if [ ! -d "$TOP/.gitlab" ]; then ===================================== .gitlab/darwin/nix/sources.json ===================================== @@ -17,10 +17,10 @@ "homepage": "", "owner": "nixos", "repo": "nixpkgs", - "rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60", - "sha256": "1anwxmjpm21msnnlrjdz19w31bxnbpn4kgf93sn3npihi7wf4a8h", + "rev": "07f572aeeaef429c75f4f867b35dc3acae3b5517", + "sha256": "1yins6gqkfcvnja6h247scc80zjwhgygfhyrc1k51q292gal357v", "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/2893f56de08021cffd9b6b6dfc70fd9ccd51eb60.tar.gz", + "url": "https://github.com/nixos/nixpkgs/archive/07f572aeeaef429c75f4f867b35dc3acae3b5517.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-04T21:29:42Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4e768618eb3f7ade69e18832a6a1b36c81317077 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4e768618eb3f7ade69e18832a6a1b36c81317077 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 19:15:41 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 08 Jan 2025 14:15:41 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] driver: Store the HomePackageTable in a mutable reference Message-ID: <677ecedd31686_16b20f11c39e011398d@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 4b2d116f by Rodrigo Mesquita at 2025-01-08T19:15:32+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b2d116fb5e8472ca08c7e41b7d1858cb53de6ff -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4b2d116fb5e8472ca08c7e41b7d1858cb53de6ff You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 22:13:24 2025 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Wed, 08 Jan 2025 17:13:24 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25621 Message-ID: <677ef8845a63f_3e2e8456f5a4367c2@gitlab.mail> Ryan Scott pushed new branch wip/T25621 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25621 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 23:07:23 2025 From: gitlab at gitlab.haskell.org (=?UTF-8?B?TWF0ZXVzeiBHb8WbbGlub3dza2kgKEBTd29yZGxhc2gp?=) Date: Wed, 08 Jan 2025 18:07:23 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/swordlash/allow_multiline_strings_in_js_ffi Message-ID: <677f052bee498_3e2e849d70744507f@gitlab.mail> Mateusz Goślinowski pushed new branch wip/swordlash/allow_multiline_strings_in_js_ffi at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/swordlash/allow_multiline_strings_in_js_ffi You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 23:33:23 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 08 Jan 2025 18:33:23 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25641 Message-ID: <677f0b4336313_3e2e84f631a05393b@gitlab.mail> Ben Gamari pushed new branch wip/T25641 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25641 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 23:35:46 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 08 Jan 2025 18:35:46 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/printer-improvements Message-ID: <677f0bd2f017_3e2e84e8deb0554c9@gitlab.mail> Ben Gamari pushed new branch wip/printer-improvements at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/printer-improvements You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 8 23:41:12 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 08 Jan 2025 18:41:12 -0500 Subject: [Git][ghc/ghc][wip/bytecode-improvements] 194 commits: DmdAnal: Make `prompt#` lazy (#25439) Message-ID: <677f0d18b9b68_3e2e841166380569be@gitlab.mail> Ben Gamari pushed to branch wip/bytecode-improvements at Glasgow Haskell Compiler / GHC Commits: 00d58ae1 by Sebastian Graf at 2024-11-13T15:21:23-05:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. - - - - - 93233a66 by Ben Gamari at 2024-11-13T15:21:59-05:00 boot: Do not attempt to update config.sub While Apple ARM hardware was new we found that the autoconf scripts included in some boot packages were too old. As a mitigation for this, we introduced logic in the `boot` script to update the `config.sub` with that from the GHC tree. However, this causes submodules which have `config.sub` committted to appear to be dirty. This is a considerable headache. Now since `config.sub` with full platform support is more common we can remove `boot`'s `config.sub` logic. Fixes #19574. - - - - - fa66fa64 by Ryan Scott at 2024-11-14T19:05:00-05:00 Add regression test for #16234 Issue #16234 was likely fixed by !9765. This adds a regression test to ensure that it remains fixed. Fixes #16234. - - - - - bfe64df8 by Matthew Pickering at 2024-11-14T19:05:36-05:00 ghc-internal: Update to Unicode 16 This patch updates the automatically generated code for querying unicode properties to unicode 16. Fixes #25402 - - - - - 1fd83f86 by Ben Gamari at 2024-11-14T19:06:13-05:00 configure: Accept happy-2.1.2 happy-2.1 was released in late Oct 2024. I have confirmed that master bootstraps with it. Here we teach configure to accept this tool. Fixes #25438. - - - - - aa58fc5b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Tighten up invariants of PACK - - - - - 8aa4c10a by Ben Gamari at 2024-11-14T19:06:49-05:00 testsuite: Fix badly escaped literals Use raw string literals to ensure that `\s` is correctly interpreted as a character class. - - - - - 0e084029 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Improve documentation of SLIDE bytecode instruction - - - - - 9bf3663b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Assert that TEST*_P discriminators are valid - - - - - 1f668511 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Improve documentation of TEST*_P instructions - - - - - 59e0a770 by Cheng Shao at 2024-11-14T19:07:25-05:00 misc: improve clangd compile_flags.txt flags This patch improves the compile_flags.txt config used to power clangd for the rts C codebase. The flags in the file are sampled & deduped from a real stage1 build with clang-19 and vastly improves the IDE accuracy when hacking the rts. For maximum code coverage under the default settings, compile_flags.txt defaults to threaded+profiled+dynamic+debug way. This does not mean profdyn needs to be actually built in _build/stage1 for IDE to work. To activate IDE for other RTS ways, simply remove one of the -D flags at the end of compile_flags.txt and restart clangd. - - - - - c2c562e0 by Ben Gamari at 2024-11-14T19:08:01-05:00 testsuite: Don't consider untracked files in dirtiness check Considering trees containing untracked files as dirty is a bridge too far. The chance of an untracked file significantly affecting measured performanced metrics is quite small whereas not collecting measurements is quite inconvenient for some workflows. We now ignore untracked files in the dirtiness check. Fixes #25471. - - - - - ed2ed6c5 by Cheng Shao at 2024-11-14T19:08:37-05:00 testsuite: add regression test T25473 This commit adds regression test T25473 marked as broken due to #25473. It will be fixed in the subsequent commit. - - - - - bd0a8b7e by Cheng Shao at 2024-11-14T19:08:37-05:00 wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. - - - - - f1b0bc32 by Ben Gamari at 2024-11-14T19:09:13-05:00 rts/linker: Make FreeBSD declarations proper prototypes The iconv declarations for FreeBSD were previously not prototypes, leading to warnings. - - - - - 086cbbc1 by Ben Gamari at 2024-11-14T19:09:13-05:00 base: Drop redundant import in FreeBSD ExecutablePath implementation - - - - - 79ecd199 by Ben Gamari at 2024-11-14T19:09:13-05:00 compiler: Fix partial selector warnings in GHC.Runtime.Heap.Inspect - - - - - 1acb73bf by Andrew Lelechenko at 2024-11-15T06:10:47-05:00 gitlab: mention CLC in MR template - - - - - 8f2e0832 by Ben Gamari at 2024-11-15T06:11:24-05:00 rts: Allow use of GNU-stack notes on FreeBSD Previously we gated use of GNU-style non-executable stack notes to only apply on Linux. However, these are also supported by FreeBSD, which also uses ELF. Fix this. Fixes #25475. - - - - - 2c427cb0 by Ben Gamari at 2024-11-16T05:27:40-05:00 rts: Fix EINTR check in timerfd ticker When `poll` failed we previously checked that `errno == -EINTR` to silence the failure warning. However, this is wrong as `errno` values are generally not negated error codes (in contrast to many system call results, which is likely what the original author had in mind). Fixes #25477. - - - - - a0fa4941 by Ben Gamari at 2024-11-16T05:28:16-05:00 rts: Increase gen_workspace alignment to 128 bytes on AArch64 Increase to match the 128-byte cache-line size of Apple's ARMv8 implementation. Closes #25459. - - - - - 142d8afa by Ben Gamari at 2024-11-16T16:20:47-05:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - b7a146e5 by Ben Gamari at 2024-11-16T16:20:47-05:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - ddb7afa6 by Ben Gamari at 2024-11-16T16:21:23-05:00 users guide: Mention language extensions in equality constraints discussion As suggested in #24127, mention the language extensions necessary for usage of equality constriants in their documentation. Closes #24127. - - - - - 36133dac by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/9.14.1-notes: Fix list syntax - - - - - 888de658 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/debug-info: Fix duplicate flag descriptions - - - - - f120e427 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide: Fix reference to 9.14.1 release notes - - - - - 8e975032 by Ben Gamari at 2024-11-16T16:21:59-05:00 Introduce GHC.Tc.Plugin.lookupTHName This makes it significantly more convenient (and less GHC-version-dependent) to resolve a template-haskell name into a GHC Name. As proposed in #24741. - - - - - a0e168ec by ARATA Mizuki at 2024-11-16T16:22:40-05:00 x86 NCG SIMD: Lower packFloatX4#, insertFloatX4# and broadcastFloatX4# to SSE1 instructions Fixes #25441 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 3936bf1b by sheaf at 2024-11-16T16:23:22-05:00 X86 NCG: allow VXOR at scalar floating-point types The NCG can emit VXOR instructions at scalar floating-point types, but the pretty-printer would panic instead of emitting the appropriate VXORPS/VXORPD instructions. This patch rectifies that oversight. Fixes #25455 - - - - - d9dff93a by Ben Gamari at 2024-11-16T16:23:58-05:00 rts: Fix platform-dependent pointer casts Previously we had unnecessary (and incorrect) platform-dependent casts to turn `OSThreadIds`s into a integer. We now just uniformly cast first to a `uintptr_t` (which is always safe, regardless of whether `OSThreadId` is a pointer), and then cast to the desired integral type. This fixes a warning on musl platforms. - - - - - 6d95cdb8 by Ben Gamari at 2024-11-16T16:24:34-05:00 testsuite: Mark encoding004 as broken on FreeBSD Due to #22003, CP936 fails to roundtrip: ```diff == CP936 +Failed to roundtrip given mutant byte at index 891 (251 /= 123 at index 891) +Failed to roundtrip given mutant byte at index 1605 (197 /= 69 at index 1605) +Failed to roundtrip given mutant byte at index 2411 (235 /= 107 at index 2411) +Failed to roundtrip given mutant byte at index 6480 (208 /= 80 at index 6480) +Failed to roundtrip given mutant byte at index 6482 (210 /= 82 at index 6482) +Failed to roundtrip given mutant byte at index 6484 (212 /= 84 at index 6484) +Failed to roundtrip given mutant byte at index 6496 (224 /= 96 at index 6496) +Failed to roundtrip given mutant byte at index 7243 (203 /= 75 at index 7243) +Failed to roundtrip given mutant byte at index 7277 (237 /= 109 at index 7277) +Failed to roundtrip given mutant byte at index 8027 (219 /= 91 at index 8027) +Failed to roundtrip given mutant byte at index 8801 (225 /= 97 at index 8801) ``` - - - - - 26e86984 by Ben Gamari at 2024-11-18T04:05:31-05:00 hadrian: Allow haddock options to be passed via key-value settings - - - - - 6e68b117 by Matthew Pickering at 2024-11-18T04:06:07-05:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - a4e0d235 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 exceptions: Improve the message layout as per #285 This commit fixes the layout of the additional information included when displaying an exception, namely the type of the exception. It also fixes the default handler's heading message to work well together with the improved display message of SomeException. CLC proposal#285 - - - - - 284ffab3 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 Display type and callstack of exception on handler This commit changes the Exception instance of SomeException to *simply* display the underlying exception in `displayException`. The augmented exception message that included the type and backtrace of the exception are now only printed on a call to `displayExceptionWithInfo`. At a surface level, existing programs should behave the same since the `uncaughtExceptionHandler`, which is responsible for printing out uncaught exceptions to the user, will use `displayExceptionWithInfo` by default. However, unlike the instance's `displayException` method, the `uncaughtExceptionHandler` can be overriden with `setUncaughtExceptionHandler`. This makes the extra information opt-in without fixing it the instance, which can be valuable if your program wants to display uncaught exceptions to users in a user-facing way (ie without backtraces). This is what was originally agreed for CLC#231 or CLC#261 with regard to the type of the exception information. The call stack also becoming part of the default handler rather than the Exception instance is an ammendment to CLC#164. Discussion of the ammendment is part of CLC#285. - - - - - 36cddd2c by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Remove redundant CallStack from exceptions Before the exception backtraces proposal was implemented, ErrorCall accumulated its own callstack via HasCallStack constraints, but ExceptionContext is now accumulated automatically. The original ErrorCall mechanism is now redundant and we get a duplicate CallStack Updates Cabal submodule to fix their usage of ErrorCallWithLocation to ErrorCall CLC proposal#285 Fixes #25283 - - - - - 7a74330b by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Freeze call stack in error throwing functions CLC proposal#285 - - - - - 3abf31a4 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 De-duplicate displayContext and displayExceptionContext The former was unused except for one module where it was essentially re-defining displayExceptionContext. Moreover, this commit extends the fix from bfe600f5bb3ecd2c8fa71c536c63d3c46984e3f8 to displayExceptionContext too, which was missing. - - - - - c0d783f8 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Re-export NoBacktrace from Control.Exception This was originally proposed and accepted in section "2.7 Capturing Backtraces on Exceptions" of the CLC proposal for exception backtraces. However, the implementation missed this re-export, which this commit now fixes. - - - - - 802b5c3e by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Fix exception backtraces from GHCi When running the program with `runhaskell`/`runghc` the backtrace should match the backtrace one would get by compiling and running the program. But currently, an exception thrown in a program interpreted with `runhaskell` will: * Not include the original exception backtrace at all * Include the backtrace from the internal GHCi/ghc rethrowing of the original exception This commit fixes this divergence by not annotating the ghc(i) backtrace (with NoBacktrace) and making sure that the backtrace of the original exception is serialized across the boundary and rethrown with the appropriate context. Fixes #25116 The !13301 MR (not this commit in particular) improves performance of MultiLayerModules. Unfortunately, T3294 regresses on aarch64-linux-deb12 by 1% allocations. Since this patch must be merged for 9.12 ASAP, we will not be able to investigate the slight regression on this platform in time. ------------------------- Metric Decrease: MultiLayerModulesRecomp MultiLayerModulesTH_OneShot Metric Increase: T3294 ------------------------- - - - - - 3e89eb65 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 base: Add to changelog.md CLC #285 - - - - - d9326a48 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Bump array and stm submodules for testsuite The testsuites of array and stm had to be updated according to !13301. Updates submodule array and stm. - - - - - 325fcb5d by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Clean up code style of Nativei386 adjustor - - - - - 39bb6e58 by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Fix stack overrun error in Nativei386 adjustor We were reserving the wrong kind of adjustor context (the generic `AdjustorContext` used by other adjustor implementations, rather than the i386-specific `CCallContext`) to return the adjustor context while freeing, resulting in #25485. Fixes #25485. - - - - - 831aab22 by sheaf at 2024-11-18T21:22:36-05:00 Include diagnostic reason in -fdiagnostics-as-json This commit ensures that the -fdiagnostics-as-json output includes the diagnostic reason. This allows the full error message produced by GHC to be re-constructed from the JSON output. Fixes #25403 - - - - - 3e5bfdd3 by Ben Gamari at 2024-11-18T21:23:12-05:00 rts: Introduce printIPE This is a convenience utility for use in GDB. - - - - - 44d909a3 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Don't store boot locations in finder cache Partially reverts commit fff55592a7b Amends add(Home)ModuleToFinder so that locations for boot files are not stored in the finder cache. Removes InstalledModule field from InstalledFound constructor since it's the same as the key that was searched for. - - - - - 64c95292 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Concentrate boot extension logic in Finder With new mkHomeModLocation that takes an extra HscSource to add boot extensions if required. - - - - - 11bad98d by ARATA Mizuki at 2024-11-19T14:39:08-05:00 Better documentation for floating-point min/max and SIMD primitives See #25350 for floating-point min/max Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 791a47b2 by Arnaud Spiwack at 2024-11-20T14:00:05+00:00 Add test for #25185 - - - - - 374e18e5 by Arnaud Spiwack at 2024-11-20T14:09:30+00:00 Quick look: emit the multiplicity of app heads in tcValArgs Otherwise it's not scaled properly by the context, allowing unsound expressions. Fixes #25185. - - - - - 1fc02399 by sheaf at 2024-11-20T18:11:03-05:00 x86 NCG: fix regUsageOfInstr for VMOVU & friends This commit fixes the implementation of 'regUsageOfInstr' for vector operations that take an 'Operand' as the destination, by ensuring that when the destination is an address then the address should be *READ*, and not *WRITTEN*. Getting this wrong is a disaster, as it means the register allocator has incorrect information, which can lead to it discard stores to registers, segfaults ensuing. Fixes #25486 - - - - - 7bd407a6 by Brandon Chinn at 2024-11-21T14:08:15-05:00 Fix CRLF in multiline strings (#25375) - - - - - 7575709b by Rodrigo Mesquita at 2024-11-21T14:08:52-05:00 Improve reachability queries on ModuleGraph Introduces `ReachabilityIndex`, an index constructed from a `GHC.Data.Graph.Directed` `Graph` that supports fast reachability queries (in $O(1)$). This abstract data structure is exposed from `GHC.Data.Graph.Directed.Reachability`. This index is constructed from the module graph nodes and cached in `ModuleGraph`, enabling efficient reachability queries on the module graph. Previously, we'd construct a Map of Set of ModuleGraph nodes which used a lot of memory (`O(n^2)` in the number of nodes) and cache that in the `ModuleGraph`. By using the reachability index we get rid of this space leak in the module graph -- even though the index is still quadratic in the number of modules, it is much, much more space efficient due to its representation using an IntMap of IntSet as opposed to the transitive closure we previously cached. In a memory profile of MultiLayerModules with 100x100 modules, memory usage improved from 6GB residency to 2.8GB, out of which roughly 1.8GB are caused by a second space leak related to ModuleGraph. On the same program, it brings compile time from 7.5s to 5.5s. Note how we simplify `checkHomeUnitsClosed` in terms of `isReachableMany` and by avoiding constructing a second graph with the full transitive closure -- it suffices to answer the reachability query on the full graph without collapsing the transitive closure completely into nodes. Unfortunately, solving this leak means we have to do a little bit more work since we can no longer cache the result of turning vertex indices into nodes. This results in a slight regression in MultiLayerModulesTH_Make, but results in large performance and memory wins when compiling large amounts of modules. ------------------------- Metric Decrease: mhu-perf Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - bcbcdaaf by Cheng Shao at 2024-11-21T14:09:28-05:00 driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code This commit fixes an undefined symbol error in RTS linker when attempting to compile home modules with -fhpc and -fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for detailed description and analysis of the bug. Also adds T25510/T25510c regression tests to test make mode/oneshot mode of the bug. - - - - - 970ada5a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Bump ci-images For introduction of Alpine/i386 image. Thanks to Julian for the base image. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 8115abc2 by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Add release job for i386/Alpine As requested by Mikolaj and started by Julian. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 639f0149 by Ben Gamari at 2024-11-22T23:32:06-05:00 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ - - - - - 490d4d0a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Mark i386 Alpine test breakages Marks the following tests as broken on i386/Alpine: * T22033 due to #25497 * simd009, T25062_V16, T25169, T22187_run due to #25498 - - - - - 536cdf09 by Cheng Shao at 2024-11-22T23:32:42-05:00 compiler: remove unused GHC.Linker.Loader.loadExpr This patch removes the unused `GHC.Linker.Loader.loadExpr` function. It was moved from `GHC.Runtime.Linker.linkExpr` in `ghc-9.0` to `GHC.Linker.Loader.loadExpr` in `ghc-9.2`, and remain completely unused and untested ever since. There's also no third party user of this function to my best knowledge, so let's remove this. Anyone who wants to write their own GHC API function to load bytecode can consult the source code in older release branches. - - - - - 6ee35024 by Drew Fenwick at 2024-11-22T23:33:26-05:00 Fix a non-compiling example in the type abstractions docs This patch adds a missing Show constraint to a code example in the User Guide's type abstractions docs to fix issue #25422. - - - - - d1172e20 by Rodrigo Mesquita at 2024-11-22T23:34:02-05:00 Re-introduce ErrorCallWithLocation with a deprecation pragma With the removal of the duplicate backtrace, part of CLC proposal #285, the constructor `ErrorCallWithLocation` was removed from base. This commit re-introduces it with a deprecation. - - - - - 1187a60a by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Skip tests requiring Hadrian deps in out-of-tree testsuite runs Some testsuite tests require specific tools (e.g. `check-ppr` and `check-exact`) beyond those shipped in the binary distribution. Skip these tests. Fixes #13897. - - - - - c37d7a2e by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Declare exactprint tests' dependency on check-exact - - - - - 454ce957 by Ben Gamari at 2024-11-22T23:35:15-05:00 ghc-internal: Fix a few cases of missing Haddock markup - - - - - a249649b by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/GHCiPrimCall : Add missing Makefile includes - - - - - a021a493 by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/IpeStats: Use Make rather than shell interpolation - - - - - 6e1fbda7 by Ben Gamari at 2024-11-25T03:55:44-05:00 hadrian-ghci-multi: Pass -this-package-name in unit response files As noted in #25509, the `-this-package-name` must be passed for each package to ensure that GHC can response references to the packages' exposed modules via package-qualified imports. Fix this. Closes #25509. - - - - - a05e4a9b by Simon Hengel at 2024-11-25T03:56:33-05:00 Refactoring: Use `OnOff` more consistently for `Extension` - - - - - 7536181d by Matthew Pickering at 2024-11-25T14:00:07-05:00 driver: Always link against "base" package when one shot linking The default value for base-unit-id is stored in the settings file. At install time, this can be set by using the BASE_UNIT_ID environment variable. At runtime, the value can be set by `-base-unit-id` flag. For whether all this is a good idea, see #25382 Fixes #25382 - - - - - 7f90f319 by Andreas Klebinger at 2024-11-25T14:00:44-05:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 - - - - - 291388e1 by Cheng Shao at 2024-11-25T14:01:19-05:00 ci: minor nix-in-docker improvements This patch makes some minor improvements re nix-in-docker logic in the ci configuration: - Update `nixos/nix` to the latest version - Apply $CPUS to `cores`/`max-jobs` to avoid oversubscribing while allowing a reasonable degree of parallelism - Remove redundant `--extra-experimental-features nix-command` in later `nix shell` invocations, it's already configured in `/etc/nix/nix.conf` - - - - - e684c406 by Cheng Shao at 2024-11-25T14:01:57-05:00 ci: avoid depending on stack job for test-bootstrap jobs This patch makes test-bootstrap related ci jobs only depend on hadrian-ghc-in-ghci job to finish, consistent with other jobs in the full-build stage generated by gen_ci.hs. This allows the jobs to be spawned earlier and improve overall pipeline parallelism. - - - - - caaf5388 by Simon Hengel at 2024-11-25T14:02:41-05:00 Refactoring: Remove `pSupportedExts` from `ParserOpts` This is never used for lexing / parsing. It is only used by `GHC.Parser.Header.getOptions`. - - - - - 41f8365c by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Add test for #25515 - - - - - 9279619f by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Desugar record notation with correct multiplicities Simply uses the multiplicity as stored in the field. As I'm writing this commit, the only possible multiplicity is 1, but !13525 is changing this. It's actually easier to take !13525 into account. Fixes #25515. - - - - - fcc3ae6e by Andreas Klebinger at 2024-11-26T08:24:58-05:00 Clarify INLINE unfolding optimization docs. Fixes #24660 - - - - - 88c4fe1d by Cheng Shao at 2024-11-26T08:25:34-05:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. - - - - - 53f978c0 by doyougnu at 2024-11-26T16:07:26-05:00 ghc-experimental: expose GHC.RTS.Flags, GHC.Stats See this CLC proposal: - https://github.com/haskell/core-libraries-committee/issues/289 and this CLC proposal for background: - https://github.com/haskell/core-libraries-committee/issues/288 Metric Decrease: MultiLayerModulesTH_OneShot - - - - - e70d4140 by Wang Xin at 2024-11-26T16:08:10-05:00 Add -mcmodel=medium moduleflag to generated LLVM IR on LoongArch platform With the Medium code model, the jump range of the generated jump instruction is larger than that of the Small code model. It's a temporary fix of the problem descriped in https://gitlab.haskell .org/ghc/ghc/-/issues/25495. This commit requires that the LLVM used contains the code of commit 9dd1d451d9719aa91b3bdd59c0c6679 83e1baf05, i.e., version 8.0 and later. Actually we should not rely on LLVM, so the only way to solve this problem is to implement the LoongArch backend. Add new type for codemodel - - - - - df42ba16 by Andreas Klebinger at 2024-11-27T11:40:49-05:00 Cmm constant folding: Narrow results to operations bitwidth. When constant folding ensure the result is still within bounds for the given type by explicitly narrowing the results. Not doing so results in a lot of spurious assembler warnings especially when testing primops. - - - - - bf3db97e by Ben Gamari at 2024-11-27T11:41:26-05:00 ghc-toolchain: Introduce basic flag validation We verify that required flags (currently `--output` and `--triple`) are provided. The implementation is truly awful, but so is getopt. Begins to address #25500. - - - - - a104508d by Ben Gamari at 2024-11-27T11:42:03-05:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. - - - - - c3fc9b86 by Ben Gamari at 2024-11-27T11:42:39-05:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. - - - - - a362b943 by sheaf at 2024-11-27T23:44:28-05:00 Add checkExact to toolTargets This change means that the Hadrian multi target will include exactprint. In particular, this means that HLS will work on exactprint inside the GHC tree. - - - - - e6c957e4 by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Add test for #25428 - - - - - 52d97f4e by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Don't bypass MonoLocalBind in empty patterns Fixes #25428 - - - - - 7890f2d8 by Ben Gamari at 2024-11-28T10:26:46-05:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. - - - - - 0fd43ea6 by Adam Sandberg Ericsson at 2024-11-28T10:27:22-05:00 mention -Iw in +RTS -? - - - - - 6cf579b9 by Ben Gamari at 2024-11-28T10:27:59-05:00 gitlab-ci: Set GIT_SUBMODULE_FORCE_HTTPS GitLab recommends using `https://` to clone submodules and provides the `GIT_SUBMODULE_FORCE_HTTPS` variable to force this. Fixes #25528. - - - - - 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 4f93db6b by Ben Gamari at 2025-01-08T18:39:07-05:00 StgToByteCode: Add Note summarizing pipeline This is just a beginning - - - - - 2231ff0d by Ben Gamari at 2025-01-08T18:40:02-05:00 GHC.Linker.Loader: Consolidate linking of CompiledByteCode There was a significant amount of unnecessary code duplication between `dynLinkBCOs` and `loadDecls`. Also, avoid open-coding `modifyClosureEnv`. - - - - - 26 changed files: - .gitattributes - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/hello.hs - .gitlab/jobs.yaml - .gitlab/merge_request_templates/Default.md - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/upload.sh - .gitmodules - boot - compile_flags.txt - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/Format.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8f878104e6e20f46d77c1b07e6b02319b5e8b1dc...2231ff0de427c39681a35e59f63f5bbd846d393d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8f878104e6e20f46d77c1b07e6b02319b5e8b1dc...2231ff0de427c39681a35e59f63f5bbd846d393d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 00:47:12 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 08 Jan 2025 19:47:12 -0500 Subject: [Git][ghc/ghc][wip/bytecode-improvements] GHC.Linker.Loader: Consolidate linking of CompiledByteCode Message-ID: <677f1c909061d_3e2e8419e21086575d@gitlab.mail> Ben Gamari pushed to branch wip/bytecode-improvements at Glasgow Haskell Compiler / GHC Commits: 58ae451b by Ben Gamari at 2025-01-08T19:47:05-05:00 GHC.Linker.Loader: Consolidate linking of CompiledByteCode There was a significant amount of unnecessary code duplication between `dynLinkBCOs` and `loadDecls`. Also, avoid open-coding `modifyClosureEnv`. - - - - - 1 changed file: - compiler/GHC/Linker/Loader.hs Changes: ===================================== compiler/GHC/Linker/Loader.hs ===================================== @@ -639,15 +639,7 @@ loadDecls interp hsc_env span linkable = do then throwGhcExceptionIO (ProgramError "") else do -- Link the expression itself - let le = linker_env pls - le2 = le { itbl_env = foldl' (\acc cbc -> plusNameEnv acc (bc_itbls cbc)) (itbl_env le) cbcs - , addr_env = foldl' (\acc cbc -> plusNameEnv acc (bc_strs cbc)) (addr_env le) cbcs } - - -- Link the necessary packages and linkables - new_bindings <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs - nms_fhvs <- makeForeignNamedHValueRefs interp new_bindings - let ce2 = extendClosureEnv (closure_env le2) nms_fhvs - !pls2 = pls { linker_env = le2 { closure_env = ce2 } } + (pls2, nms_fhvs) <- link_compiled_bytecodes interp isExternalName cbcs pls return (pls2, (nms_fhvs, links_needed, units_needed)) where cbcs = linkableBCOs linkable @@ -851,34 +843,41 @@ rmDupLinkables already ls dynLinkBCOs :: Interp -> LoaderState -> [Linkable] -> IO LoaderState dynLinkBCOs interp pls bcos = do + fst <$> link_compiled_bytecodes interp (const True) cbcs pls1 + where + (bcos_loaded', new_bcos) = rmDupLinkables (bcos_loaded pls) bcos + pls1 = pls { bcos_loaded = bcos_loaded' } + + parts :: [LinkablePart] + parts = concatMap (NE.toList . linkableParts) new_bcos + + cbcs = concatMap linkablePartAllBCOs parts + +link_compiled_bytecodes + :: Interp + -> (Name -> Bool) -- ^ predicate determining which names to add to 'ClosureEnv' + -> [CompiledByteCode] -- ^ bytecode to load + -> LoaderState + -> IO (LoaderState, [(Name, ForeignHValue)]) +link_compiled_bytecodes interp expose_pred cbcs pls = do + let le1 = linker_env pls + le2 = le1 { itbl_env = foldr plusNameEnv (itbl_env le1) (map bc_itbls cbcs) + , addr_env = foldr plusNameEnv (addr_env le1) (map bc_strs cbcs) + } - let (bcos_loaded', new_bcos) = rmDupLinkables (bcos_loaded pls) bcos - pls1 = pls { bcos_loaded = bcos_loaded' } - - parts :: [LinkablePart] - parts = concatMap (NE.toList . linkableParts) new_bcos - - cbcs :: [CompiledByteCode] - cbcs = concatMap linkablePartAllBCOs parts - - - le1 = linker_env pls - ie2 = foldr plusNameEnv (itbl_env le1) (map bc_itbls cbcs) - ae2 = foldr plusNameEnv (addr_env le1) (map bc_strs cbcs) - le2 = le1 { itbl_env = ie2, addr_env = ae2 } + names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs - names_and_refs <- linkSomeBCOs interp (pkgs_loaded pls) le2 cbcs + -- We only want to add the external ones to the ClosureEnv + let (to_add, to_drop) = partition (expose_pred . fst) names_and_refs - -- We only want to add the external ones to the ClosureEnv - let (to_add, to_drop) = partition (isExternalName.fst) names_and_refs + -- Immediately release any HValueRefs we're not going to add + freeHValueRefs interp (map snd to_drop) - -- Immediately release any HValueRefs we're not going to add - freeHValueRefs interp (map snd to_drop) - -- Wrap finalizers on the ones we want to keep - new_binds <- makeForeignNamedHValueRefs interp to_add + -- Wrap finalizers on the ones we want to keep + new_binds <- makeForeignNamedHValueRefs interp to_add - let ce2 = extendClosureEnv (closure_env le2) new_binds - return $! pls1 { linker_env = le2 { closure_env = ce2 } } + let !pls' = modifyClosureEnv pls (`extendClosureEnv` new_binds) + return (pls', new_binds) -- Link a bunch of BCOs and return references to their values linkSomeBCOs :: Interp View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/58ae451b0b4e40a1553897b469d13501207411d9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/58ae451b0b4e40a1553897b469d13501207411d9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 02:17:11 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Wed, 08 Jan 2025 21:17:11 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <677f31a79daf0_3e2e842443ea87173e@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 0c6fa68e by Brandon Chinn at 2025-01-08T18:16:58-08:00 Require alex >= 3.5.2 (#25623) - - - - - 6 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in - hadrian/cabal.project Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: eb4d3389fd62e4f7321a0c8799014ec1f4da0708 + DOCKER_REV: f8b8b8910097a88185835e0c929b8bb03fadfe61 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/ci.sh ===================================== @@ -8,9 +8,9 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-04T21:29:42Z" MIN_HAPPY_VERSION="1.20" -MIN_ALEX_VERSION="3.2.6" +MIN_ALEX_VERSION="3.5.2.0" TOP="$(pwd)" if [ ! -d "$TOP/.gitlab" ]; then ===================================== .gitlab/darwin/nix/sources.json ===================================== @@ -17,10 +17,10 @@ "homepage": "", "owner": "nixos", "repo": "nixpkgs", - "rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60", - "sha256": "1anwxmjpm21msnnlrjdz19w31bxnbpn4kgf93sn3npihi7wf4a8h", + "rev": "91ef85e17108be826689fe42a207dfd24d354012", + "sha256": "", "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/2893f56de08021cffd9b6b6dfc70fd9ccd51eb60.tar.gz", + "url": "https://github.com/nixos/nixpkgs/archive/91ef85e17108be826689fe42a207dfd24d354012.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-04T21:29:42Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c6fa68ee6cb376bd4e884cd8415b4b98c79ad9f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0c6fa68ee6cb376bd4e884cd8415b4b98c79ad9f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 04:56:32 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Wed, 08 Jan 2025 23:56:32 -0500 Subject: [Git][ghc/ghc][wip/T25609] 23 commits: Remove unnecessary irrefutable patterns from NonEmpty functions Message-ID: <677f57002cdfc_3bc4389ca8b0937ec@gitlab.mail> Brandon Chinn pushed to branch wip/T25609 at Glasgow Haskell Compiler / GHC Commits: feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 221bf592 by Brandon Chinn at 2025-01-08T20:55:40-08:00 Break out GHC.Parser.Lexer.Interface - - - - - 99471b92 by Brandon Chinn at 2025-01-08T20:55:40-08:00 Fix #25609 - - - - - 7b1d869a by Brandon Chinn at 2025-01-08T20:55:40-08:00 Allow decrease in metrics Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/GHC/Rename/Unbound.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/TyCl.hs - compiler/ghc.cabal.in - docs/users_guide/phases.rst - ghc/ghc-bin.cabal.in - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Warnings.hs - libraries/Cabal - libraries/Win32 - libraries/array - libraries/base/base.cabal.in - libraries/base/changelog.md - libraries/base/src/Data/List/NonEmpty.hs - libraries/binary - libraries/bytestring - libraries/deepseq - libraries/directory - libraries/exceptions - libraries/file-io The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/597f862d74544fb5f809152779afaea1c64015e6...7b1d869aec869e41483ff9954b23a67af44e1e78 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/597f862d74544fb5f809152779afaea1c64015e6...7b1d869aec869e41483ff9954b23a67af44e1e78 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 04:57:13 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Wed, 08 Jan 2025 23:57:13 -0500 Subject: [Git][ghc/ghc][wip/T25623] 21 commits: Remove unnecessary irrefutable patterns from NonEmpty functions Message-ID: <677f5729b9752_3bc438b3572c9401e@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 6bed69ae by Brandon Chinn at 2025-01-08T20:56:32-08:00 Require alex >= 3.5.2 (#25623) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Rename/Unbound.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/TyCl.hs - compiler/ghc.cabal.in - docs/users_guide/phases.rst - ghc/ghc-bin.cabal.in - hadrian/cabal.project - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Warnings.hs - libraries/Cabal - libraries/Win32 - libraries/array - libraries/base/base.cabal.in - libraries/base/changelog.md - libraries/base/src/Data/List/NonEmpty.hs - libraries/binary - libraries/bytestring - libraries/deepseq - libraries/directory - libraries/exceptions - libraries/file-io The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c6fa68ee6cb376bd4e884cd8415b4b98c79ad9f...6bed69aed62863a07b8285a197e7b06186df0e25 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c6fa68ee6cb376bd4e884cd8415b4b98c79ad9f...6bed69aed62863a07b8285a197e7b06186df0e25 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 05:27:47 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 09 Jan 2025 00:27:47 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] rts/printClosure: Print IPE information for thunks and functions Message-ID: <677f5e53b1e70_3bc438eac50498972@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 44634f24 by Ben Gamari at 2025-01-09T00:27:41-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 1 changed file: - rts/Printer.c Changes: ===================================== rts/Printer.c ===================================== @@ -151,13 +151,20 @@ printClosure( const StgClosure *obj ) case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_0_2: case FUN_2_0: case FUN_STATIC: - debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); - printPtr((StgPtr)obj->header.info); + { + debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); + + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #if defined(PROFILING) - debugBelch(", %s", obj->header.prof.ccs->cc->label); + debugBelch(", %s", obj->header.prof.ccs->cc->label); #endif - printStdObjPayload(obj); - break; + printStdObjPayload(obj); + break; + } case PRIM: debugBelch("PRIM("); @@ -175,13 +182,19 @@ printClosure( const StgClosure *obj ) case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: case THUNK_STATIC: + { /* ToDo: will this work for THUNK_STATIC too? */ #if defined(PROFILING) printThunkObject((StgThunk *)obj,GET_PROF_DESC(info)); #else printThunkObject((StgThunk *)obj,"THUNK"); + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #endif break; + } case THUNK_SELECTOR: printStdObjHdr(obj, "THUNK_SELECTOR"); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44634f24459e13dfbb1c447d7b402889589990b2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44634f24459e13dfbb1c447d7b402889589990b2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 06:49:24 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 09 Jan 2025 01:49:24 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update note Message-ID: <677f717435c3e_2a026afceb8-33c@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 3af75d42 by Patrick at 2025-01-09T14:49:13+08:00 update note - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1010,7 +1010,8 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- , Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1027,6 +1028,8 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Perhaps surprisingly, we don't need the skolemised tvs themselves ; return inner_kind' } + + {- Note [Result kind signature for a data family instance] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The expected type might have a forall at the type. Normally, we @@ -1036,6 +1039,22 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +default the result kind of a newtype instance to `Type` when +`-XUnliftedNewtypes` is not enabled. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1190,47 +1209,47 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in a data/newtype family instance declaration: -* We take account of the data constructors (via `kcConDecls`) for +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: * Haskell-98 style data instance declarations * All newtype instance declarations - For H-98 style declarations there is no GADT refinement. And for + For Haskell-98 style declarations, there is no GADT refinement. And for GADT-style newtype declarations, no GADT matching is allowed anyway, - so it's just a syntactic difference from H-98. + so it's just a syntactic difference from Haskell-98. -* We /ignore/ the data constructors for +* We /ignore/ the data constructors for: * GADT-style data instance declarations - Here the instance kinds are influenced only by the header. + Here, the instance kinds are influenced only by the header. This choice is implemented by the guarded call to `kcConDecls` in `tcDataFamInstHeader`. Observations: -* With UnliftedNewtypes or UnliftedDatatypes, looking at the data - constructors is necessary to infer the kind of result type for - certain cases. Otherwise addtional kind signatures are required. +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. Consider the following example in #25611: data family Fix :: (k -> Type) -> k newtype instance Fix f = In { out :: f (Fix f) } - If we are not looking at the data constructors. - * Without UnliftedNewtypes, it is accepted since `Fix f` is defaulted - to Type. - * But with UnliftedNewtypes, `Fix f` is defaulted to `TYPE a` where - a is not scoped over the data constructor. Then header `Fix f :: TYPE a` + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` will fail to kind unify with `f (Fix f) :: Type`. - Hence we need to look at the data constructor to infer `Fix f :: TYPE` + Hence, we need to look at the data constructor to infer `Fix f :: Type` for this newtype instance. -This DESIGN CHOICE strikes a balance between well rounded kind inference -and the implementation simplicity. See #25611, #18891 and !4419 for more +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3af75d42c7bedbe2750dae9d362e3aceaa615e72 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3af75d42c7bedbe2750dae9d362e3aceaa615e72 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 06:51:11 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 09 Jan 2025 01:51:11 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update note Message-ID: <677f71df586a9_2a026a101d142121@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: e9ca2183 by Patrick at 2025-01-09T14:51:01+08:00 update note - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1011,7 +1011,7 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), -- , Note [Implementation of UnliftedDatatypes] - -- and Note [Defaulting newtype/data family instance]. + -- and Note [Defaulting kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1039,7 +1039,7 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 -Note [Defaulting newtype/data family instance] +Note [Defaulting kind of newtype/data family instance] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9ca218328efdad63b77da4b324664e9e4806898 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9ca218328efdad63b77da4b324664e9e4806898 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 07:32:52 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 09 Jan 2025 02:32:52 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update note Message-ID: <677f7ba4755ca_2a026a62cdac43e@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 734c02bb by Patrick at 2025-01-09T15:32:43+08:00 update note - - - - - 2 changed files: - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2463,7 +2463,7 @@ There are also some changes for dealing with families: UnliftedNewtypes is on. This allows us to write things like: data family Foo :: TYPE 'IntRep -2. In a newtype instance, if the user does +2. In a newtype instance (with -XUnliftedNewtypes), if the user does not write a kind signature, we want to allow the possibility that the kind is not Type, so we use newOpenTypeKind instead of liftedTypeKind. This is done in tcDataFamInstHeader in GHC.Tc.TyCl.Instance. Example: @@ -2503,16 +2503,7 @@ If we expect the argument to MkA to have kind Type, then we get a kind-mismatch error. The problem is that there is no way to connect this mismatch error to -XUnliftedNewtypes, and suggest enabling the extension. So, instead, we allow the A to type-check, but then find the problem when doing validity checking (and -where we get make a suitable error message). - -The same handling, is done for newtype data instances, resolving #25593. -So the following example would be suggested to enable UnliftedNewtypes: - - -- no UnliftedNewtypes - data family D :: UnliftedType - newtype instance D = MkD Any - -One potential worry is +where we get make a suitable error message). One potential worry is {-# LANGUAGE PolyKinds #-} newtype B a = MkB a ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1028,8 +1028,6 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Perhaps surprisingly, we don't need the skolemised tvs themselves ; return inner_kind' } - - {- Note [Result kind signature for a data family instance] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The expected type might have a forall at the type. Normally, we View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/734c02bb2a1df715e253212f199713e7c2acaf1c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/734c02bb2a1df715e253212f199713e7c2acaf1c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 09:53:45 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 09 Jan 2025 04:53:45 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] driver: Store an ExternalModuleGraph in the EPS Message-ID: <677f9ca9375aa_2383f561d1b8359b0@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: ec787af6 by Matthew Pickering at 2025-01-09T09:53:23+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25639 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Unit/External.hs - + compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/Graph.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr - testsuite/tests/backpack/should_compile/bkp61.stderr - testsuite/tests/backpack/should_fail/bkpfail07.stderr - testsuite/tests/backpack/should_fail/bkpfail09.stderr - testsuite/tests/backpack/should_fail/bkpfail12.stderr - testsuite/tests/backpack/should_fail/bkpfail13.stderr - testsuite/tests/backpack/should_fail/bkpfail14.stderr - testsuite/tests/backpack/should_fail/bkpfail15.stderr - testsuite/tests/backpack/should_fail/bkpfail21.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec787af64ebe0782cc2db5c1093745737ea6c76f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec787af64ebe0782cc2db5c1093745737ea6c76f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 10:08:51 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 09 Jan 2025 05:08:51 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] rts/printClosure: Print IPE information for thunks and functions Message-ID: <677fa03317733_32288cbccf06693b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 09030ba1 by Ben Gamari at 2025-01-09T05:08:45-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 1 changed file: - rts/Printer.c Changes: ===================================== rts/Printer.c ===================================== @@ -151,13 +151,20 @@ printClosure( const StgClosure *obj ) case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_0_2: case FUN_2_0: case FUN_STATIC: - debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); - printPtr((StgPtr)obj->header.info); + { + debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); + + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #if defined(PROFILING) - debugBelch(", %s", obj->header.prof.ccs->cc->label); + debugBelch(", %s", obj->header.prof.ccs->cc->label); #endif - printStdObjPayload(obj); - break; + printStdObjPayload(obj); + break; + } case PRIM: debugBelch("PRIM("); @@ -175,13 +182,19 @@ printClosure( const StgClosure *obj ) case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: case THUNK_STATIC: + { /* ToDo: will this work for THUNK_STATIC too? */ #if defined(PROFILING) printThunkObject((StgThunk *)obj,GET_PROF_DESC(info)); #else printThunkObject((StgThunk *)obj,"THUNK"); + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #endif break; + } case THUNK_SELECTOR: printStdObjHdr(obj, "THUNK_SELECTOR"); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/09030ba1e3439b00eb22bc75de7b222cfee9d76c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/09030ba1e3439b00eb22bc75de7b222cfee9d76c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 10:47:12 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 09 Jan 2025 05:47:12 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] driver: Store the HomePackageTable in a mutable reference Message-ID: <677fa93072cda_37d3782ebb2099286@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: a857f160 by Rodrigo Mesquita at 2025-01-09T10:47:01+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a857f1602216c8a61c8293da6b152796d0b2ce5d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a857f1602216c8a61c8293da6b152796d0b2ce5d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 10:52:03 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 09 Jan 2025 05:52:03 -0500 Subject: [Git][ghc/ghc][wip/romes/25574] 35 commits: testsuite: Use math.inf instead of division-by-zero Message-ID: <677faa53a9435_37d378495cc8996f6@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/25574 at Glasgow Haskell Compiler / GHC Commits: e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - dc542b79 by Rodrigo Mesquita at 2025-01-09T10:51:51+00:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/upload.sh - .gitmodules - compiler/GHC/Builtin/Names.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Unit/Types.hs - compiler/ghc.cabal.in - docs/users_guide/9.14.1-notes.rst - docs/users_guide/exts/overloaded_record_update.rst The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7decbb7d248f7f51799e8c665b3c758488c05fb9...dc542b79d5d67c872ec2eee6c5fa72769b8144c8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7decbb7d248f7f51799e8c665b3c758488c05fb9...dc542b79d5d67c872ec2eee6c5fa72769b8144c8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 10:59:22 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 09 Jan 2025 05:59:22 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/romes/here-for-ci Message-ID: <677fac0ac8ff2_37d3785fcf6c104246@gitlab.mail> Rodrigo Mesquita deleted branch wip/romes/here-for-ci at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 11:05:01 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 09 Jan 2025 06:05:01 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/romes/fix-no-fixup-chains Message-ID: <677fad5d90412_37d3786ddc381044b4@gitlab.mail> Rodrigo Mesquita deleted branch wip/romes/fix-no-fixup-chains at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 11:09:51 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 09 Jan 2025 06:09:51 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add HsConFieldSpec Message-ID: <677fae7f3feb6_26bbcbe34855a6@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 618fdaa7 by Sjoerd Visscher at 2025-01-09T12:09:19+01:00 Add HsConFieldSpec - - - - - 26 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Type.hs - utils/check-exact/ExactPrint.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/Rename.hs - utils/haddock/haddock-api/src/Haddock/Types.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -881,11 +881,11 @@ pprConDecl (ConDeclH98 { con_name = L _ con where -- In ppr_details: let's not print the multiplicities (they are always 1, by -- definition) as they do not appear in an actual declaration. - ppr_details (InfixCon t1 t2) = hsep [ppr (hsScaledThing t1), + ppr_details (InfixCon t1 t2) = hsep [pprHsConFieldSpecNoMult t1, pprInfixOcc con, - ppr (hsScaledThing t2)] + pprHsConFieldSpecNoMult t2] ppr_details (PrefixCon _ tys) = hsep (pprPrefixOcc con - : map (pprHsType . unLoc . hsScaledThing) tys) + : map pprHsConFieldSpecNoMult tys) ppr_details (RecCon fields) = pprPrefixOcc con <+> pprConDeclFields (unLoc fields) @@ -896,7 +896,7 @@ pprConDecl (ConDeclGADT { con_names = cons, con_bndrs = L _ outer_bndrs <+> (sep [pprHsOuterSigTyVarBndrs outer_bndrs <+> pprLHsContext mcxt, sep (ppr_args args ++ [ppr res_ty]) ]) where - ppr_args (PrefixConGADT _ args) = map (\(HsScaled arr t) -> ppr t <+> ppr_arr arr) args + ppr_args (PrefixConGADT _ args) = map (pprHsConFieldSpecWith (\arr tyDoc -> tyDoc <+> ppr_arr arr)) args ppr_args (RecConGADT _ fields) = [pprConDeclFields (unLoc fields) <+> arrow] -- Display linear arrows as unrestricted with -XNoLinearTypes ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -535,7 +535,7 @@ deriving instance Data (HsTyLit GhcPs) deriving instance Data (HsTyLit GhcRn) deriving instance Data (HsTyLit GhcTc) --- deriving instance (Data mult, DataIdLR p p) => Data (HsArrowOf mult p) +-- deriving instance (Data mult, DataIdLR p p, Typeable on) => Data (HsMultAnnOn on mult p) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsType GhcPs)) GhcPs) deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsType GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcRn)) GhcRn) @@ -545,7 +545,7 @@ deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsExpr deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcTc)) GhcTc) --- deriving instance (DataIdLR p p) => Data (HsScaled p a) +-- deriving instance (DataIdLR p p, Typeable on) => Data (HsScaled on p a) deriving instance Data thing => Data (HsScaled OnArrow GhcPs thing) deriving instance Data thing => Data (HsScaled OnRecField GhcPs thing) deriving instance (Data thing, Typeable on) => Data (HsScaled on GhcRn thing) @@ -561,6 +561,12 @@ deriving instance Data (ConDeclField GhcPs) deriving instance Data (ConDeclField GhcRn) deriving instance Data (ConDeclField GhcTc) +-- deriving instance (DataIdLR p p, Typeable on) => Data (HsConFieldSpec on p) +deriving instance Data (HsConFieldSpec OnArrow GhcPs) +deriving instance Data (HsConFieldSpec OnRecField GhcPs) +deriving instance Typeable on => Data (HsConFieldSpec on GhcRn) +deriving instance Typeable on => Data (HsConFieldSpec on GhcTc) + -- deriving instance (DataId p) => Data (FieldOcc p) deriving instance Data (FieldOcc GhcPs) deriving instance Data (FieldOcc GhcRn) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -25,11 +25,11 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( Mult, HsScaled(..), - hsMultIsLinear, hsScaledThing, hsScaledToHsTypes, + hsMultIsLinear, hsScaledThing, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, EpLinearArrow(..), - hsLinear, hsNoMultAnn, isUnrestricted, + hsNoMultAnn, isUnrestricted, pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, @@ -61,6 +61,8 @@ module GHC.Hs.Type ( ConDeclField(..), LConDeclField, pprConDeclFields, HsConDetails(..), noTypeArgs, + HsConFieldSpec(..), pprHsConFieldSpecWith, pprHsConFieldSpecNoMult, + hsPlainTypeField, hsConFieldSpecToHsTypes, FieldOcc(..), LFieldOcc, mkFieldOcc, fieldOccRdrName, fieldOccLRdrName, @@ -482,6 +484,8 @@ type instance XSpliceTy GhcTc = Kind type instance XDocTy (GhcPass _) = NoExtField type instance XBangTy (GhcPass _) = ((EpaLocation, EpToken "#-}", EpaLocation), SourceText) +type instance XConFieldSpec (GhcPass _) = ((EpaLocation, EpToken "#-}", EpaLocation), SourceText) +type instance XXConDeclField (GhcPass _) = DataConCantHappen type instance XRecTy GhcPs = AnnList () type instance XRecTy GhcRn = NoExtField @@ -541,14 +545,8 @@ type instance XExplicitMult _ _ GhcTc = NoExtField type instance XXMultAnnOn _ _ (GhcPass _) = DataConCantHappen -hsLinear :: a -> HsScaled OnArrow GhcPs a -hsLinear = HsScaled (HsLinearAnn noAnn) - -hsNoMultAnn :: a -> HsScaled OnRecField GhcPs a -hsNoMultAnn = HsScaled (HsUnannotated HsUnannOne noAnn) - -hsScaledToHsTypes :: HsScaled on GhcRn (LHsType GhcRn) -> [LHsType GhcRn] -hsScaledToHsTypes (HsScaled arr t) = [multAnnToHsType arr, t] +hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => HsMultAnnOn on (LHsType GhcPs) GhcPs +hsNoMultAnn = HsUnannotated HsUnannOne noAnn isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (multAnnToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName @@ -582,16 +580,17 @@ type instance XXConDeclField (GhcPass _) = DataConCantHappen instance OutputableBndrId p => Outputable (ConDeclField (GhcPass p)) where - ppr (ConDeclField _ fld_n (HsScaled fld_mult fld_ty) _) = ppr_names fld_n <+> ppr_mult <+> ppr fld_ty + ppr (ConDeclField _ fld_n cfs _) = ppr_names fld_n <+> pprHsConFieldSpecWith ppr_mult cfs where ppr_names :: [LFieldOcc (GhcPass p)] -> SDoc ppr_names [n] = pprPrefixOcc n ppr_names ns = sep (punctuate comma (map pprPrefixOcc ns)) - ppr_mult = case fld_mult of - HsUnannotated _ _ -> dcolon - HsLinearAnn _ -> text "%1" <+> dcolon - HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon + ppr_mult :: HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc + ppr_mult mult tyDoc = case mult of + HsUnannotated _ _ -> dcolon <+> tyDoc + HsLinearAnn _ -> text "%1" <+> dcolon <+> tyDoc + HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon <+> tyDoc --------------------- hsWcScopedTvs :: LHsSigWcType GhcRn -> [Name] @@ -723,10 +722,10 @@ mkHsAppKindTy at ty k = addCLocA ty k (HsAppKindTy at ty k) -- splitHsFunType (a -> (b -> c)) = ([a,b], c) -- It returns API Annotations for any parens removed splitHsFunType :: - LHsType (GhcPass p) + LHsType GhcPs -> ( ([EpToken "("], [EpToken ")"]) , EpAnnComments -- The locations of any parens and -- comments discarded - , [HsScaled OnArrow (GhcPass p) (LHsType (GhcPass p))], LHsType (GhcPass p)) + , [HsConFieldSpec OnArrow GhcPs], LHsType GhcPs) splitHsFunType ty = go ty where go (L l (HsParTy (op,cp) ty)) @@ -737,7 +736,7 @@ splitHsFunType ty = go ty go (L ll (HsFunTy _ mult x y)) | (anns, csy, args, res) <- splitHsFunType y - = (anns, csy S.<> epAnnComments ll, HsScaled mult x:args, res) + = (anns, csy S.<> epAnnComments ll, CFS noAnn NoSrcUnpack NoSrcStrict mult x:args, res) go other = (noAnn, emptyComments, [], other) @@ -1297,6 +1296,18 @@ instance (Outputable tyarg, Outputable arg, Outputable rec) ppr (RecCon rec) = text "RecCon:" <+> ppr rec ppr (InfixCon l r) = text "InfixCon:" <+> ppr [l, r] +pprHsConFieldSpecWith :: (OutputableBndrId p) => (HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc) -> HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty) = ppr_mult mult (ppr prag <+> ppr mark <> ppr ty) + +pprHsConFieldSpecNoMult :: (OutputableBndrId p) => HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecNoMult = pprHsConFieldSpecWith (\_ d -> d) + +hsPlainTypeField :: LHsType GhcPs -> HsConFieldSpec OnArrow GhcPs +hsPlainTypeField = CFS noAnn NoSrcUnpack NoSrcStrict (HsLinearAnn noAnn) + +hsConFieldSpecToHsTypes :: HsConFieldSpec on GhcRn -> [LHsType GhcRn] +hsConFieldSpecToHsTypes (CFS _ _ _ arr t) = [multAnnToHsType arr, t] + instance Outputable (XRecGhc (IdGhcP p)) => Outputable (FieldOcc (GhcPass p)) where ppr = ppr . foLabel ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -430,14 +430,14 @@ conArgDocs (ConDeclGADT{con_g_args = args, con_res_ty = res_ty}) = h98ConArgDocs :: HsConDeclH98Details GhcRn -> IntMap (HsDoc GhcRn) h98ConArgDocs con_args = case con_args of - PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args - InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (hsScaledThing arg1) - , unLoc (hsScaledThing arg2) ] + PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args + InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (cfs_type arg1) + , unLoc (cfs_type arg2) ] RecCon _ -> IM.empty gadtConArgDocs :: HsConDeclGADTDetails GhcRn -> HsType GhcRn -> IntMap (HsDoc GhcRn) gadtConArgDocs con_args res_ty = case con_args of - PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args ++ [res_ty] + PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args ++ [res_ty] RecConGADT _ _ -> con_arg_docs 1 [res_ty] con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn) ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -920,17 +920,13 @@ repSrcStrictness SrcLazy = rep2 sourceLazyName [] repSrcStrictness SrcStrict = rep2 sourceStrictName [] repSrcStrictness NoSrcStrict = rep2 noSourceStrictnessName [] -repBangTy :: LBangType GhcRn -> MetaM (Core (M TH.BangType)) -repBangTy ty = do - MkC u <- repSrcUnpackedness su' - MkC s <- repSrcStrictness ss' +repConFieldSpec :: HsConFieldSpec on GhcRn -> MetaM (Core (M TH.BangType)) +repConFieldSpec (CFS _ su ss _ ty') = do + MkC u <- repSrcUnpackedness su + MkC s <- repSrcStrictness ss MkC b <- rep2 bangName [u, s] MkC t <- repLTy ty' rep2 bangTypeName [b, t] - where - (su', ss', ty') = case unLoc ty of - HsBangTy _ (HsBang su ss) ty -> (su, ss, ty) - _ -> (NoSrcUnpack, NoSrcStrict, ty) ------------------------------------------------------- -- Deriving clauses @@ -2838,8 +2834,8 @@ repH98DataCon con details rep2 normalCName [unC con', unC arg_tys] InfixCon st1 st2 -> do verifyLinearFields [st1, st2] - arg1 <- repBangTy (hsScaledThing st1) - arg2 <- repBangTy (hsScaledThing st2) + arg1 <- repConFieldSpec st1 + arg2 <- repConFieldSpec st2 rep2 infixCName [unC arg1, unC con', unC arg2] RecCon ips -> do arg_vtys <- repRecConArgs ips @@ -2865,33 +2861,33 @@ repGadtDataCons cons details res_ty -- TH currently only supports linear constructors. -- We also accept the (->) arrow when -XLinearTypes is off, because this -- denotes a linear field. -verifyLinearFields :: [HsScaled on GhcRn (LHsType GhcRn)] -> MetaM () +verifyLinearFields :: [HsConFieldSpec on GhcRn] -> MetaM () verifyLinearFields ps = do linear <- lift $ xoptM LangExt.LinearTypes - let allGood = all (hsMultIsLinear linear) ps + let allGood = all (hsMultIsLinear linear . cfs_multiplicity) ps unless allGood $ notHandled ThNonLinearDataCon -- Desugar the arguments in a data constructor declared with prefix syntax. -repPrefixConArgs :: [HsScaled OnArrow GhcRn (LHsType GhcRn)] +repPrefixConArgs :: [HsConFieldSpec OnArrow GhcRn] -> MetaM (Core [M TH.BangType]) repPrefixConArgs ps = do verifyLinearFields ps - repListM bangTypeTyConName repBangTy (map hsScaledThing ps) + repListM bangTypeTyConName repConFieldSpec ps -- Desugar the arguments in a data constructor declared with record syntax. repRecConArgs :: LocatedL [LConDeclField GhcRn] -> MetaM (Core [M TH.VarBangType]) repRecConArgs lips = do let ips = map unLoc (unLoc lips) - verifyLinearFields (map cd_fld_type ips) + verifyLinearFields (map cd_fld_spec ips) args <- concatMapM rep_ip ips coreListM varBangTypeTyConName args where - rep_ip ip = mapM (rep_one_ip (hsScaledThing $ cd_fld_type ip)) (cd_fld_names ip) + rep_ip ip = mapM (rep_one_ip (cd_fld_spec ip)) (cd_fld_names ip) - rep_one_ip :: LBangType GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) + rep_one_ip :: HsConFieldSpec OnRecField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) rep_one_ip t n = do { MkC v <- lookupOcc (unLoc . foLabel $ unLoc n) - ; MkC ty <- repBangTy t + ; MkC ty <- repConFieldSpec t ; rep2 varBangTypeName [v,ty] } ------------ Types ------------------- ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1789,8 +1789,8 @@ instance ToHie (LocatedA (ConDecl GhcRn)) where PrefixCon _ xs -> scaled_args_scope xs InfixCon a b -> scaled_args_scope [a, b] RecCon x -> mkScope x - where scaled_args_scope :: [HsScaled on GhcRn (LHsType GhcRn)] -> Scope - scaled_args_scope = foldr combineScopes NoScope . map (mkScope . hsScaledThing) + where scaled_args_scope :: [HsConFieldSpec on GhcRn] -> Scope + scaled_args_scope = foldr combineScopes NoScope . map (mkScope . cfs_type) instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where toHie (L span decls) = concatM $ @@ -1798,6 +1798,9 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where , toHie decls ] +instance ToHie (HsConFieldSpec on GhcRn) where + toHie (CFS _ _ _ w t) = concatM [toHie (multAnnToHsType w), toHie t] + instance ToHie (TScoped (HsWildCardBndrs GhcRn (LocatedA (HsSigType GhcRn)))) where toHie (TS sc (HsWC names a)) = concatM $ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names @@ -2000,7 +2003,7 @@ instance HiePass p => ToHie (LocatedC [LocatedA (HsExpr (GhcPass p))]) where instance ToHie (LocatedA (ConDeclField GhcRn)) where toHie (L span field) = concatM $ makeNode field (locA span) : case field of ConDeclField _ fields typ doc -> - [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ hsScaledThing typ)) fields + [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ cfs_type typ)) fields , toHie typ , toHie doc ] ===================================== compiler/GHC/Parser.y ===================================== @@ -2598,7 +2598,7 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (HsScaled (HsUnannotated HsUnannOne (epUniTok $2)) $3) + (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3) Nothing))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -72,6 +72,7 @@ module GHC.Parser.PostProcess ( mkMultTy, mkMultAnn, mkMultField, + mkConFieldSpec, -- Token location mkTokenLocation, @@ -2337,11 +2338,11 @@ dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) -- Normal prefix constructor, e.g. data T = MkT A B C dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) - = PrefixCon noTypeArgs (map hsLinear (toList flds)) + = PrefixCon noTypeArgs (map hsPlainTypeField (toList flds)) -- Infix constructor, e.g. data T = Int :! Bool dataConBuilderDetails (L (EpAnn _ _ csl) (InfixDataConBuilder (L (EpAnn anc ann csll) lhs) _ rhs)) - = InfixCon (hsLinear (L (EpAnn anc ann (csl Semi.<> csll)) lhs)) (hsLinear rhs) + = InfixCon (hsPlainTypeField (L (EpAnn anc ann (csl Semi.<> csll)) lhs)) (hsPlainTypeField rhs) instance DisambTD DataConBuilder where @@ -2409,7 +2410,7 @@ checkNotPromotedDataCon IsPromoted (L l name) = mkUnboxedSumCon :: LHsType GhcPs -> ConTag -> Arity -> (LocatedN RdrName, HsConDeclH98Details GhcPs) mkUnboxedSumCon t tag arity = - (noLocA (getRdrName (sumDataCon tag arity)), PrefixCon noTypeArgs [hsLinear t]) + (noLocA (getRdrName (sumDataCon tag arity)), PrefixCon noTypeArgs [hsPlainTypeField t]) {- Note [Ambiguous syntactic categories] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3519,15 +3520,19 @@ mkMultAnn pct t@(L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) pct1 = epTokenWidenR pct (locA (getLoc t)) mkMultAnn pct t = HsMultAnn pct t -mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsScaled OnRecField GhcPs (LBangType GhcPs) +mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnRecField GhcPs mkMultField pct (L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) col t -- See #18888 for the use of (SourceText "1") above - = HsScaled (HsLinearAnn (pct1, col)) t + = mkConFieldSpec (HsLinearAnn (pct1, col)) t where -- The location of "%" combined with the location of "1". pct1 :: EpToken "%1" pct1 = epTokenWidenR pct (locA (getLoc t)) -mkMultField pct mult col t = HsScaled (HsExplicitMult (pct, col) mult) t +mkMultField pct mult col t = mkConFieldSpec (HsExplicitMult (pct, col) mult) t + +mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs +mkConFieldSpec mult (L _ (HsBangTy ann (HsBang unp str) t)) = CFS ann unp str mult t +mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t mkTokenLocation :: SrcSpan -> TokenLocation mkTokenLocation (UnhelpfulSpan _) = NoTokenLoc ===================================== compiler/GHC/Parser/PostProcess/Haddock.hs ===================================== @@ -788,12 +788,12 @@ getConDoc l = extendHdkA l $ liftHdkA $ getPrevNextDoc l -- Add documentation comment to a data constructor field. -- Used for PrefixCon and InfixCon. addHaddockConDeclFieldTy - :: HsScaled on GhcPs (LHsType GhcPs) - -> HdkA (HsScaled on GhcPs (LHsType GhcPs)) -addHaddockConDeclFieldTy (HsScaled mult (L l t)) = + :: HsConFieldSpec on GhcPs + -> HdkA (HsConFieldSpec on GhcPs) +addHaddockConDeclFieldTy (CFS ann unpack strict mult (L l t)) = extendHdkA (locA l) $ liftHdkA $ do mDoc <- getPrevNextDoc (locA l) - return (HsScaled mult (mkLHsDocTy (L l t) mDoc)) + return (CFS ann unpack strict mult (mkLHsDocTy (L l t) mDoc)) -- Add documentation comment to a data constructor field. -- Used for RecCon. @@ -909,6 +909,9 @@ We implement this in two steps: instance HasHaddock a => HasHaddock (HsScaled on GhcPs a) where addHaddock (HsScaled mult a) = HsScaled mult <$> addHaddock a +instance HasHaddock (HsConFieldSpec on GhcPs) where + addHaddock (CFS ann unp str mult a) = CFS ann unp str mult <$> addHaddock a + instance HasHaddock a => HasHaddock (HsWildCardBndrs GhcPs a) where addHaddock (HsWC _ t) = HsWC noExtField <$> addHaddock t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Rename.HsType ( lookupField, mkHsOpTyRn, rnLTyVar, - rnScaledLHsType, + rnHsConFieldSpec, -- Precence related stuff NegationHandling(..), @@ -450,16 +450,16 @@ rnLHsType ctxt ty = rnLHsTyKi (mkTyKiEnv ctxt TypeLevel RnTypeBody) ty rnLHsTypes :: HsDocContext -> [LHsType GhcPs] -> RnM ([LHsType GhcRn], FreeVars) rnLHsTypes doc tys = mapFvRn (rnLHsType doc) tys -rnScaledLHsType :: HsDocContext -> HsScaled on GhcPs (LHsType GhcPs) - -> RnM (HsScaled on GhcRn (LHsType GhcRn), FreeVars) -rnScaledLHsType doc = rnScaledLHsTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) +rnHsConFieldSpec :: HsDocContext -> HsConFieldSpec on GhcPs + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpec doc = rnHsConFieldSpecTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) -rnScaledLHsTyKi :: RnTyKiEnv -> HsScaled on GhcPs (LHsType GhcPs) - -> RnM (HsScaled on GhcRn (LHsType GhcRn), FreeVars) -rnScaledLHsTyKi env (HsScaled w ty) = do +rnHsConFieldSpecTyKi :: RnTyKiEnv -> HsConFieldSpec on GhcPs + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpecTyKi env (CFS ext unp str w ty) = do (w' , fvs_w) <- rnHsMultAnnOn env w (ty', fvs) <- rnLHsTyKi env ty - return (HsScaled w' ty', fvs `plusFV` fvs_w) + return (CFS ext unp str w' ty', fvs `plusFV` fvs_w) rnHsType :: HsDocContext -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) @@ -1339,7 +1339,7 @@ rnField :: FastStringEnv FieldLabel -> RnTyKiEnv -> LConDeclField GhcPs -> RnM (LConDeclField GhcRn, FreeVars) rnField fl_env env (L l (ConDeclField _ names ty haddock_doc)) = do { let new_names = map (fmap (lookupField fl_env)) names - ; (new_ty, fvs) <- rnScaledLHsTyKi env ty + ; (new_ty, fvs) <- rnHsConFieldSpecTyKi env ty ; haddock_doc' <- traverse rnLHsDoc haddock_doc ; return (L l (ConDeclField noExtField new_names new_ty haddock_doc') , fvs) } @@ -2035,7 +2035,7 @@ extractConDeclGADTDetailsTyVars :: HsConDeclGADTDetails GhcPs -> FreeKiTyVars -> FreeKiTyVars extractConDeclGADTDetailsTyVars con_args = case con_args of PrefixConGADT _ args -> extract_scaled_ltys args - RecConGADT _ (L _ flds) -> extract_scaled_ltys $ map (cd_fld_type . unLoc) $ flds + RecConGADT _ (L _ flds) -> extract_scaled_ltys $ map (cd_fld_spec . unLoc) $ flds -- | Get type/kind variables mentioned in the kind signature, preserving -- left-to-right order: @@ -2051,13 +2051,13 @@ extractDataDefnKindVars (HsDataDefn { dd_kindSig = ksig }) extract_lctxt :: LHsContext GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lctxt ctxt = extract_ltys (unLoc ctxt) -extract_scaled_ltys :: [HsScaled on GhcPs (LHsType GhcPs)] +extract_scaled_ltys :: [HsConFieldSpec on GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_scaled_ltys args acc = foldr extract_scaled_lty acc args -extract_scaled_lty :: HsScaled on GhcPs (LHsType GhcPs) +extract_scaled_lty :: HsConFieldSpec on GhcPs -> FreeKiTyVars -> FreeKiTyVars -extract_scaled_lty (HsScaled m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc +extract_scaled_lty (CFS _ _ _ m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc extract_ltys :: [LHsType GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_ltys tys acc = foldr extract_lty acc tys @@ -2068,7 +2068,7 @@ extract_lty (L _ ty) acc HsTyVar _ _ ltv -> extract_tv ltv acc HsBangTy _ _ ty -> extract_lty ty acc HsRecTy _ flds -> foldr (extract_scaled_lty - . cd_fld_type . unLoc) acc + . cd_fld_spec . unLoc) acc flds HsAppTy _ ty1 ty2 -> extract_lty ty1 $ extract_lty ty2 acc ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1928,9 +1928,7 @@ rnDataDefn doc (HsDataDefn { dd_cType = cType, dd_ctxt = context, dd_cons = cond has_labelled_fields _ = False has_strictness_flags condecl - = any (is_strict . getBangStrictness . hsScaledThing) (con_args condecl) - - is_strict (HsSrcBang _ (HsBang _ s)) = isSrcStrict s + = any (isSrcStrict . cfs_bang) (con_args condecl) con_args (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = args con_args (ConDeclH98 { con_args = PrefixCon _ args }) = args @@ -2483,11 +2481,11 @@ rnConDeclH98Details :: -> HsConDeclH98Details GhcPs -> RnM (HsConDeclH98Details GhcRn, FreeVars) rnConDeclH98Details _ doc (PrefixCon _ tys) - = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys + = do { (new_tys, fvs) <- mapFvRn (rnHsConFieldSpec doc) tys ; return (PrefixCon noTypeArgs new_tys, fvs) } rnConDeclH98Details _ doc (InfixCon ty1 ty2) - = do { (new_ty1, fvs1) <- rnScaledLHsType doc ty1 - ; (new_ty2, fvs2) <- rnScaledLHsType doc ty2 + = do { (new_ty1, fvs1) <- rnHsConFieldSpec doc ty1 + ; (new_ty2, fvs2) <- rnHsConFieldSpec doc ty2 ; return (InfixCon new_ty1 new_ty2, fvs1 `plusFV` fvs2) } rnConDeclH98Details con doc (RecCon flds) = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds @@ -2499,7 +2497,7 @@ rnConDeclGADTDetails :: -> HsConDeclGADTDetails GhcPs -> RnM (HsConDeclGADTDetails GhcRn, FreeVars) rnConDeclGADTDetails _ doc (PrefixConGADT _ tys) - = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys + = do { (new_tys, fvs) <- mapFvRn (rnHsConFieldSpec doc) tys ; return (PrefixConGADT noExtField new_tys, fvs) } rnConDeclGADTDetails con doc (RecConGADT _ flds) = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -283,7 +283,7 @@ no_anon_wc_ty lty = go lty HsKindSig _ ty kind -> go ty && go kind HsDocTy _ ty _ -> go ty HsBangTy _ _ ty -> go ty - HsRecTy _ flds -> gos $ concatMap (hsScaledToHsTypes . cd_fld_type . unLoc) flds + HsRecTy _ flds -> gos $ concatMap (hsConFieldSpecToHsTypes . cd_fld_spec . unLoc) flds HsExplicitListTy _ _ tys -> gos tys HsExplicitTupleTy _ _ tys -> gos tys HsForAllTy { hst_tele = tele ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1799,11 +1799,11 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled on GhcRn (LHsType GhcRn)] -> TcM () +kcConArgTys :: NewOrData -> TcKind -> [HsConFieldSpec on GhcRn] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) + ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -1813,14 +1813,14 @@ kcConH98Args new_or_data res_kind con_args = case con_args of PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ - map (cd_fld_type . unLoc) flds + map (cd_fld_spec . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () kcConGADTArgs new_or_data res_kind con_args = case con_args of PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ - map (cd_fld_type . unLoc) flds + map (cd_fld_spec . unLoc) flds kcConDecls :: Foldable f => NewOrData @@ -3893,7 +3893,7 @@ tcConIsInfixGADT con details RecConGADT{} -> return False PrefixConGADT _ arg_tys -- See Note [Infix GADT constructors] | isSymOcc (getOccName con) - , [_ty1,_ty2] <- map hsScaledThing arg_tys + , [_ty1,_ty2] <- arg_tys -> do { fix_env <- getFixityEnv ; return (con `elemNameEnv` fix_env) } | otherwise -> return False @@ -3924,13 +3924,13 @@ tcConGADTArgs exp_kind (RecConGADT _ fields) tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes - -> HsScaled on GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) -tcConArg exp_kind (HsScaled w bty) + -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) +tcConArg exp_kind (CFS (_, src) unp str w bty) = do { traceTc "tcConArg 1" (ppr bty) ; arg_ty <- tcCheckLHsTypeInContext (getBangType bty) exp_kind ; w' <- tcDataConMult w ; traceTc "tcConArg 2" (ppr bty) - ; return (Scaled w' arg_ty, getBangStrictness bty) } + ; return (Scaled w' arg_ty, HsSrcBang src (HsBang unp str)) } tcRecConDeclFields :: ContextKind -> LocatedL [LConDeclField GhcRn] @@ -3939,7 +3939,7 @@ tcRecConDeclFields exp_kind fields = mapM (tcConArg exp_kind) btys where -- We need a one-to-one mapping from field_names to btys - combined = map (\(L _ f) -> (cd_fld_names f, cd_fld_type f)) + combined = map (\(L _ f) -> (cd_fld_names f, cd_fld_spec f)) (unLoc fields) explode (ns,ty) = zip ns (repeat ty) exploded = concatMap explode combined ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -3,6 +3,7 @@ {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE DataKinds #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -689,7 +690,7 @@ cvtConstr :: TH.Name -- ^ name of first constructor of parent type cvtConstr _ do_con_name (NormalC c strtys) = do { c' <- do_con_name c ; tys' <- mapM cvt_arg strtys - ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing (PrefixCon noTypeArgs (map hsLinear tys')) } + ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing (PrefixCon noTypeArgs tys') } cvtConstr parent_con do_con_name (RecC c varstrtys) = do { c' <- do_con_name c @@ -702,7 +703,7 @@ cvtConstr _ do_con_name (InfixC st1 c st2) ; st1' <- cvt_arg st1 ; st2' <- cvt_arg st2 ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing - (InfixCon (hsLinear st1') (hsLinear st2')) } + (InfixCon st1' st2') } cvtConstr parent_con do_con_name (ForallC tvs ctxt con) = do { tvs' <- cvtTvs tvs @@ -741,7 +742,7 @@ cvtConstr _ do_con_name (GadtC c strtys ty) = case nonEmpty c of { c' <- mapM do_con_name c ; args <- mapM cvt_arg strtys ; ty' <- cvtType ty - ; mk_gadt_decl c' (PrefixConGADT noExtField $ map hsLinear args) ty'} + ; mk_gadt_decl c' (PrefixConGADT noExtField args) ty'} cvtConstr parent_con do_con_name (RecGadtC c varstrtys ty) = case nonEmpty c of Nothing -> failWith RecGadtNoCons @@ -775,13 +776,13 @@ cvtSrcStrictness NoSourceStrictness = NoSrcStrict cvtSrcStrictness SourceLazy = SrcLazy cvtSrcStrictness SourceStrict = SrcStrict -cvt_arg :: (TH.Bang, TH.Type) -> CvtM (LHsType GhcPs) +cvt_arg :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) cvt_arg (Bang su ss, ty) = do { ty'' <- cvtType ty ; let ty' = parenthesizeHsType appPrec ty'' su' = cvtSrcUnpackedness su ss' = cvtSrcStrictness ss - ; returnLA $ HsBangTy (noAnn, NoSourceText) (HsBang su' ss') ty' } + ; return $ CFS noAnn su' ss' hsNoMultAnn ty' } cvt_id_arg :: TH.Name -- ^ parent constructor name -> (TH.Name, TH.Bang, TH.Type) -> CvtM (LConDeclField GhcPs) @@ -792,7 +793,7 @@ cvt_id_arg parent_con (i, str, ty) { cd_fld_ext = noExtField , cd_fld_names = [L (l2l li) $ FieldOcc noExtField (L li i')] - , cd_fld_type = hsNoMultAnn ty' + , cd_fld_spec = ty' , cd_fld_doc = Nothing} } cvtDerivs :: [TH.DerivClause] -> CvtM (HsDeriving GhcPs) ===================================== compiler/Language/Haskell/Syntax/Decls.hs ===================================== @@ -1122,7 +1122,7 @@ or contexts in two parts: -- | The arguments in a Haskell98-style data constructor. type HsConDeclH98Details pass - = HsConDetails Void (HsScaled OnArrow pass (LBangType pass)) (XRec pass [LConDeclField pass]) + = HsConDetails Void (HsConFieldSpec OnArrow pass) (XRec pass [LConDeclField pass]) -- The Void argument to HsConDetails here is a reflection of the fact that -- type applications are not allowed in data constructor declarations. @@ -1133,7 +1133,7 @@ type HsConDeclH98Details pass -- derived Show instances—see Note [Infix GADT constructors] in -- GHC.Tc.TyCl—but that is an orthogonal concern.) data HsConDeclGADTDetails pass - = PrefixConGADT !(XPrefixConGADT pass) [HsScaled OnArrow pass (LBangType pass)] + = PrefixConGADT !(XPrefixConGADT pass) [HsConFieldSpec OnArrow pass] | RecConGADT !(XRecConGADT pass) (XRec pass [LConDeclField pass]) | XConDeclGADTDetails !(XXConDeclGADTDetails pass) ===================================== compiler/Language/Haskell/Syntax/Extension.hs ===================================== @@ -682,6 +682,11 @@ type family XXTyVarBndr x type family XConDeclField x type family XXConDeclField x +-- --------------------------------------------------------------------- +-- ConFieldSpec type families +type family XConFieldSpec x +type family XXConFieldSpec x + -- --------------------------------------------------------------------- -- FieldOcc type families type family XCFieldOcc x ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -23,7 +23,7 @@ GHC.Hs.Type: Abstract syntax: user-defined types -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* module Language.Haskell.Syntax.Type ( HsScaled(..), - hsMultIsLinear, hsScaledThing, hsScaledGeneralize, + hsMultIsLinear, hsScaledThing, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), pattern HsUnrestrictedArrow, XUnannotated, XLinearAnn, XExplicitMult, XXMultAnnOn, @@ -57,6 +57,7 @@ module Language.Haskell.Syntax.Type ( ConDeclField(..), LConDeclField, HsConDetails(..), noTypeArgs, + HsConFieldSpec(..), hsConFieldSpecGeneralize, FieldOcc(..), LFieldOcc, @@ -67,7 +68,7 @@ module Language.Haskell.Syntax.Type ( import {-# SOURCE #-} Language.Haskell.Syntax.Expr ( HsUntypedSplice ) -import Language.Haskell.Syntax.Basic ( HsBang(..) ) +import Language.Haskell.Syntax.Basic ( HsBang(..), SrcStrictness, SrcUnpackedness ) import Language.Haskell.Syntax.Extension import Language.Haskell.Syntax.Specificity @@ -983,13 +984,10 @@ type family XXMultAnnOn (on :: HsMultAnnOnWhat) mult p data HsScaled on pass a = HsScaled (HsMultAnnOn on (LHsType pass) pass) a deriving (Functor) -hsScaledGeneralize :: HsScaled on pass a -> HsScaled on1 pass a -hsScaledGeneralize = unsafeCoerce - -hsMultIsLinear :: Bool -> HsScaled on pass a -> Bool -hsMultIsLinear _ (HsScaled (HsUnannotated HsUnannOne _) _) = True -hsMultIsLinear linear (HsScaled (HsUnannotated HsUnannMany _) _) = not linear -hsMultIsLinear _ (HsScaled HsLinearAnn{} _) = True +hsMultIsLinear :: Bool -> HsMultAnnOn on mult pass -> Bool +hsMultIsLinear _ (HsUnannotated HsUnannOne _) = True +hsMultIsLinear linear (HsUnannotated HsUnannMany _) = not linear +hsMultIsLinear _ HsLinearAnn{} = True hsMultIsLinear _ _ = False hsScaledThing :: HsScaled on pass a -> a @@ -1098,7 +1096,7 @@ data ConDeclField pass -- Record fields have Haddock docs on them = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_type :: HsScaled OnRecField pass (LBangType pass), + cd_fld_spec :: HsConFieldSpec OnRecField pass, cd_fld_doc :: Maybe (LHsDoc pass)} | XConDeclField !(XXConDeclField pass) @@ -1129,6 +1127,16 @@ data HsConDetails tyarg arg rec noTypeArgs :: [Void] noTypeArgs = [] +data HsConFieldSpec on pass + = CFS { cfs_ext :: XConFieldSpec pass + , cfs_unpack :: SrcUnpackedness + , cfs_bang :: SrcStrictness + , cfs_multiplicity :: HsMultAnnOn on (LHsType pass) pass + , cfs_type :: LHsType pass } + +hsConFieldSpecGeneralize :: HsConFieldSpec on pass -> HsConFieldSpec on1 pass +hsConFieldSpecGeneralize = unsafeCoerce + {- Note [ConDeclField pass] ~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4448,13 +4448,29 @@ instance (ExactPrint a) => ExactPrint (HsScaled OnArrow GhcPs a) where arr' <- markArrow arr return (HsScaled arr' t') -instance (ExactPrint a) => ExactPrint (HsScaled OnRecField GhcPs a) where +-- instance (ExactPrint a) => ExactPrint (HsScaled OnRecField GhcPs a) where +-- getAnnotationEntry = const NoEntryVal +-- setAnnotationAnchor a _ _ _ = a +-- exact (HsScaled mult t) = do +-- mult' <- markRecFieldMult mult +-- t' <- markAnnotated t +-- return (HsScaled mult' t') + +instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (HsScaled mult t) = do + exact (CFS unp str arr t) = do + t' <- markAnnotated t + arr' <- markArrow arr + return (CFS unp str arr' t') + +instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where + getAnnotationEntry = const NoEntryVal + setAnnotationAnchor a _ _ _ = a + exact (CFS unp str mult t) = do mult' <- markRecFieldMult mult t' <- markAnnotated t - return (HsScaled mult' t') + return (CFS unp str mult' t') -- --------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs ===================================== @@ -295,14 +295,14 @@ ppCtor sDocContext dat subdocs con at ConDeclH98{con_args = con_args'} = -- AZ:TODO get rid of the concatMap concatMap (lookupCon sDocContext subdocs) [con_name con] ++ f con_args' where - f :: HsConDetails v (HsScaled on GhcRn (LHsType GhcRn)) (LocatedL [LocatedA (ConDeclField GhcRn)]) -> [String] - f (PrefixCon _ args) = [typeSig name $ (map hsScaledThing args) ++ [resType]] + f :: HsConDetails v (HsConFieldSpec on GhcRn) (LocatedL [LocatedA (ConDeclField GhcRn)]) -> [String] + f (PrefixCon _ args) = [typeSig name $ (map cfs_type args) ++ [resType]] f (InfixCon a1 a2) = f $ PrefixCon [] [a1, a2] f (RecCon (L _ recs)) = - f (PrefixCon [] $ map (cd_fld_type . unLoc) recs) + f (PrefixCon [] $ map (cd_fld_spec . unLoc) recs) ++ concat [ (concatMap (lookupCon sDocContext subdocs . noLocA . unLoc . foLabel . unLoc) (cd_fld_names r)) - ++ [out sDocContext (map (foExt . unLoc) $ cd_fld_names r) `typeSig` [resType, hsScaledThing $ cd_fld_type r]] + ++ [out sDocContext (map (foExt . unLoc) $ cd_fld_names r) `typeSig` [resType, cfs_type $ cd_fld_spec r]] | r <- map unLoc recs ] @@ -356,8 +356,8 @@ ppCtor Nothing -> tau_ty tau_ty = foldr mkFunTy res_ty $ case args of - PrefixConGADT _ pos_args -> map hsScaledThing pos_args - RecConGADT _ (L _ flds) -> map (hsScaledThing . cd_fld_type . unL) flds + PrefixConGADT _ pos_args -> map cfs_type pos_args + RecConGADT _ (L _ flds) -> map (cfs_type . cd_fld_spec . unL) flds mkFunTy a b = noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) a b) ppFixity :: SDocContext -> (Name, Fixity) -> [String] ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -964,7 +964,7 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = hsep [ header_ , ppOcc - , hsep (map (ppLParendType unicode . hsScaledThing) args) + , hsep (map (ppLParendType unicode . cfs_type) args) ] -- Record constructor, e.g. 'Identity { runIdentity :: a }' RecCon _ -> header_ <+> ppOcc @@ -974,9 +974,9 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = | otherwise -> hsep [ header_ - , ppLParendType unicode (hsScaledThing arg1) + , ppLParendType unicode (cfs_type arg1) , ppOccInfix - , ppLParendType unicode (hsScaledThing arg2) + , ppLParendType unicode (cfs_type arg2) ] ConDeclGADT{} | hasArgDocs || not (isEmpty fieldPart) -> ppOcc @@ -993,15 +993,15 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = -- GADT record declarations RecConGADT _ _ -> doConstrArgsWithDocs [] -- GADT prefix data constructors - PrefixConGADT _ args | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing args) + PrefixConGADT _ args | hasArgDocs -> doConstrArgsWithDocs (map cfs_type args) _ -> empty ConDeclH98{con_args = con_args'} -> case con_args' of -- H98 record declarations RecCon (L _ fields) -> doRecordFields fields -- H98 prefix data constructors - PrefixCon _ args | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing args) + PrefixCon _ args | hasArgDocs -> doConstrArgsWithDocs (map cfs_type args) -- H98 infix data constructor - InfixCon arg1 arg2 | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing [arg1, arg2]) + InfixCon arg1 arg2 | hasArgDocs -> doConstrArgsWithDocs (map cfs_type [arg1, arg2]) _ -> empty doRecordFields fields = @@ -1035,7 +1035,7 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = decltt ( cat (punctuate comma (map (ppBinder . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode ltype (dcolon unicode) - <+> ppLType unicode (hsScaledThing ltype) + <+> ppLType unicode (cfs_type ltype) ) <-> rDoc mbDoc where @@ -1047,8 +1047,8 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd -ppRecFieldMultAnn :: Bool -> HsScaled on DocNameI a -> LaTeX -> LaTeX -ppRecFieldMultAnn unicode (HsScaled arr _) following = case arr of +ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX +ppRecFieldMultAnn unicode (CFS _ _ arr _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1350,7 +1350,7 @@ ppShortConstrParts summary dataInst con unicode qual = in case det of -- Prefix constructor, e.g. 'Just a' PrefixCon _ args -> - ( header_ <+> hsep (ppOcc : map (ppLParendType unicode qual HideEmptyContexts . hsScaledThing) args) + ( header_ <+> hsep (ppOcc : map (ppLParendType unicode qual HideEmptyContexts . cfs_type) args) , noHtml , noHtml ) @@ -1368,9 +1368,9 @@ ppShortConstrParts summary dataInst con unicode qual = InfixCon arg1 arg2 -> ( header_ <+> hsep - [ ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg1) + [ ppLParendType unicode qual HideEmptyContexts (cfs_type arg1) , ppOccInfix - , ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg2) + , ppLParendType unicode qual HideEmptyContexts (cfs_type arg2) ] , noHtml , noHtml @@ -1431,7 +1431,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = | otherwise -> hsep [ header_ <+> ppOcc - , hsep (map (ppLParendType unicode qual HideEmptyContexts . hsScaledThing) args) + , hsep (map (ppLParendType unicode qual HideEmptyContexts . cfs_type) args) , fixity ] -- Record constructor, e.g. 'Identity { runIdentity :: a }' @@ -1441,9 +1441,9 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = | hasArgDocs -> header_ <+> ppOcc <+> fixity | otherwise -> hsep - [ header_ <+> ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg1) + [ header_ <+> ppLParendType unicode qual HideEmptyContexts (cfs_type arg1) , ppOccInfix - , ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg2) + , ppLParendType unicode qual HideEmptyContexts (cfs_type arg2) , fixity ] -- GADT constructor, e.g. 'Foo :: Int -> Foo' @@ -1483,7 +1483,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = doConstrArgsWithDocs args = subFields pkg qual $ case con of ConDeclH98{} -> [ (ppLParendType unicode qual HideEmptyContexts arg, mdoc, []) - | (i, arg) <- zip [0 ..] (map hsScaledThing args) + | (i, arg) <- zip [0 ..] (map cfs_type args) , let mdoc = Map.lookup i argDocs ] ConDeclGADT{} -> @@ -1543,7 +1543,7 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = ] ) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) - <+> ppLType unicode qual HideEmptyContexts (hsScaledThing ltype) + <+> ppLType unicode qual HideEmptyContexts (cfs_type ltype) , mbDoc , [] ) @@ -1555,8 +1555,8 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd -ppRecFieldMultAnn :: Unicode -> Qualification -> HsScaled on DocNameI a -> Html -> Html -ppRecFieldMultAnn unicode qual (HsScaled arr _) following = case arr of +ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html +ppRecFieldMultAnn unicode qual (CFS _ _ arr _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following @@ -1565,7 +1565,7 @@ ppShortField :: Bool -> Unicode -> Qualification -> ConDeclField DocNameI -> Htm ppShortField summary unicode qual (ConDeclField _ names ltype _) = hsep (punctuate comma (map ((ppBinder summary) . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) - <+> ppLType unicode qual HideEmptyContexts (hsScaledThing ltype) + <+> ppLType unicode qual HideEmptyContexts (cfs_type ltype) -- | Pretty print an expanded pattern (for bundled patterns) ppSideBySidePat ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -494,13 +494,10 @@ synifyDataCon use_gadt_syntax dc = linear_tys = zipWith - ( \(Scaled mult ty) bang -> + ( \(Scaled mult ty) (HsSrcBang _ (HsBang unp str)) -> let tySyn = synifyType WithinType [] ty multSyn = synifyMultRec [] mult - bangTy = case bang of - (HsSrcBang _ (HsBang NoSrcUnpack NoSrcStrict)) -> tySyn - (HsSrcBang src bang') -> noLocA $ HsBangTy (noAnn, src) bang' tySyn - in HsScaled multSyn bangTy + in CFS unp str multSyn tySyn ) arg_tys (dataConSrcBangs dc) @@ -518,15 +515,15 @@ synifyDataCon use_gadt_syntax dc = mk_h98_arg_tys = case (use_named_field_syntax, use_infix_syntax) of (True, True) -> Left "synifyDataCon: contradiction!" (True, False) -> return $ RecCon (noLocA field_tys) - (False, False) -> return $ PrefixCon noTypeArgs (map hsScaledGeneralize linear_tys) - (False, True) -> case map hsScaledGeneralize linear_tys of + (False, False) -> return $ PrefixCon noTypeArgs (map hsConFieldSpecGeneralize linear_tys) + (False, True) -> case map hsConFieldSpecGeneralize linear_tys of [a, b] -> return $ InfixCon a b _ -> Left "synifyDataCon: infix with non-2 args?" mk_gadt_arg_tys :: HsConDeclGADTDetails GhcRn mk_gadt_arg_tys | use_named_field_syntax = RecConGADT noExtField (noLocA field_tys) - | otherwise = PrefixConGADT noExtField (map hsScaledGeneralize linear_tys) + | otherwise = PrefixConGADT noExtField (map hsConFieldSpecGeneralize linear_tys) in -- finally we get synifyDataCon's result! if use_gadt_syntax ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -220,7 +220,7 @@ getGADTConType -- tau_ty :: LHsType DocNameI tau_ty = case args of RecConGADT _ flds -> mkFunTy (noLocA (HsRecTy noAnn (unLoc flds))) res_ty - PrefixConGADT _ pos_args -> foldr mkFunTy res_ty (map hsScaledThing pos_args) + PrefixConGADT _ pos_args -> foldr mkFunTy res_ty (map cfs_type pos_args) mkFunTy :: LHsType DocNameI -> LHsType DocNameI -> LHsType DocNameI mkFunTy a b = noLocA (HsFunTy noAnn (HsUnrestrictedArrow noExtField) a b) @@ -361,8 +361,8 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] field_avail (L _ (ConDeclField _ fs _ _)) = all (\f -> (unLoc . foLabel . unLoc $ f) `elem` names) fs - field_types :: [LConDeclField GhcRn] -> [HsScaled OnArrow GhcRn (LBangType GhcRn)] - field_types flds = [hsScaledGeneralize t | L _ (ConDeclField _ _ t _) <- flds] + field_types :: [LConDeclField GhcRn] -> [HsConFieldSpec OnArrow GhcRn] + field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t _) <- flds] keep _ = Nothing restrictDecls :: [Name] -> [LSig GhcRn] -> [LSig GhcRn] @@ -513,7 +513,7 @@ reparenBndrKind v at XBndrKind{} = v -- | Add parenthesis around the types in a 'ConDeclField' (see 'reparenTypePrec') reparenConDeclField :: XRecCond a => ConDeclField a -> ConDeclField a -reparenConDeclField (ConDeclField x n t d) = ConDeclField x n (fmap reparenLType t) d +reparenConDeclField (ConDeclField x n (CFS unp str m t) d) = ConDeclField x n (CFS unp str m (reparenLType t)) d reparenConDeclField c at XConDeclField{} = c ------------------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Create.hs ===================================== @@ -962,12 +962,12 @@ extractPatternSyn nm t tvs cons = let args = case con of ConDeclH98{con_args = con_args'} -> case con_args' of - PrefixCon _ args' -> map hsScaledThing args' - RecCon (L _ fields) -> hsScaledThing . cd_fld_type . unLoc <$> fields - InfixCon arg1 arg2 -> map hsScaledThing [arg1, arg2] + PrefixCon _ args' -> map cfs_type args' + RecCon (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields + InfixCon arg1 arg2 -> map cfs_type [arg1, arg2] ConDeclGADT{con_g_args = con_args'} -> case con_args' of - PrefixConGADT _ args' -> map hsScaledThing args' - RecConGADT _ (L _ fields) -> hsScaledThing . cd_fld_type . unLoc <$> fields + PrefixConGADT _ args' -> map cfs_type args' + RecConGADT _ (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields typ = longArrow args (data_ty con) typ' = case con of @@ -999,7 +999,7 @@ extractRecSel nm t tvs (L _ con : rest) = case getRecConArgs_maybe con of Just (L _ fields) | ((l, L _ (ConDeclField _ _nn ty _)) : _) <- matching_fields fields -> - pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (getBangType $ hsScaledThing ty)))))) + pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (cfs_type ty)))))) -- TODO : was getBangType $ hsScaledThing ty _ -> extractRecSel nm t tvs rest where matching_fields :: [LConDeclField GhcRn] -> [(SrcSpan, LConDeclField GhcRn)] ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -718,10 +718,10 @@ renameCon } ) -renameHsScaled - :: HsScaled on GhcRn (LHsType GhcRn) - -> RnM (HsScaled on DocNameI (LHsType DocNameI)) -renameHsScaled (HsScaled w ty) = HsScaled <$> renameMultAnnOn w <*> renameLType ty +renameHsConFieldSpec + :: HsConFieldSpec on GhcRn + -> RnM (HsConFieldSpec on DocNameI) +renameHsConFieldSpec (CFS unp str w ty) = CFS unp str <$> renameMultAnnOn w <*> renameLType ty renameH98Details :: HsConDeclH98Details GhcRn @@ -729,10 +729,10 @@ renameH98Details renameH98Details (RecCon (L l fields)) = do fields' <- mapM renameConDeclFieldField fields return (RecCon (L (locA l) fields')) -renameH98Details (PrefixCon ts ps) = PrefixCon ts <$> mapM renameHsScaled ps +renameH98Details (PrefixCon ts ps) = PrefixCon ts <$> mapM renameHsConFieldSpec ps renameH98Details (InfixCon a b) = do - a' <- renameHsScaled a - b' <- renameHsScaled b + a' <- renameHsConFieldSpec a + b' <- renameHsConFieldSpec b return (InfixCon a' b') renameGADTDetails @@ -741,12 +741,12 @@ renameGADTDetails renameGADTDetails (RecConGADT _ (L l fields)) = do fields' <- mapM renameConDeclFieldField fields return (RecConGADT noExtField (L (locA l) fields')) -renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsScaled ps +renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsConFieldSpec ps renameConDeclFieldField :: LConDeclField GhcRn -> RnM (LConDeclField DocNameI) renameConDeclFieldField (L l (ConDeclField _ names t doc)) = do names' <- mapM renameLFieldOcc names - t' <- renameHsScaled t + t' <- renameHsConFieldSpec t doc' <- mapM renameLDocHsSyn doc return $ L (locA l) (ConDeclField noExtField names' t' doc') ===================================== utils/haddock/haddock-api/src/Haddock/Types.hs ===================================== @@ -964,6 +964,9 @@ type instance XXLHsQTyVars DocNameI = DataConCantHappen type instance XConDeclField DocNameI = NoExtField type instance XXConDeclField DocNameI = DataConCantHappen +type instance XConFieldSpec DocNameI = NoExtField +type instance XXConFieldSpec DocNameI = DataConCantHappen + type instance XXPat DocNameI = DataConCantHappen type instance XXHsBindsLR DocNameI a = DataConCantHappen View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/618fdaa70bfbfd424263efc549762087701425a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/618fdaa70bfbfd424263efc549762087701425a7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 11:22:22 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 09 Jan 2025 06:22:22 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] driver: Store the HomePackageTable in a mutable reference Message-ID: <677fb16e3967d_26bbcbe3e874cb@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 49fa34c0 by Rodrigo Mesquita at 2025-01-09T11:22:10+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/49fa34c003f0e24089936f975783fafcd1203728 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/49fa34c003f0e24089936f975783fafcd1203728 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 11:45:30 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 09 Jan 2025 06:45:30 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] driver: Store the HomePackageTable in a mutable reference Message-ID: <677fb6dad50bd_26bbc84fe0414821@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: c4e444e0 by Rodrigo Mesquita at 2025-01-09T11:45:22+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c4e444e00f1e8343cc44b3676b99a9d974776dac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c4e444e00f1e8343cc44b3676b99a9d974776dac You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 11:46:30 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 09 Jan 2025 06:46:30 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] driver: Store the HomePackageTable in a mutable reference Message-ID: <677fb716b083e_26bbc84fe0415279@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 7abb46d6 by Rodrigo Mesquita at 2025-01-09T11:46:20+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7abb46d6586934ced5a43c49d18a6b8d7b24d5fa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7abb46d6586934ced5a43c49d18a6b8d7b24d5fa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 12:43:49 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 09 Jan 2025 07:43:49 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add HsConFieldSpec Message-ID: <677fc484f3fde_21de7cbcca0441aa@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: a28732e9 by Sjoerd Visscher at 2025-01-09T13:43:22+01:00 Add HsConFieldSpec - - - - - 26 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Type.hs - utils/check-exact/ExactPrint.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/Rename.hs - utils/haddock/haddock-api/src/Haddock/Types.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -881,11 +881,11 @@ pprConDecl (ConDeclH98 { con_name = L _ con where -- In ppr_details: let's not print the multiplicities (they are always 1, by -- definition) as they do not appear in an actual declaration. - ppr_details (InfixCon t1 t2) = hsep [ppr (hsScaledThing t1), + ppr_details (InfixCon t1 t2) = hsep [pprHsConFieldSpecNoMult t1, pprInfixOcc con, - ppr (hsScaledThing t2)] + pprHsConFieldSpecNoMult t2] ppr_details (PrefixCon _ tys) = hsep (pprPrefixOcc con - : map (pprHsType . unLoc . hsScaledThing) tys) + : map pprHsConFieldSpecNoMult tys) ppr_details (RecCon fields) = pprPrefixOcc con <+> pprConDeclFields (unLoc fields) @@ -896,7 +896,7 @@ pprConDecl (ConDeclGADT { con_names = cons, con_bndrs = L _ outer_bndrs <+> (sep [pprHsOuterSigTyVarBndrs outer_bndrs <+> pprLHsContext mcxt, sep (ppr_args args ++ [ppr res_ty]) ]) where - ppr_args (PrefixConGADT _ args) = map (\(HsScaled arr t) -> ppr t <+> ppr_arr arr) args + ppr_args (PrefixConGADT _ args) = map (pprHsConFieldSpecWith (\arr tyDoc -> tyDoc <+> ppr_arr arr)) args ppr_args (RecConGADT _ fields) = [pprConDeclFields (unLoc fields) <+> arrow] -- Display linear arrows as unrestricted with -XNoLinearTypes ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -535,7 +535,7 @@ deriving instance Data (HsTyLit GhcPs) deriving instance Data (HsTyLit GhcRn) deriving instance Data (HsTyLit GhcTc) --- deriving instance (Data mult, DataIdLR p p) => Data (HsArrowOf mult p) +-- deriving instance (Data mult, DataIdLR p p, Typeable on) => Data (HsMultAnnOn on mult p) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsType GhcPs)) GhcPs) deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsType GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcRn)) GhcRn) @@ -545,7 +545,7 @@ deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsExpr deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcTc)) GhcTc) --- deriving instance (DataIdLR p p) => Data (HsScaled p a) +-- deriving instance (DataIdLR p p, Typeable on) => Data (HsScaled on p a) deriving instance Data thing => Data (HsScaled OnArrow GhcPs thing) deriving instance Data thing => Data (HsScaled OnRecField GhcPs thing) deriving instance (Data thing, Typeable on) => Data (HsScaled on GhcRn thing) @@ -561,6 +561,12 @@ deriving instance Data (ConDeclField GhcPs) deriving instance Data (ConDeclField GhcRn) deriving instance Data (ConDeclField GhcTc) +-- deriving instance (DataIdLR p p, Typeable on) => Data (HsConFieldSpec on p) +deriving instance Data (HsConFieldSpec OnArrow GhcPs) +deriving instance Data (HsConFieldSpec OnRecField GhcPs) +deriving instance Typeable on => Data (HsConFieldSpec on GhcRn) +deriving instance Typeable on => Data (HsConFieldSpec on GhcTc) + -- deriving instance (DataId p) => Data (FieldOcc p) deriving instance Data (FieldOcc GhcPs) deriving instance Data (FieldOcc GhcRn) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -25,11 +25,11 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( Mult, HsScaled(..), - hsMultIsLinear, hsScaledThing, hsScaledToHsTypes, + hsMultIsLinear, hsScaledThing, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, EpLinearArrow(..), - hsLinear, hsNoMultAnn, isUnrestricted, + hsNoMultAnn, isUnrestricted, pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, @@ -61,6 +61,8 @@ module GHC.Hs.Type ( ConDeclField(..), LConDeclField, pprConDeclFields, HsConDetails(..), noTypeArgs, + HsConFieldSpec(..), pprHsConFieldSpecWith, pprHsConFieldSpecNoMult, + hsPlainTypeField, hsConFieldSpecToHsTypes, FieldOcc(..), LFieldOcc, mkFieldOcc, fieldOccRdrName, fieldOccLRdrName, @@ -482,6 +484,8 @@ type instance XSpliceTy GhcTc = Kind type instance XDocTy (GhcPass _) = NoExtField type instance XBangTy (GhcPass _) = ((EpaLocation, EpToken "#-}", EpaLocation), SourceText) +type instance XConFieldSpec (GhcPass _) = ((EpaLocation, EpToken "#-}", EpaLocation), SourceText) +type instance XXConDeclField (GhcPass _) = DataConCantHappen type instance XRecTy GhcPs = AnnList () type instance XRecTy GhcRn = NoExtField @@ -541,14 +545,8 @@ type instance XExplicitMult _ _ GhcTc = NoExtField type instance XXMultAnnOn _ _ (GhcPass _) = DataConCantHappen -hsLinear :: a -> HsScaled OnArrow GhcPs a -hsLinear = HsScaled (HsLinearAnn noAnn) - -hsNoMultAnn :: a -> HsScaled OnRecField GhcPs a -hsNoMultAnn = HsScaled (HsUnannotated HsUnannOne noAnn) - -hsScaledToHsTypes :: HsScaled on GhcRn (LHsType GhcRn) -> [LHsType GhcRn] -hsScaledToHsTypes (HsScaled arr t) = [multAnnToHsType arr, t] +hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => HsMultAnnOn on (LHsType GhcPs) GhcPs +hsNoMultAnn = HsUnannotated HsUnannOne noAnn isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (multAnnToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName @@ -582,16 +580,17 @@ type instance XXConDeclField (GhcPass _) = DataConCantHappen instance OutputableBndrId p => Outputable (ConDeclField (GhcPass p)) where - ppr (ConDeclField _ fld_n (HsScaled fld_mult fld_ty) _) = ppr_names fld_n <+> ppr_mult <+> ppr fld_ty + ppr (ConDeclField _ fld_n cfs _) = ppr_names fld_n <+> pprHsConFieldSpecWith ppr_mult cfs where ppr_names :: [LFieldOcc (GhcPass p)] -> SDoc ppr_names [n] = pprPrefixOcc n ppr_names ns = sep (punctuate comma (map pprPrefixOcc ns)) - ppr_mult = case fld_mult of - HsUnannotated _ _ -> dcolon - HsLinearAnn _ -> text "%1" <+> dcolon - HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon + ppr_mult :: HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc + ppr_mult mult tyDoc = case mult of + HsUnannotated _ _ -> dcolon <+> tyDoc + HsLinearAnn _ -> text "%1" <+> dcolon <+> tyDoc + HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon <+> tyDoc --------------------- hsWcScopedTvs :: LHsSigWcType GhcRn -> [Name] @@ -723,10 +722,10 @@ mkHsAppKindTy at ty k = addCLocA ty k (HsAppKindTy at ty k) -- splitHsFunType (a -> (b -> c)) = ([a,b], c) -- It returns API Annotations for any parens removed splitHsFunType :: - LHsType (GhcPass p) + LHsType GhcPs -> ( ([EpToken "("], [EpToken ")"]) , EpAnnComments -- The locations of any parens and -- comments discarded - , [HsScaled OnArrow (GhcPass p) (LHsType (GhcPass p))], LHsType (GhcPass p)) + , [HsConFieldSpec OnArrow GhcPs], LHsType GhcPs) splitHsFunType ty = go ty where go (L l (HsParTy (op,cp) ty)) @@ -737,7 +736,7 @@ splitHsFunType ty = go ty go (L ll (HsFunTy _ mult x y)) | (anns, csy, args, res) <- splitHsFunType y - = (anns, csy S.<> epAnnComments ll, HsScaled mult x:args, res) + = (anns, csy S.<> epAnnComments ll, CFS noAnn NoSrcUnpack NoSrcStrict mult x:args, res) go other = (noAnn, emptyComments, [], other) @@ -1297,6 +1296,19 @@ instance (Outputable tyarg, Outputable arg, Outputable rec) ppr (RecCon rec) = text "RecCon:" <+> ppr rec ppr (InfixCon l r) = text "InfixCon:" <+> ppr [l, r] +pprHsConFieldSpecWith :: (OutputableBndrId p) => (HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc) -> HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty) = ppr_mult mult (ppr prag <+> ppr mark <> ppr ty) + +pprHsConFieldSpecNoMult :: (OutputableBndrId p) => HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecNoMult = pprHsConFieldSpecWith (\_ d -> d) + +hsPlainTypeField :: LHsType GhcPs -> HsConFieldSpec OnArrow GhcPs +hsPlainTypeField (L _ (HsBangTy ann (HsBang unp str) lty)) = CFS ann unp str (HsLinearAnn noAnn) lty +hsPlainTypeField lty = CFS noAnn NoSrcUnpack NoSrcStrict (HsLinearAnn noAnn) lty + +hsConFieldSpecToHsTypes :: HsConFieldSpec on GhcRn -> [LHsType GhcRn] +hsConFieldSpecToHsTypes (CFS _ _ _ arr t) = [multAnnToHsType arr, t] + instance Outputable (XRecGhc (IdGhcP p)) => Outputable (FieldOcc (GhcPass p)) where ppr = ppr . foLabel ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -430,14 +430,14 @@ conArgDocs (ConDeclGADT{con_g_args = args, con_res_ty = res_ty}) = h98ConArgDocs :: HsConDeclH98Details GhcRn -> IntMap (HsDoc GhcRn) h98ConArgDocs con_args = case con_args of - PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args - InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (hsScaledThing arg1) - , unLoc (hsScaledThing arg2) ] + PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args + InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (cfs_type arg1) + , unLoc (cfs_type arg2) ] RecCon _ -> IM.empty gadtConArgDocs :: HsConDeclGADTDetails GhcRn -> HsType GhcRn -> IntMap (HsDoc GhcRn) gadtConArgDocs con_args res_ty = case con_args of - PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args ++ [res_ty] + PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args ++ [res_ty] RecConGADT _ _ -> con_arg_docs 1 [res_ty] con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn) ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -920,17 +920,13 @@ repSrcStrictness SrcLazy = rep2 sourceLazyName [] repSrcStrictness SrcStrict = rep2 sourceStrictName [] repSrcStrictness NoSrcStrict = rep2 noSourceStrictnessName [] -repBangTy :: LBangType GhcRn -> MetaM (Core (M TH.BangType)) -repBangTy ty = do - MkC u <- repSrcUnpackedness su' - MkC s <- repSrcStrictness ss' +repConFieldSpec :: HsConFieldSpec on GhcRn -> MetaM (Core (M TH.BangType)) +repConFieldSpec (CFS _ su ss _ ty') = do + MkC u <- repSrcUnpackedness su + MkC s <- repSrcStrictness ss MkC b <- rep2 bangName [u, s] MkC t <- repLTy ty' rep2 bangTypeName [b, t] - where - (su', ss', ty') = case unLoc ty of - HsBangTy _ (HsBang su ss) ty -> (su, ss, ty) - _ -> (NoSrcUnpack, NoSrcStrict, ty) ------------------------------------------------------- -- Deriving clauses @@ -2838,8 +2834,8 @@ repH98DataCon con details rep2 normalCName [unC con', unC arg_tys] InfixCon st1 st2 -> do verifyLinearFields [st1, st2] - arg1 <- repBangTy (hsScaledThing st1) - arg2 <- repBangTy (hsScaledThing st2) + arg1 <- repConFieldSpec st1 + arg2 <- repConFieldSpec st2 rep2 infixCName [unC arg1, unC con', unC arg2] RecCon ips -> do arg_vtys <- repRecConArgs ips @@ -2865,33 +2861,33 @@ repGadtDataCons cons details res_ty -- TH currently only supports linear constructors. -- We also accept the (->) arrow when -XLinearTypes is off, because this -- denotes a linear field. -verifyLinearFields :: [HsScaled on GhcRn (LHsType GhcRn)] -> MetaM () +verifyLinearFields :: [HsConFieldSpec on GhcRn] -> MetaM () verifyLinearFields ps = do linear <- lift $ xoptM LangExt.LinearTypes - let allGood = all (hsMultIsLinear linear) ps + let allGood = all (hsMultIsLinear linear . cfs_multiplicity) ps unless allGood $ notHandled ThNonLinearDataCon -- Desugar the arguments in a data constructor declared with prefix syntax. -repPrefixConArgs :: [HsScaled OnArrow GhcRn (LHsType GhcRn)] +repPrefixConArgs :: [HsConFieldSpec OnArrow GhcRn] -> MetaM (Core [M TH.BangType]) repPrefixConArgs ps = do verifyLinearFields ps - repListM bangTypeTyConName repBangTy (map hsScaledThing ps) + repListM bangTypeTyConName repConFieldSpec ps -- Desugar the arguments in a data constructor declared with record syntax. repRecConArgs :: LocatedL [LConDeclField GhcRn] -> MetaM (Core [M TH.VarBangType]) repRecConArgs lips = do let ips = map unLoc (unLoc lips) - verifyLinearFields (map cd_fld_type ips) + verifyLinearFields (map cd_fld_spec ips) args <- concatMapM rep_ip ips coreListM varBangTypeTyConName args where - rep_ip ip = mapM (rep_one_ip (hsScaledThing $ cd_fld_type ip)) (cd_fld_names ip) + rep_ip ip = mapM (rep_one_ip (cd_fld_spec ip)) (cd_fld_names ip) - rep_one_ip :: LBangType GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) + rep_one_ip :: HsConFieldSpec OnRecField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) rep_one_ip t n = do { MkC v <- lookupOcc (unLoc . foLabel $ unLoc n) - ; MkC ty <- repBangTy t + ; MkC ty <- repConFieldSpec t ; rep2 varBangTypeName [v,ty] } ------------ Types ------------------- ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1789,8 +1789,8 @@ instance ToHie (LocatedA (ConDecl GhcRn)) where PrefixCon _ xs -> scaled_args_scope xs InfixCon a b -> scaled_args_scope [a, b] RecCon x -> mkScope x - where scaled_args_scope :: [HsScaled on GhcRn (LHsType GhcRn)] -> Scope - scaled_args_scope = foldr combineScopes NoScope . map (mkScope . hsScaledThing) + where scaled_args_scope :: [HsConFieldSpec on GhcRn] -> Scope + scaled_args_scope = foldr combineScopes NoScope . map (mkScope . cfs_type) instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where toHie (L span decls) = concatM $ @@ -1798,6 +1798,9 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where , toHie decls ] +instance ToHie (HsConFieldSpec on GhcRn) where + toHie (CFS _ _ _ w t) = concatM [toHie (multAnnToHsType w), toHie t] + instance ToHie (TScoped (HsWildCardBndrs GhcRn (LocatedA (HsSigType GhcRn)))) where toHie (TS sc (HsWC names a)) = concatM $ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names @@ -2000,7 +2003,7 @@ instance HiePass p => ToHie (LocatedC [LocatedA (HsExpr (GhcPass p))]) where instance ToHie (LocatedA (ConDeclField GhcRn)) where toHie (L span field) = concatM $ makeNode field (locA span) : case field of ConDeclField _ fields typ doc -> - [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ hsScaledThing typ)) fields + [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ cfs_type typ)) fields , toHie typ , toHie doc ] ===================================== compiler/GHC/Parser.y ===================================== @@ -2598,7 +2598,7 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (HsScaled (HsUnannotated HsUnannOne (epUniTok $2)) $3) + (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3) Nothing))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -72,6 +72,7 @@ module GHC.Parser.PostProcess ( mkMultTy, mkMultAnn, mkMultField, + mkConFieldSpec, -- Token location mkTokenLocation, @@ -2337,11 +2338,11 @@ dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) -- Normal prefix constructor, e.g. data T = MkT A B C dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) - = PrefixCon noTypeArgs (map hsLinear (toList flds)) + = PrefixCon noTypeArgs (map hsPlainTypeField (toList flds)) -- Infix constructor, e.g. data T = Int :! Bool dataConBuilderDetails (L (EpAnn _ _ csl) (InfixDataConBuilder (L (EpAnn anc ann csll) lhs) _ rhs)) - = InfixCon (hsLinear (L (EpAnn anc ann (csl Semi.<> csll)) lhs)) (hsLinear rhs) + = InfixCon (hsPlainTypeField (L (EpAnn anc ann (csl Semi.<> csll)) lhs)) (hsPlainTypeField rhs) instance DisambTD DataConBuilder where @@ -2409,7 +2410,7 @@ checkNotPromotedDataCon IsPromoted (L l name) = mkUnboxedSumCon :: LHsType GhcPs -> ConTag -> Arity -> (LocatedN RdrName, HsConDeclH98Details GhcPs) mkUnboxedSumCon t tag arity = - (noLocA (getRdrName (sumDataCon tag arity)), PrefixCon noTypeArgs [hsLinear t]) + (noLocA (getRdrName (sumDataCon tag arity)), PrefixCon noTypeArgs [hsPlainTypeField t]) {- Note [Ambiguous syntactic categories] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3519,15 +3520,19 @@ mkMultAnn pct t@(L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) pct1 = epTokenWidenR pct (locA (getLoc t)) mkMultAnn pct t = HsMultAnn pct t -mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsScaled OnRecField GhcPs (LBangType GhcPs) +mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnRecField GhcPs mkMultField pct (L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) col t -- See #18888 for the use of (SourceText "1") above - = HsScaled (HsLinearAnn (pct1, col)) t + = mkConFieldSpec (HsLinearAnn (pct1, col)) t where -- The location of "%" combined with the location of "1". pct1 :: EpToken "%1" pct1 = epTokenWidenR pct (locA (getLoc t)) -mkMultField pct mult col t = HsScaled (HsExplicitMult (pct, col) mult) t +mkMultField pct mult col t = mkConFieldSpec (HsExplicitMult (pct, col) mult) t + +mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs +mkConFieldSpec mult (L _ (HsBangTy ann (HsBang unp str) t)) = CFS ann unp str mult t +mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t mkTokenLocation :: SrcSpan -> TokenLocation mkTokenLocation (UnhelpfulSpan _) = NoTokenLoc ===================================== compiler/GHC/Parser/PostProcess/Haddock.hs ===================================== @@ -788,12 +788,12 @@ getConDoc l = extendHdkA l $ liftHdkA $ getPrevNextDoc l -- Add documentation comment to a data constructor field. -- Used for PrefixCon and InfixCon. addHaddockConDeclFieldTy - :: HsScaled on GhcPs (LHsType GhcPs) - -> HdkA (HsScaled on GhcPs (LHsType GhcPs)) -addHaddockConDeclFieldTy (HsScaled mult (L l t)) = + :: HsConFieldSpec on GhcPs + -> HdkA (HsConFieldSpec on GhcPs) +addHaddockConDeclFieldTy (CFS ann unpack strict mult (L l t)) = extendHdkA (locA l) $ liftHdkA $ do mDoc <- getPrevNextDoc (locA l) - return (HsScaled mult (mkLHsDocTy (L l t) mDoc)) + return (CFS ann unpack strict mult (mkLHsDocTy (L l t) mDoc)) -- Add documentation comment to a data constructor field. -- Used for RecCon. @@ -909,6 +909,9 @@ We implement this in two steps: instance HasHaddock a => HasHaddock (HsScaled on GhcPs a) where addHaddock (HsScaled mult a) = HsScaled mult <$> addHaddock a +instance HasHaddock (HsConFieldSpec on GhcPs) where + addHaddock (CFS ann unp str mult a) = CFS ann unp str mult <$> addHaddock a + instance HasHaddock a => HasHaddock (HsWildCardBndrs GhcPs a) where addHaddock (HsWC _ t) = HsWC noExtField <$> addHaddock t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Rename.HsType ( lookupField, mkHsOpTyRn, rnLTyVar, - rnScaledLHsType, + rnHsConFieldSpec, -- Precence related stuff NegationHandling(..), @@ -450,16 +450,16 @@ rnLHsType ctxt ty = rnLHsTyKi (mkTyKiEnv ctxt TypeLevel RnTypeBody) ty rnLHsTypes :: HsDocContext -> [LHsType GhcPs] -> RnM ([LHsType GhcRn], FreeVars) rnLHsTypes doc tys = mapFvRn (rnLHsType doc) tys -rnScaledLHsType :: HsDocContext -> HsScaled on GhcPs (LHsType GhcPs) - -> RnM (HsScaled on GhcRn (LHsType GhcRn), FreeVars) -rnScaledLHsType doc = rnScaledLHsTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) +rnHsConFieldSpec :: HsDocContext -> HsConFieldSpec on GhcPs + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpec doc = rnHsConFieldSpecTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) -rnScaledLHsTyKi :: RnTyKiEnv -> HsScaled on GhcPs (LHsType GhcPs) - -> RnM (HsScaled on GhcRn (LHsType GhcRn), FreeVars) -rnScaledLHsTyKi env (HsScaled w ty) = do +rnHsConFieldSpecTyKi :: RnTyKiEnv -> HsConFieldSpec on GhcPs + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpecTyKi env (CFS ext unp str w ty) = do (w' , fvs_w) <- rnHsMultAnnOn env w (ty', fvs) <- rnLHsTyKi env ty - return (HsScaled w' ty', fvs `plusFV` fvs_w) + return (CFS ext unp str w' ty', fvs `plusFV` fvs_w) rnHsType :: HsDocContext -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) @@ -1339,7 +1339,7 @@ rnField :: FastStringEnv FieldLabel -> RnTyKiEnv -> LConDeclField GhcPs -> RnM (LConDeclField GhcRn, FreeVars) rnField fl_env env (L l (ConDeclField _ names ty haddock_doc)) = do { let new_names = map (fmap (lookupField fl_env)) names - ; (new_ty, fvs) <- rnScaledLHsTyKi env ty + ; (new_ty, fvs) <- rnHsConFieldSpecTyKi env ty ; haddock_doc' <- traverse rnLHsDoc haddock_doc ; return (L l (ConDeclField noExtField new_names new_ty haddock_doc') , fvs) } @@ -2035,7 +2035,7 @@ extractConDeclGADTDetailsTyVars :: HsConDeclGADTDetails GhcPs -> FreeKiTyVars -> FreeKiTyVars extractConDeclGADTDetailsTyVars con_args = case con_args of PrefixConGADT _ args -> extract_scaled_ltys args - RecConGADT _ (L _ flds) -> extract_scaled_ltys $ map (cd_fld_type . unLoc) $ flds + RecConGADT _ (L _ flds) -> extract_scaled_ltys $ map (cd_fld_spec . unLoc) $ flds -- | Get type/kind variables mentioned in the kind signature, preserving -- left-to-right order: @@ -2051,13 +2051,13 @@ extractDataDefnKindVars (HsDataDefn { dd_kindSig = ksig }) extract_lctxt :: LHsContext GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lctxt ctxt = extract_ltys (unLoc ctxt) -extract_scaled_ltys :: [HsScaled on GhcPs (LHsType GhcPs)] +extract_scaled_ltys :: [HsConFieldSpec on GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_scaled_ltys args acc = foldr extract_scaled_lty acc args -extract_scaled_lty :: HsScaled on GhcPs (LHsType GhcPs) +extract_scaled_lty :: HsConFieldSpec on GhcPs -> FreeKiTyVars -> FreeKiTyVars -extract_scaled_lty (HsScaled m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc +extract_scaled_lty (CFS _ _ _ m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc extract_ltys :: [LHsType GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_ltys tys acc = foldr extract_lty acc tys @@ -2068,7 +2068,7 @@ extract_lty (L _ ty) acc HsTyVar _ _ ltv -> extract_tv ltv acc HsBangTy _ _ ty -> extract_lty ty acc HsRecTy _ flds -> foldr (extract_scaled_lty - . cd_fld_type . unLoc) acc + . cd_fld_spec . unLoc) acc flds HsAppTy _ ty1 ty2 -> extract_lty ty1 $ extract_lty ty2 acc ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1928,9 +1928,7 @@ rnDataDefn doc (HsDataDefn { dd_cType = cType, dd_ctxt = context, dd_cons = cond has_labelled_fields _ = False has_strictness_flags condecl - = any (is_strict . getBangStrictness . hsScaledThing) (con_args condecl) - - is_strict (HsSrcBang _ (HsBang _ s)) = isSrcStrict s + = any (isSrcStrict . cfs_bang) (con_args condecl) con_args (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = args con_args (ConDeclH98 { con_args = PrefixCon _ args }) = args @@ -2483,11 +2481,11 @@ rnConDeclH98Details :: -> HsConDeclH98Details GhcPs -> RnM (HsConDeclH98Details GhcRn, FreeVars) rnConDeclH98Details _ doc (PrefixCon _ tys) - = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys + = do { (new_tys, fvs) <- mapFvRn (rnHsConFieldSpec doc) tys ; return (PrefixCon noTypeArgs new_tys, fvs) } rnConDeclH98Details _ doc (InfixCon ty1 ty2) - = do { (new_ty1, fvs1) <- rnScaledLHsType doc ty1 - ; (new_ty2, fvs2) <- rnScaledLHsType doc ty2 + = do { (new_ty1, fvs1) <- rnHsConFieldSpec doc ty1 + ; (new_ty2, fvs2) <- rnHsConFieldSpec doc ty2 ; return (InfixCon new_ty1 new_ty2, fvs1 `plusFV` fvs2) } rnConDeclH98Details con doc (RecCon flds) = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds @@ -2499,7 +2497,7 @@ rnConDeclGADTDetails :: -> HsConDeclGADTDetails GhcPs -> RnM (HsConDeclGADTDetails GhcRn, FreeVars) rnConDeclGADTDetails _ doc (PrefixConGADT _ tys) - = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys + = do { (new_tys, fvs) <- mapFvRn (rnHsConFieldSpec doc) tys ; return (PrefixConGADT noExtField new_tys, fvs) } rnConDeclGADTDetails con doc (RecConGADT _ flds) = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -283,7 +283,7 @@ no_anon_wc_ty lty = go lty HsKindSig _ ty kind -> go ty && go kind HsDocTy _ ty _ -> go ty HsBangTy _ _ ty -> go ty - HsRecTy _ flds -> gos $ concatMap (hsScaledToHsTypes . cd_fld_type . unLoc) flds + HsRecTy _ flds -> gos $ concatMap (hsConFieldSpecToHsTypes . cd_fld_spec . unLoc) flds HsExplicitListTy _ _ tys -> gos tys HsExplicitTupleTy _ _ tys -> gos tys HsForAllTy { hst_tele = tele ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1799,11 +1799,11 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled on GhcRn (LHsType GhcRn)] -> TcM () +kcConArgTys :: NewOrData -> TcKind -> [HsConFieldSpec on GhcRn] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) + ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -1813,14 +1813,14 @@ kcConH98Args new_or_data res_kind con_args = case con_args of PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ - map (cd_fld_type . unLoc) flds + map (cd_fld_spec . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () kcConGADTArgs new_or_data res_kind con_args = case con_args of PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ - map (cd_fld_type . unLoc) flds + map (cd_fld_spec . unLoc) flds kcConDecls :: Foldable f => NewOrData @@ -3893,7 +3893,7 @@ tcConIsInfixGADT con details RecConGADT{} -> return False PrefixConGADT _ arg_tys -- See Note [Infix GADT constructors] | isSymOcc (getOccName con) - , [_ty1,_ty2] <- map hsScaledThing arg_tys + , [_ty1,_ty2] <- arg_tys -> do { fix_env <- getFixityEnv ; return (con `elemNameEnv` fix_env) } | otherwise -> return False @@ -3924,13 +3924,13 @@ tcConGADTArgs exp_kind (RecConGADT _ fields) tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes - -> HsScaled on GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) -tcConArg exp_kind (HsScaled w bty) + -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) +tcConArg exp_kind (CFS (_, src) unp str w bty) = do { traceTc "tcConArg 1" (ppr bty) ; arg_ty <- tcCheckLHsTypeInContext (getBangType bty) exp_kind ; w' <- tcDataConMult w ; traceTc "tcConArg 2" (ppr bty) - ; return (Scaled w' arg_ty, getBangStrictness bty) } + ; return (Scaled w' arg_ty, HsSrcBang src (HsBang unp str)) } tcRecConDeclFields :: ContextKind -> LocatedL [LConDeclField GhcRn] @@ -3939,7 +3939,7 @@ tcRecConDeclFields exp_kind fields = mapM (tcConArg exp_kind) btys where -- We need a one-to-one mapping from field_names to btys - combined = map (\(L _ f) -> (cd_fld_names f, cd_fld_type f)) + combined = map (\(L _ f) -> (cd_fld_names f, cd_fld_spec f)) (unLoc fields) explode (ns,ty) = zip ns (repeat ty) exploded = concatMap explode combined ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -3,6 +3,7 @@ {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE DataKinds #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -689,7 +690,7 @@ cvtConstr :: TH.Name -- ^ name of first constructor of parent type cvtConstr _ do_con_name (NormalC c strtys) = do { c' <- do_con_name c ; tys' <- mapM cvt_arg strtys - ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing (PrefixCon noTypeArgs (map hsLinear tys')) } + ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing (PrefixCon noTypeArgs tys') } cvtConstr parent_con do_con_name (RecC c varstrtys) = do { c' <- do_con_name c @@ -702,7 +703,7 @@ cvtConstr _ do_con_name (InfixC st1 c st2) ; st1' <- cvt_arg st1 ; st2' <- cvt_arg st2 ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing - (InfixCon (hsLinear st1') (hsLinear st2')) } + (InfixCon st1' st2') } cvtConstr parent_con do_con_name (ForallC tvs ctxt con) = do { tvs' <- cvtTvs tvs @@ -741,7 +742,7 @@ cvtConstr _ do_con_name (GadtC c strtys ty) = case nonEmpty c of { c' <- mapM do_con_name c ; args <- mapM cvt_arg strtys ; ty' <- cvtType ty - ; mk_gadt_decl c' (PrefixConGADT noExtField $ map hsLinear args) ty'} + ; mk_gadt_decl c' (PrefixConGADT noExtField args) ty'} cvtConstr parent_con do_con_name (RecGadtC c varstrtys ty) = case nonEmpty c of Nothing -> failWith RecGadtNoCons @@ -775,13 +776,13 @@ cvtSrcStrictness NoSourceStrictness = NoSrcStrict cvtSrcStrictness SourceLazy = SrcLazy cvtSrcStrictness SourceStrict = SrcStrict -cvt_arg :: (TH.Bang, TH.Type) -> CvtM (LHsType GhcPs) +cvt_arg :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) cvt_arg (Bang su ss, ty) = do { ty'' <- cvtType ty ; let ty' = parenthesizeHsType appPrec ty'' su' = cvtSrcUnpackedness su ss' = cvtSrcStrictness ss - ; returnLA $ HsBangTy (noAnn, NoSourceText) (HsBang su' ss') ty' } + ; return $ CFS noAnn su' ss' hsNoMultAnn ty' } cvt_id_arg :: TH.Name -- ^ parent constructor name -> (TH.Name, TH.Bang, TH.Type) -> CvtM (LConDeclField GhcPs) @@ -792,7 +793,7 @@ cvt_id_arg parent_con (i, str, ty) { cd_fld_ext = noExtField , cd_fld_names = [L (l2l li) $ FieldOcc noExtField (L li i')] - , cd_fld_type = hsNoMultAnn ty' + , cd_fld_spec = ty' , cd_fld_doc = Nothing} } cvtDerivs :: [TH.DerivClause] -> CvtM (HsDeriving GhcPs) ===================================== compiler/Language/Haskell/Syntax/Decls.hs ===================================== @@ -1122,7 +1122,7 @@ or contexts in two parts: -- | The arguments in a Haskell98-style data constructor. type HsConDeclH98Details pass - = HsConDetails Void (HsScaled OnArrow pass (LBangType pass)) (XRec pass [LConDeclField pass]) + = HsConDetails Void (HsConFieldSpec OnArrow pass) (XRec pass [LConDeclField pass]) -- The Void argument to HsConDetails here is a reflection of the fact that -- type applications are not allowed in data constructor declarations. @@ -1133,7 +1133,7 @@ type HsConDeclH98Details pass -- derived Show instances—see Note [Infix GADT constructors] in -- GHC.Tc.TyCl—but that is an orthogonal concern.) data HsConDeclGADTDetails pass - = PrefixConGADT !(XPrefixConGADT pass) [HsScaled OnArrow pass (LBangType pass)] + = PrefixConGADT !(XPrefixConGADT pass) [HsConFieldSpec OnArrow pass] | RecConGADT !(XRecConGADT pass) (XRec pass [LConDeclField pass]) | XConDeclGADTDetails !(XXConDeclGADTDetails pass) ===================================== compiler/Language/Haskell/Syntax/Extension.hs ===================================== @@ -682,6 +682,11 @@ type family XXTyVarBndr x type family XConDeclField x type family XXConDeclField x +-- --------------------------------------------------------------------- +-- ConFieldSpec type families +type family XConFieldSpec x +type family XXConFieldSpec x + -- --------------------------------------------------------------------- -- FieldOcc type families type family XCFieldOcc x ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -23,7 +23,7 @@ GHC.Hs.Type: Abstract syntax: user-defined types -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* module Language.Haskell.Syntax.Type ( HsScaled(..), - hsMultIsLinear, hsScaledThing, hsScaledGeneralize, + hsMultIsLinear, hsScaledThing, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), pattern HsUnrestrictedArrow, XUnannotated, XLinearAnn, XExplicitMult, XXMultAnnOn, @@ -57,6 +57,7 @@ module Language.Haskell.Syntax.Type ( ConDeclField(..), LConDeclField, HsConDetails(..), noTypeArgs, + HsConFieldSpec(..), hsConFieldSpecGeneralize, FieldOcc(..), LFieldOcc, @@ -67,7 +68,7 @@ module Language.Haskell.Syntax.Type ( import {-# SOURCE #-} Language.Haskell.Syntax.Expr ( HsUntypedSplice ) -import Language.Haskell.Syntax.Basic ( HsBang(..) ) +import Language.Haskell.Syntax.Basic ( HsBang(..), SrcStrictness, SrcUnpackedness ) import Language.Haskell.Syntax.Extension import Language.Haskell.Syntax.Specificity @@ -983,13 +984,10 @@ type family XXMultAnnOn (on :: HsMultAnnOnWhat) mult p data HsScaled on pass a = HsScaled (HsMultAnnOn on (LHsType pass) pass) a deriving (Functor) -hsScaledGeneralize :: HsScaled on pass a -> HsScaled on1 pass a -hsScaledGeneralize = unsafeCoerce - -hsMultIsLinear :: Bool -> HsScaled on pass a -> Bool -hsMultIsLinear _ (HsScaled (HsUnannotated HsUnannOne _) _) = True -hsMultIsLinear linear (HsScaled (HsUnannotated HsUnannMany _) _) = not linear -hsMultIsLinear _ (HsScaled HsLinearAnn{} _) = True +hsMultIsLinear :: Bool -> HsMultAnnOn on mult pass -> Bool +hsMultIsLinear _ (HsUnannotated HsUnannOne _) = True +hsMultIsLinear linear (HsUnannotated HsUnannMany _) = not linear +hsMultIsLinear _ HsLinearAnn{} = True hsMultIsLinear _ _ = False hsScaledThing :: HsScaled on pass a -> a @@ -1098,7 +1096,7 @@ data ConDeclField pass -- Record fields have Haddock docs on them = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_type :: HsScaled OnRecField pass (LBangType pass), + cd_fld_spec :: HsConFieldSpec OnRecField pass, cd_fld_doc :: Maybe (LHsDoc pass)} | XConDeclField !(XXConDeclField pass) @@ -1129,6 +1127,16 @@ data HsConDetails tyarg arg rec noTypeArgs :: [Void] noTypeArgs = [] +data HsConFieldSpec on pass + = CFS { cfs_ext :: XConFieldSpec pass + , cfs_unpack :: SrcUnpackedness + , cfs_bang :: SrcStrictness + , cfs_multiplicity :: HsMultAnnOn on (LHsType pass) pass + , cfs_type :: LHsType pass } + +hsConFieldSpecGeneralize :: HsConFieldSpec on pass -> HsConFieldSpec on1 pass +hsConFieldSpecGeneralize = unsafeCoerce + {- Note [ConDeclField pass] ~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4448,13 +4448,29 @@ instance (ExactPrint a) => ExactPrint (HsScaled OnArrow GhcPs a) where arr' <- markArrow arr return (HsScaled arr' t') -instance (ExactPrint a) => ExactPrint (HsScaled OnRecField GhcPs a) where +-- instance (ExactPrint a) => ExactPrint (HsScaled OnRecField GhcPs a) where +-- getAnnotationEntry = const NoEntryVal +-- setAnnotationAnchor a _ _ _ = a +-- exact (HsScaled mult t) = do +-- mult' <- markRecFieldMult mult +-- t' <- markAnnotated t +-- return (HsScaled mult' t') + +instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (HsScaled mult t) = do + exact (CFS an unp str arr t) = do + t' <- markAnnotated t + arr' <- markArrow arr + return (CFS an unp str arr' t') + +instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where + getAnnotationEntry = const NoEntryVal + setAnnotationAnchor a _ _ _ = a + exact (CFS an unp str mult t) = do mult' <- markRecFieldMult mult t' <- markAnnotated t - return (HsScaled mult' t') + return (CFS an unp str mult' t') -- --------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs ===================================== @@ -295,14 +295,14 @@ ppCtor sDocContext dat subdocs con at ConDeclH98{con_args = con_args'} = -- AZ:TODO get rid of the concatMap concatMap (lookupCon sDocContext subdocs) [con_name con] ++ f con_args' where - f :: HsConDetails v (HsScaled on GhcRn (LHsType GhcRn)) (LocatedL [LocatedA (ConDeclField GhcRn)]) -> [String] - f (PrefixCon _ args) = [typeSig name $ (map hsScaledThing args) ++ [resType]] + f :: HsConDetails v (HsConFieldSpec on GhcRn) (LocatedL [LocatedA (ConDeclField GhcRn)]) -> [String] + f (PrefixCon _ args) = [typeSig name $ (map cfs_type args) ++ [resType]] f (InfixCon a1 a2) = f $ PrefixCon [] [a1, a2] f (RecCon (L _ recs)) = - f (PrefixCon [] $ map (cd_fld_type . unLoc) recs) + f (PrefixCon [] $ map (cd_fld_spec . unLoc) recs) ++ concat [ (concatMap (lookupCon sDocContext subdocs . noLocA . unLoc . foLabel . unLoc) (cd_fld_names r)) - ++ [out sDocContext (map (foExt . unLoc) $ cd_fld_names r) `typeSig` [resType, hsScaledThing $ cd_fld_type r]] + ++ [out sDocContext (map (foExt . unLoc) $ cd_fld_names r) `typeSig` [resType, cfs_type $ cd_fld_spec r]] | r <- map unLoc recs ] @@ -356,8 +356,8 @@ ppCtor Nothing -> tau_ty tau_ty = foldr mkFunTy res_ty $ case args of - PrefixConGADT _ pos_args -> map hsScaledThing pos_args - RecConGADT _ (L _ flds) -> map (hsScaledThing . cd_fld_type . unL) flds + PrefixConGADT _ pos_args -> map cfs_type pos_args + RecConGADT _ (L _ flds) -> map (cfs_type . cd_fld_spec . unL) flds mkFunTy a b = noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) a b) ppFixity :: SDocContext -> (Name, Fixity) -> [String] ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -964,7 +964,7 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = hsep [ header_ , ppOcc - , hsep (map (ppLParendType unicode . hsScaledThing) args) + , hsep (map (ppLParendType unicode . cfs_type) args) ] -- Record constructor, e.g. 'Identity { runIdentity :: a }' RecCon _ -> header_ <+> ppOcc @@ -974,9 +974,9 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = | otherwise -> hsep [ header_ - , ppLParendType unicode (hsScaledThing arg1) + , ppLParendType unicode (cfs_type arg1) , ppOccInfix - , ppLParendType unicode (hsScaledThing arg2) + , ppLParendType unicode (cfs_type arg2) ] ConDeclGADT{} | hasArgDocs || not (isEmpty fieldPart) -> ppOcc @@ -993,15 +993,15 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = -- GADT record declarations RecConGADT _ _ -> doConstrArgsWithDocs [] -- GADT prefix data constructors - PrefixConGADT _ args | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing args) + PrefixConGADT _ args | hasArgDocs -> doConstrArgsWithDocs (map cfs_type args) _ -> empty ConDeclH98{con_args = con_args'} -> case con_args' of -- H98 record declarations RecCon (L _ fields) -> doRecordFields fields -- H98 prefix data constructors - PrefixCon _ args | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing args) + PrefixCon _ args | hasArgDocs -> doConstrArgsWithDocs (map cfs_type args) -- H98 infix data constructor - InfixCon arg1 arg2 | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing [arg1, arg2]) + InfixCon arg1 arg2 | hasArgDocs -> doConstrArgsWithDocs (map cfs_type [arg1, arg2]) _ -> empty doRecordFields fields = @@ -1035,7 +1035,7 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = decltt ( cat (punctuate comma (map (ppBinder . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode ltype (dcolon unicode) - <+> ppLType unicode (hsScaledThing ltype) + <+> ppLType unicode (cfs_type ltype) ) <-> rDoc mbDoc where @@ -1047,8 +1047,8 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd -ppRecFieldMultAnn :: Bool -> HsScaled on DocNameI a -> LaTeX -> LaTeX -ppRecFieldMultAnn unicode (HsScaled arr _) following = case arr of +ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX +ppRecFieldMultAnn unicode (CFS _ _ _ arr _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1350,7 +1350,7 @@ ppShortConstrParts summary dataInst con unicode qual = in case det of -- Prefix constructor, e.g. 'Just a' PrefixCon _ args -> - ( header_ <+> hsep (ppOcc : map (ppLParendType unicode qual HideEmptyContexts . hsScaledThing) args) + ( header_ <+> hsep (ppOcc : map (ppLParendType unicode qual HideEmptyContexts . cfs_type) args) , noHtml , noHtml ) @@ -1368,9 +1368,9 @@ ppShortConstrParts summary dataInst con unicode qual = InfixCon arg1 arg2 -> ( header_ <+> hsep - [ ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg1) + [ ppLParendType unicode qual HideEmptyContexts (cfs_type arg1) , ppOccInfix - , ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg2) + , ppLParendType unicode qual HideEmptyContexts (cfs_type arg2) ] , noHtml , noHtml @@ -1431,7 +1431,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = | otherwise -> hsep [ header_ <+> ppOcc - , hsep (map (ppLParendType unicode qual HideEmptyContexts . hsScaledThing) args) + , hsep (map (ppLParendType unicode qual HideEmptyContexts . cfs_type) args) , fixity ] -- Record constructor, e.g. 'Identity { runIdentity :: a }' @@ -1441,9 +1441,9 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = | hasArgDocs -> header_ <+> ppOcc <+> fixity | otherwise -> hsep - [ header_ <+> ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg1) + [ header_ <+> ppLParendType unicode qual HideEmptyContexts (cfs_type arg1) , ppOccInfix - , ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg2) + , ppLParendType unicode qual HideEmptyContexts (cfs_type arg2) , fixity ] -- GADT constructor, e.g. 'Foo :: Int -> Foo' @@ -1483,7 +1483,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = doConstrArgsWithDocs args = subFields pkg qual $ case con of ConDeclH98{} -> [ (ppLParendType unicode qual HideEmptyContexts arg, mdoc, []) - | (i, arg) <- zip [0 ..] (map hsScaledThing args) + | (i, arg) <- zip [0 ..] (map cfs_type args) , let mdoc = Map.lookup i argDocs ] ConDeclGADT{} -> @@ -1543,7 +1543,7 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = ] ) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) - <+> ppLType unicode qual HideEmptyContexts (hsScaledThing ltype) + <+> ppLType unicode qual HideEmptyContexts (cfs_type ltype) , mbDoc , [] ) @@ -1555,8 +1555,8 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd -ppRecFieldMultAnn :: Unicode -> Qualification -> HsScaled on DocNameI a -> Html -> Html -ppRecFieldMultAnn unicode qual (HsScaled arr _) following = case arr of +ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html +ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following @@ -1565,7 +1565,7 @@ ppShortField :: Bool -> Unicode -> Qualification -> ConDeclField DocNameI -> Htm ppShortField summary unicode qual (ConDeclField _ names ltype _) = hsep (punctuate comma (map ((ppBinder summary) . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) - <+> ppLType unicode qual HideEmptyContexts (hsScaledThing ltype) + <+> ppLType unicode qual HideEmptyContexts (cfs_type ltype) -- | Pretty print an expanded pattern (for bundled patterns) ppSideBySidePat ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -494,13 +494,10 @@ synifyDataCon use_gadt_syntax dc = linear_tys = zipWith - ( \(Scaled mult ty) bang -> + ( \(Scaled mult ty) (HsSrcBang st (HsBang unp str)) -> let tySyn = synifyType WithinType [] ty multSyn = synifyMultRec [] mult - bangTy = case bang of - (HsSrcBang _ (HsBang NoSrcUnpack NoSrcStrict)) -> tySyn - (HsSrcBang src bang') -> noLocA $ HsBangTy (noAnn, src) bang' tySyn - in HsScaled multSyn bangTy + in CFS (noAnn, st) unp str multSyn tySyn ) arg_tys (dataConSrcBangs dc) @@ -518,15 +515,15 @@ synifyDataCon use_gadt_syntax dc = mk_h98_arg_tys = case (use_named_field_syntax, use_infix_syntax) of (True, True) -> Left "synifyDataCon: contradiction!" (True, False) -> return $ RecCon (noLocA field_tys) - (False, False) -> return $ PrefixCon noTypeArgs (map hsScaledGeneralize linear_tys) - (False, True) -> case map hsScaledGeneralize linear_tys of + (False, False) -> return $ PrefixCon noTypeArgs (map hsConFieldSpecGeneralize linear_tys) + (False, True) -> case map hsConFieldSpecGeneralize linear_tys of [a, b] -> return $ InfixCon a b _ -> Left "synifyDataCon: infix with non-2 args?" mk_gadt_arg_tys :: HsConDeclGADTDetails GhcRn mk_gadt_arg_tys | use_named_field_syntax = RecConGADT noExtField (noLocA field_tys) - | otherwise = PrefixConGADT noExtField (map hsScaledGeneralize linear_tys) + | otherwise = PrefixConGADT noExtField (map hsConFieldSpecGeneralize linear_tys) in -- finally we get synifyDataCon's result! if use_gadt_syntax ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -220,7 +220,7 @@ getGADTConType -- tau_ty :: LHsType DocNameI tau_ty = case args of RecConGADT _ flds -> mkFunTy (noLocA (HsRecTy noAnn (unLoc flds))) res_ty - PrefixConGADT _ pos_args -> foldr mkFunTy res_ty (map hsScaledThing pos_args) + PrefixConGADT _ pos_args -> foldr mkFunTy res_ty (map cfs_type pos_args) mkFunTy :: LHsType DocNameI -> LHsType DocNameI -> LHsType DocNameI mkFunTy a b = noLocA (HsFunTy noAnn (HsUnrestrictedArrow noExtField) a b) @@ -361,8 +361,8 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] field_avail (L _ (ConDeclField _ fs _ _)) = all (\f -> (unLoc . foLabel . unLoc $ f) `elem` names) fs - field_types :: [LConDeclField GhcRn] -> [HsScaled OnArrow GhcRn (LBangType GhcRn)] - field_types flds = [hsScaledGeneralize t | L _ (ConDeclField _ _ t _) <- flds] + field_types :: [LConDeclField GhcRn] -> [HsConFieldSpec OnArrow GhcRn] + field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t _) <- flds] keep _ = Nothing restrictDecls :: [Name] -> [LSig GhcRn] -> [LSig GhcRn] @@ -513,7 +513,7 @@ reparenBndrKind v at XBndrKind{} = v -- | Add parenthesis around the types in a 'ConDeclField' (see 'reparenTypePrec') reparenConDeclField :: XRecCond a => ConDeclField a -> ConDeclField a -reparenConDeclField (ConDeclField x n t d) = ConDeclField x n (fmap reparenLType t) d +reparenConDeclField (ConDeclField x n (CFS an unp str m t) d) = ConDeclField x n (CFS an unp str m (reparenLType t)) d reparenConDeclField c at XConDeclField{} = c ------------------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Create.hs ===================================== @@ -962,12 +962,12 @@ extractPatternSyn nm t tvs cons = let args = case con of ConDeclH98{con_args = con_args'} -> case con_args' of - PrefixCon _ args' -> map hsScaledThing args' - RecCon (L _ fields) -> hsScaledThing . cd_fld_type . unLoc <$> fields - InfixCon arg1 arg2 -> map hsScaledThing [arg1, arg2] + PrefixCon _ args' -> map cfs_type args' + RecCon (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields + InfixCon arg1 arg2 -> map cfs_type [arg1, arg2] ConDeclGADT{con_g_args = con_args'} -> case con_args' of - PrefixConGADT _ args' -> map hsScaledThing args' - RecConGADT _ (L _ fields) -> hsScaledThing . cd_fld_type . unLoc <$> fields + PrefixConGADT _ args' -> map cfs_type args' + RecConGADT _ (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields typ = longArrow args (data_ty con) typ' = case con of @@ -999,7 +999,7 @@ extractRecSel nm t tvs (L _ con : rest) = case getRecConArgs_maybe con of Just (L _ fields) | ((l, L _ (ConDeclField _ _nn ty _)) : _) <- matching_fields fields -> - pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (getBangType $ hsScaledThing ty)))))) + pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (cfs_type ty)))))) -- TODO : was getBangType $ hsScaledThing ty _ -> extractRecSel nm t tvs rest where matching_fields :: [LConDeclField GhcRn] -> [(SrcSpan, LConDeclField GhcRn)] ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -718,10 +718,10 @@ renameCon } ) -renameHsScaled - :: HsScaled on GhcRn (LHsType GhcRn) - -> RnM (HsScaled on DocNameI (LHsType DocNameI)) -renameHsScaled (HsScaled w ty) = HsScaled <$> renameMultAnnOn w <*> renameLType ty +renameHsConFieldSpec + :: HsConFieldSpec on GhcRn + -> RnM (HsConFieldSpec on DocNameI) +renameHsConFieldSpec (CFS _ unp str w ty) = CFS noExtField unp str <$> renameMultAnnOn w <*> renameLType ty renameH98Details :: HsConDeclH98Details GhcRn @@ -729,10 +729,10 @@ renameH98Details renameH98Details (RecCon (L l fields)) = do fields' <- mapM renameConDeclFieldField fields return (RecCon (L (locA l) fields')) -renameH98Details (PrefixCon ts ps) = PrefixCon ts <$> mapM renameHsScaled ps +renameH98Details (PrefixCon ts ps) = PrefixCon ts <$> mapM renameHsConFieldSpec ps renameH98Details (InfixCon a b) = do - a' <- renameHsScaled a - b' <- renameHsScaled b + a' <- renameHsConFieldSpec a + b' <- renameHsConFieldSpec b return (InfixCon a' b') renameGADTDetails @@ -741,12 +741,12 @@ renameGADTDetails renameGADTDetails (RecConGADT _ (L l fields)) = do fields' <- mapM renameConDeclFieldField fields return (RecConGADT noExtField (L (locA l) fields')) -renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsScaled ps +renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsConFieldSpec ps renameConDeclFieldField :: LConDeclField GhcRn -> RnM (LConDeclField DocNameI) renameConDeclFieldField (L l (ConDeclField _ names t doc)) = do names' <- mapM renameLFieldOcc names - t' <- renameHsScaled t + t' <- renameHsConFieldSpec t doc' <- mapM renameLDocHsSyn doc return $ L (locA l) (ConDeclField noExtField names' t' doc') ===================================== utils/haddock/haddock-api/src/Haddock/Types.hs ===================================== @@ -964,6 +964,9 @@ type instance XXLHsQTyVars DocNameI = DataConCantHappen type instance XConDeclField DocNameI = NoExtField type instance XXConDeclField DocNameI = DataConCantHappen +type instance XConFieldSpec DocNameI = NoExtField +type instance XXConFieldSpec DocNameI = DataConCantHappen + type instance XXPat DocNameI = DataConCantHappen type instance XXHsBindsLR DocNameI a = DataConCantHappen View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a28732e9c1d17a5f5c6b1f5d46513809fc11746a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a28732e9c1d17a5f5c6b1f5d46513809fc11746a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 13:19:47 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 09 Jan 2025 08:19:47 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add HsConFieldSpec Message-ID: <677fccf3608ba_21de7c4fbf00463f6@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 8bc7e565 by Sjoerd Visscher at 2025-01-09T14:19:23+01:00 Add HsConFieldSpec - - - - - 26 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Type.hs - utils/check-exact/ExactPrint.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/Rename.hs - utils/haddock/haddock-api/src/Haddock/Types.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -881,11 +881,11 @@ pprConDecl (ConDeclH98 { con_name = L _ con where -- In ppr_details: let's not print the multiplicities (they are always 1, by -- definition) as they do not appear in an actual declaration. - ppr_details (InfixCon t1 t2) = hsep [ppr (hsScaledThing t1), + ppr_details (InfixCon t1 t2) = hsep [pprHsConFieldSpecNoMult t1, pprInfixOcc con, - ppr (hsScaledThing t2)] + pprHsConFieldSpecNoMult t2] ppr_details (PrefixCon _ tys) = hsep (pprPrefixOcc con - : map (pprHsType . unLoc . hsScaledThing) tys) + : map pprHsConFieldSpecNoMult tys) ppr_details (RecCon fields) = pprPrefixOcc con <+> pprConDeclFields (unLoc fields) @@ -896,7 +896,7 @@ pprConDecl (ConDeclGADT { con_names = cons, con_bndrs = L _ outer_bndrs <+> (sep [pprHsOuterSigTyVarBndrs outer_bndrs <+> pprLHsContext mcxt, sep (ppr_args args ++ [ppr res_ty]) ]) where - ppr_args (PrefixConGADT _ args) = map (\(HsScaled arr t) -> ppr t <+> ppr_arr arr) args + ppr_args (PrefixConGADT _ args) = map (pprHsConFieldSpecWith (\arr tyDoc -> tyDoc <+> ppr_arr arr)) args ppr_args (RecConGADT _ fields) = [pprConDeclFields (unLoc fields) <+> arrow] -- Display linear arrows as unrestricted with -XNoLinearTypes ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -535,7 +535,7 @@ deriving instance Data (HsTyLit GhcPs) deriving instance Data (HsTyLit GhcRn) deriving instance Data (HsTyLit GhcTc) --- deriving instance (Data mult, DataIdLR p p) => Data (HsArrowOf mult p) +-- deriving instance (Data mult, DataIdLR p p, Typeable on) => Data (HsMultAnnOn on mult p) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsType GhcPs)) GhcPs) deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsType GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcRn)) GhcRn) @@ -545,7 +545,7 @@ deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsExpr deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcTc)) GhcTc) --- deriving instance (DataIdLR p p) => Data (HsScaled p a) +-- deriving instance (DataIdLR p p, Typeable on) => Data (HsScaled on p a) deriving instance Data thing => Data (HsScaled OnArrow GhcPs thing) deriving instance Data thing => Data (HsScaled OnRecField GhcPs thing) deriving instance (Data thing, Typeable on) => Data (HsScaled on GhcRn thing) @@ -561,6 +561,12 @@ deriving instance Data (ConDeclField GhcPs) deriving instance Data (ConDeclField GhcRn) deriving instance Data (ConDeclField GhcTc) +-- deriving instance (DataIdLR p p, Typeable on) => Data (HsConFieldSpec on p) +deriving instance Data (HsConFieldSpec OnArrow GhcPs) +deriving instance Data (HsConFieldSpec OnRecField GhcPs) +deriving instance Typeable on => Data (HsConFieldSpec on GhcRn) +deriving instance Typeable on => Data (HsConFieldSpec on GhcTc) + -- deriving instance (DataId p) => Data (FieldOcc p) deriving instance Data (FieldOcc GhcPs) deriving instance Data (FieldOcc GhcRn) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -25,11 +25,11 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( Mult, HsScaled(..), - hsMultIsLinear, hsScaledThing, hsScaledToHsTypes, + hsMultIsLinear, hsScaledThing, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, EpLinearArrow(..), - hsLinear, hsNoMultAnn, isUnrestricted, + hsNoMultAnn, isUnrestricted, pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, @@ -61,6 +61,8 @@ module GHC.Hs.Type ( ConDeclField(..), LConDeclField, pprConDeclFields, HsConDetails(..), noTypeArgs, + HsConFieldSpec(..), pprHsConFieldSpecWith, pprHsConFieldSpecNoMult, + hsPlainTypeField, hsConFieldSpecToHsTypes, mkConFieldSpec, FieldOcc(..), LFieldOcc, mkFieldOcc, fieldOccRdrName, fieldOccLRdrName, @@ -482,6 +484,8 @@ type instance XSpliceTy GhcTc = Kind type instance XDocTy (GhcPass _) = NoExtField type instance XBangTy (GhcPass _) = ((EpaLocation, EpToken "#-}", EpaLocation), SourceText) +type instance XConFieldSpec (GhcPass _) = ((EpaLocation, EpToken "#-}", EpaLocation), SourceText) +type instance XXConDeclField (GhcPass _) = DataConCantHappen type instance XRecTy GhcPs = AnnList () type instance XRecTy GhcRn = NoExtField @@ -541,14 +545,8 @@ type instance XExplicitMult _ _ GhcTc = NoExtField type instance XXMultAnnOn _ _ (GhcPass _) = DataConCantHappen -hsLinear :: a -> HsScaled OnArrow GhcPs a -hsLinear = HsScaled (HsLinearAnn noAnn) - -hsNoMultAnn :: a -> HsScaled OnRecField GhcPs a -hsNoMultAnn = HsScaled (HsUnannotated HsUnannOne noAnn) - -hsScaledToHsTypes :: HsScaled on GhcRn (LHsType GhcRn) -> [LHsType GhcRn] -hsScaledToHsTypes (HsScaled arr t) = [multAnnToHsType arr, t] +hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => HsMultAnnOn on (LHsType GhcPs) GhcPs +hsNoMultAnn = HsUnannotated HsUnannOne noAnn isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (multAnnToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName @@ -582,16 +580,17 @@ type instance XXConDeclField (GhcPass _) = DataConCantHappen instance OutputableBndrId p => Outputable (ConDeclField (GhcPass p)) where - ppr (ConDeclField _ fld_n (HsScaled fld_mult fld_ty) _) = ppr_names fld_n <+> ppr_mult <+> ppr fld_ty + ppr (ConDeclField _ fld_n cfs _) = ppr_names fld_n <+> pprHsConFieldSpecWith ppr_mult cfs where ppr_names :: [LFieldOcc (GhcPass p)] -> SDoc ppr_names [n] = pprPrefixOcc n ppr_names ns = sep (punctuate comma (map pprPrefixOcc ns)) - ppr_mult = case fld_mult of - HsUnannotated _ _ -> dcolon - HsLinearAnn _ -> text "%1" <+> dcolon - HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon + ppr_mult :: HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc + ppr_mult mult tyDoc = case mult of + HsUnannotated _ _ -> dcolon <+> tyDoc + HsLinearAnn _ -> text "%1" <+> dcolon <+> tyDoc + HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon <+> tyDoc --------------------- hsWcScopedTvs :: LHsSigWcType GhcRn -> [Name] @@ -723,10 +722,10 @@ mkHsAppKindTy at ty k = addCLocA ty k (HsAppKindTy at ty k) -- splitHsFunType (a -> (b -> c)) = ([a,b], c) -- It returns API Annotations for any parens removed splitHsFunType :: - LHsType (GhcPass p) + LHsType GhcPs -> ( ([EpToken "("], [EpToken ")"]) , EpAnnComments -- The locations of any parens and -- comments discarded - , [HsScaled OnArrow (GhcPass p) (LHsType (GhcPass p))], LHsType (GhcPass p)) + , [HsConFieldSpec OnArrow GhcPs], LHsType GhcPs) splitHsFunType ty = go ty where go (L l (HsParTy (op,cp) ty)) @@ -737,7 +736,7 @@ splitHsFunType ty = go ty go (L ll (HsFunTy _ mult x y)) | (anns, csy, args, res) <- splitHsFunType y - = (anns, csy S.<> epAnnComments ll, HsScaled mult x:args, res) + = (anns, csy S.<> epAnnComments ll, mkConFieldSpec mult x:args, res) go other = (noAnn, emptyComments, [], other) @@ -1297,6 +1296,23 @@ instance (Outputable tyarg, Outputable arg, Outputable rec) ppr (RecCon rec) = text "RecCon:" <+> ppr rec ppr (InfixCon l r) = text "InfixCon:" <+> ppr [l, r] +pprHsConFieldSpecWith :: (OutputableBndrId p) => (HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc) -> HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty) = ppr_mult mult (ppr prag <+> ppr mark <> ppr ty) + +pprHsConFieldSpecNoMult :: (OutputableBndrId p) => HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecNoMult = pprHsConFieldSpecWith (\_ d -> d) + +hsPlainTypeField :: LHsType GhcPs -> HsConFieldSpec OnArrow GhcPs +hsPlainTypeField (L _ (HsBangTy ann (HsBang unp str) lty)) = CFS ann unp str (HsLinearAnn noAnn) lty +hsPlainTypeField lty = CFS noAnn NoSrcUnpack NoSrcStrict (HsLinearAnn noAnn) lty + +hsConFieldSpecToHsTypes :: HsConFieldSpec on GhcRn -> [LHsType GhcRn] +hsConFieldSpecToHsTypes (CFS _ _ _ arr t) = [multAnnToHsType arr, t] + +mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs +mkConFieldSpec mult (L _ (HsBangTy ann (HsBang unp str) t)) = CFS ann unp str mult t +mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t + instance Outputable (XRecGhc (IdGhcP p)) => Outputable (FieldOcc (GhcPass p)) where ppr = ppr . foLabel ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -430,14 +430,14 @@ conArgDocs (ConDeclGADT{con_g_args = args, con_res_ty = res_ty}) = h98ConArgDocs :: HsConDeclH98Details GhcRn -> IntMap (HsDoc GhcRn) h98ConArgDocs con_args = case con_args of - PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args - InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (hsScaledThing arg1) - , unLoc (hsScaledThing arg2) ] + PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args + InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (cfs_type arg1) + , unLoc (cfs_type arg2) ] RecCon _ -> IM.empty gadtConArgDocs :: HsConDeclGADTDetails GhcRn -> HsType GhcRn -> IntMap (HsDoc GhcRn) gadtConArgDocs con_args res_ty = case con_args of - PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . hsScaledThing) args ++ [res_ty] + PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args ++ [res_ty] RecConGADT _ _ -> con_arg_docs 1 [res_ty] con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn) ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -920,17 +920,13 @@ repSrcStrictness SrcLazy = rep2 sourceLazyName [] repSrcStrictness SrcStrict = rep2 sourceStrictName [] repSrcStrictness NoSrcStrict = rep2 noSourceStrictnessName [] -repBangTy :: LBangType GhcRn -> MetaM (Core (M TH.BangType)) -repBangTy ty = do - MkC u <- repSrcUnpackedness su' - MkC s <- repSrcStrictness ss' +repConFieldSpec :: HsConFieldSpec on GhcRn -> MetaM (Core (M TH.BangType)) +repConFieldSpec (CFS _ su ss _ ty') = do + MkC u <- repSrcUnpackedness su + MkC s <- repSrcStrictness ss MkC b <- rep2 bangName [u, s] MkC t <- repLTy ty' rep2 bangTypeName [b, t] - where - (su', ss', ty') = case unLoc ty of - HsBangTy _ (HsBang su ss) ty -> (su, ss, ty) - _ -> (NoSrcUnpack, NoSrcStrict, ty) ------------------------------------------------------- -- Deriving clauses @@ -2838,8 +2834,8 @@ repH98DataCon con details rep2 normalCName [unC con', unC arg_tys] InfixCon st1 st2 -> do verifyLinearFields [st1, st2] - arg1 <- repBangTy (hsScaledThing st1) - arg2 <- repBangTy (hsScaledThing st2) + arg1 <- repConFieldSpec st1 + arg2 <- repConFieldSpec st2 rep2 infixCName [unC arg1, unC con', unC arg2] RecCon ips -> do arg_vtys <- repRecConArgs ips @@ -2865,33 +2861,33 @@ repGadtDataCons cons details res_ty -- TH currently only supports linear constructors. -- We also accept the (->) arrow when -XLinearTypes is off, because this -- denotes a linear field. -verifyLinearFields :: [HsScaled on GhcRn (LHsType GhcRn)] -> MetaM () +verifyLinearFields :: [HsConFieldSpec on GhcRn] -> MetaM () verifyLinearFields ps = do linear <- lift $ xoptM LangExt.LinearTypes - let allGood = all (hsMultIsLinear linear) ps + let allGood = all (hsMultIsLinear linear . cfs_multiplicity) ps unless allGood $ notHandled ThNonLinearDataCon -- Desugar the arguments in a data constructor declared with prefix syntax. -repPrefixConArgs :: [HsScaled OnArrow GhcRn (LHsType GhcRn)] +repPrefixConArgs :: [HsConFieldSpec OnArrow GhcRn] -> MetaM (Core [M TH.BangType]) repPrefixConArgs ps = do verifyLinearFields ps - repListM bangTypeTyConName repBangTy (map hsScaledThing ps) + repListM bangTypeTyConName repConFieldSpec ps -- Desugar the arguments in a data constructor declared with record syntax. repRecConArgs :: LocatedL [LConDeclField GhcRn] -> MetaM (Core [M TH.VarBangType]) repRecConArgs lips = do let ips = map unLoc (unLoc lips) - verifyLinearFields (map cd_fld_type ips) + verifyLinearFields (map cd_fld_spec ips) args <- concatMapM rep_ip ips coreListM varBangTypeTyConName args where - rep_ip ip = mapM (rep_one_ip (hsScaledThing $ cd_fld_type ip)) (cd_fld_names ip) + rep_ip ip = mapM (rep_one_ip (cd_fld_spec ip)) (cd_fld_names ip) - rep_one_ip :: LBangType GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) + rep_one_ip :: HsConFieldSpec OnRecField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) rep_one_ip t n = do { MkC v <- lookupOcc (unLoc . foLabel $ unLoc n) - ; MkC ty <- repBangTy t + ; MkC ty <- repConFieldSpec t ; rep2 varBangTypeName [v,ty] } ------------ Types ------------------- ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1789,8 +1789,8 @@ instance ToHie (LocatedA (ConDecl GhcRn)) where PrefixCon _ xs -> scaled_args_scope xs InfixCon a b -> scaled_args_scope [a, b] RecCon x -> mkScope x - where scaled_args_scope :: [HsScaled on GhcRn (LHsType GhcRn)] -> Scope - scaled_args_scope = foldr combineScopes NoScope . map (mkScope . hsScaledThing) + where scaled_args_scope :: [HsConFieldSpec on GhcRn] -> Scope + scaled_args_scope = foldr combineScopes NoScope . map (mkScope . cfs_type) instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where toHie (L span decls) = concatM $ @@ -1798,6 +1798,9 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where , toHie decls ] +instance ToHie (HsConFieldSpec on GhcRn) where + toHie (CFS _ _ _ w t) = concatM [toHie (multAnnToHsType w), toHie t] + instance ToHie (TScoped (HsWildCardBndrs GhcRn (LocatedA (HsSigType GhcRn)))) where toHie (TS sc (HsWC names a)) = concatM $ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names @@ -2000,7 +2003,7 @@ instance HiePass p => ToHie (LocatedC [LocatedA (HsExpr (GhcPass p))]) where instance ToHie (LocatedA (ConDeclField GhcRn)) where toHie (L span field) = concatM $ makeNode field (locA span) : case field of ConDeclField _ fields typ doc -> - [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ hsScaledThing typ)) fields + [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ cfs_type typ)) fields , toHie typ , toHie doc ] ===================================== compiler/GHC/Parser.y ===================================== @@ -2598,7 +2598,7 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (HsScaled (HsUnannotated HsUnannOne (epUniTok $2)) $3) + (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3) Nothing))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -72,6 +72,7 @@ module GHC.Parser.PostProcess ( mkMultTy, mkMultAnn, mkMultField, + mkConFieldSpec, -- Token location mkTokenLocation, @@ -2337,11 +2338,11 @@ dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) -- Normal prefix constructor, e.g. data T = MkT A B C dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) - = PrefixCon noTypeArgs (map hsLinear (toList flds)) + = PrefixCon noTypeArgs (map hsPlainTypeField (toList flds)) -- Infix constructor, e.g. data T = Int :! Bool dataConBuilderDetails (L (EpAnn _ _ csl) (InfixDataConBuilder (L (EpAnn anc ann csll) lhs) _ rhs)) - = InfixCon (hsLinear (L (EpAnn anc ann (csl Semi.<> csll)) lhs)) (hsLinear rhs) + = InfixCon (hsPlainTypeField (L (EpAnn anc ann (csl Semi.<> csll)) lhs)) (hsPlainTypeField rhs) instance DisambTD DataConBuilder where @@ -2409,7 +2410,7 @@ checkNotPromotedDataCon IsPromoted (L l name) = mkUnboxedSumCon :: LHsType GhcPs -> ConTag -> Arity -> (LocatedN RdrName, HsConDeclH98Details GhcPs) mkUnboxedSumCon t tag arity = - (noLocA (getRdrName (sumDataCon tag arity)), PrefixCon noTypeArgs [hsLinear t]) + (noLocA (getRdrName (sumDataCon tag arity)), PrefixCon noTypeArgs [hsPlainTypeField t]) {- Note [Ambiguous syntactic categories] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3519,15 +3520,15 @@ mkMultAnn pct t@(L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) pct1 = epTokenWidenR pct (locA (getLoc t)) mkMultAnn pct t = HsMultAnn pct t -mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsScaled OnRecField GhcPs (LBangType GhcPs) +mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnRecField GhcPs mkMultField pct (L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) col t -- See #18888 for the use of (SourceText "1") above - = HsScaled (HsLinearAnn (pct1, col)) t + = mkConFieldSpec (HsLinearAnn (pct1, col)) t where -- The location of "%" combined with the location of "1". pct1 :: EpToken "%1" pct1 = epTokenWidenR pct (locA (getLoc t)) -mkMultField pct mult col t = HsScaled (HsExplicitMult (pct, col) mult) t +mkMultField pct mult col t = mkConFieldSpec (HsExplicitMult (pct, col) mult) t mkTokenLocation :: SrcSpan -> TokenLocation mkTokenLocation (UnhelpfulSpan _) = NoTokenLoc ===================================== compiler/GHC/Parser/PostProcess/Haddock.hs ===================================== @@ -788,12 +788,12 @@ getConDoc l = extendHdkA l $ liftHdkA $ getPrevNextDoc l -- Add documentation comment to a data constructor field. -- Used for PrefixCon and InfixCon. addHaddockConDeclFieldTy - :: HsScaled on GhcPs (LHsType GhcPs) - -> HdkA (HsScaled on GhcPs (LHsType GhcPs)) -addHaddockConDeclFieldTy (HsScaled mult (L l t)) = + :: HsConFieldSpec on GhcPs + -> HdkA (HsConFieldSpec on GhcPs) +addHaddockConDeclFieldTy (CFS ann unpack strict mult (L l t)) = extendHdkA (locA l) $ liftHdkA $ do mDoc <- getPrevNextDoc (locA l) - return (HsScaled mult (mkLHsDocTy (L l t) mDoc)) + return (CFS ann unpack strict mult (mkLHsDocTy (L l t) mDoc)) -- Add documentation comment to a data constructor field. -- Used for RecCon. @@ -909,6 +909,9 @@ We implement this in two steps: instance HasHaddock a => HasHaddock (HsScaled on GhcPs a) where addHaddock (HsScaled mult a) = HsScaled mult <$> addHaddock a +instance HasHaddock (HsConFieldSpec on GhcPs) where + addHaddock (CFS ann unp str mult a) = CFS ann unp str mult <$> addHaddock a + instance HasHaddock a => HasHaddock (HsWildCardBndrs GhcPs a) where addHaddock (HsWC _ t) = HsWC noExtField <$> addHaddock t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -21,7 +21,7 @@ module GHC.Rename.HsType ( lookupField, mkHsOpTyRn, rnLTyVar, - rnScaledLHsType, + rnHsConFieldSpec, -- Precence related stuff NegationHandling(..), @@ -450,16 +450,16 @@ rnLHsType ctxt ty = rnLHsTyKi (mkTyKiEnv ctxt TypeLevel RnTypeBody) ty rnLHsTypes :: HsDocContext -> [LHsType GhcPs] -> RnM ([LHsType GhcRn], FreeVars) rnLHsTypes doc tys = mapFvRn (rnLHsType doc) tys -rnScaledLHsType :: HsDocContext -> HsScaled on GhcPs (LHsType GhcPs) - -> RnM (HsScaled on GhcRn (LHsType GhcRn), FreeVars) -rnScaledLHsType doc = rnScaledLHsTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) +rnHsConFieldSpec :: HsDocContext -> HsConFieldSpec on GhcPs + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpec doc = rnHsConFieldSpecTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) -rnScaledLHsTyKi :: RnTyKiEnv -> HsScaled on GhcPs (LHsType GhcPs) - -> RnM (HsScaled on GhcRn (LHsType GhcRn), FreeVars) -rnScaledLHsTyKi env (HsScaled w ty) = do +rnHsConFieldSpecTyKi :: RnTyKiEnv -> HsConFieldSpec on GhcPs + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpecTyKi env (CFS ext unp str w ty) = do (w' , fvs_w) <- rnHsMultAnnOn env w (ty', fvs) <- rnLHsTyKi env ty - return (HsScaled w' ty', fvs `plusFV` fvs_w) + return (CFS ext unp str w' ty', fvs `plusFV` fvs_w) rnHsType :: HsDocContext -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) @@ -1339,7 +1339,7 @@ rnField :: FastStringEnv FieldLabel -> RnTyKiEnv -> LConDeclField GhcPs -> RnM (LConDeclField GhcRn, FreeVars) rnField fl_env env (L l (ConDeclField _ names ty haddock_doc)) = do { let new_names = map (fmap (lookupField fl_env)) names - ; (new_ty, fvs) <- rnScaledLHsTyKi env ty + ; (new_ty, fvs) <- rnHsConFieldSpecTyKi env ty ; haddock_doc' <- traverse rnLHsDoc haddock_doc ; return (L l (ConDeclField noExtField new_names new_ty haddock_doc') , fvs) } @@ -2035,7 +2035,7 @@ extractConDeclGADTDetailsTyVars :: HsConDeclGADTDetails GhcPs -> FreeKiTyVars -> FreeKiTyVars extractConDeclGADTDetailsTyVars con_args = case con_args of PrefixConGADT _ args -> extract_scaled_ltys args - RecConGADT _ (L _ flds) -> extract_scaled_ltys $ map (cd_fld_type . unLoc) $ flds + RecConGADT _ (L _ flds) -> extract_scaled_ltys $ map (cd_fld_spec . unLoc) $ flds -- | Get type/kind variables mentioned in the kind signature, preserving -- left-to-right order: @@ -2051,13 +2051,13 @@ extractDataDefnKindVars (HsDataDefn { dd_kindSig = ksig }) extract_lctxt :: LHsContext GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lctxt ctxt = extract_ltys (unLoc ctxt) -extract_scaled_ltys :: [HsScaled on GhcPs (LHsType GhcPs)] +extract_scaled_ltys :: [HsConFieldSpec on GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_scaled_ltys args acc = foldr extract_scaled_lty acc args -extract_scaled_lty :: HsScaled on GhcPs (LHsType GhcPs) +extract_scaled_lty :: HsConFieldSpec on GhcPs -> FreeKiTyVars -> FreeKiTyVars -extract_scaled_lty (HsScaled m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc +extract_scaled_lty (CFS _ _ _ m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc extract_ltys :: [LHsType GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_ltys tys acc = foldr extract_lty acc tys @@ -2068,7 +2068,7 @@ extract_lty (L _ ty) acc HsTyVar _ _ ltv -> extract_tv ltv acc HsBangTy _ _ ty -> extract_lty ty acc HsRecTy _ flds -> foldr (extract_scaled_lty - . cd_fld_type . unLoc) acc + . cd_fld_spec . unLoc) acc flds HsAppTy _ ty1 ty2 -> extract_lty ty1 $ extract_lty ty2 acc ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1928,9 +1928,7 @@ rnDataDefn doc (HsDataDefn { dd_cType = cType, dd_ctxt = context, dd_cons = cond has_labelled_fields _ = False has_strictness_flags condecl - = any (is_strict . getBangStrictness . hsScaledThing) (con_args condecl) - - is_strict (HsSrcBang _ (HsBang _ s)) = isSrcStrict s + = any (isSrcStrict . cfs_bang) (con_args condecl) con_args (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = args con_args (ConDeclH98 { con_args = PrefixCon _ args }) = args @@ -2483,11 +2481,11 @@ rnConDeclH98Details :: -> HsConDeclH98Details GhcPs -> RnM (HsConDeclH98Details GhcRn, FreeVars) rnConDeclH98Details _ doc (PrefixCon _ tys) - = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys + = do { (new_tys, fvs) <- mapFvRn (rnHsConFieldSpec doc) tys ; return (PrefixCon noTypeArgs new_tys, fvs) } rnConDeclH98Details _ doc (InfixCon ty1 ty2) - = do { (new_ty1, fvs1) <- rnScaledLHsType doc ty1 - ; (new_ty2, fvs2) <- rnScaledLHsType doc ty2 + = do { (new_ty1, fvs1) <- rnHsConFieldSpec doc ty1 + ; (new_ty2, fvs2) <- rnHsConFieldSpec doc ty2 ; return (InfixCon new_ty1 new_ty2, fvs1 `plusFV` fvs2) } rnConDeclH98Details con doc (RecCon flds) = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds @@ -2499,7 +2497,7 @@ rnConDeclGADTDetails :: -> HsConDeclGADTDetails GhcPs -> RnM (HsConDeclGADTDetails GhcRn, FreeVars) rnConDeclGADTDetails _ doc (PrefixConGADT _ tys) - = do { (new_tys, fvs) <- mapFvRn (rnScaledLHsType doc) tys + = do { (new_tys, fvs) <- mapFvRn (rnHsConFieldSpec doc) tys ; return (PrefixConGADT noExtField new_tys, fvs) } rnConDeclGADTDetails con doc (RecConGADT _ flds) = do { (new_flds, fvs) <- rnRecConDeclFields con doc flds ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -283,7 +283,7 @@ no_anon_wc_ty lty = go lty HsKindSig _ ty kind -> go ty && go kind HsDocTy _ ty _ -> go ty HsBangTy _ _ ty -> go ty - HsRecTy _ flds -> gos $ concatMap (hsScaledToHsTypes . cd_fld_type . unLoc) flds + HsRecTy _ flds -> gos $ concatMap (hsConFieldSpecToHsTypes . cd_fld_spec . unLoc) flds HsExplicitListTy _ _ tys -> gos tys HsExplicitTupleTy _ _ tys -> gos tys HsForAllTy { hst_tele = tele ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1799,11 +1799,11 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled on GhcRn (LHsType GhcRn)] -> TcM () +kcConArgTys :: NewOrData -> TcKind -> [HsConFieldSpec on GhcRn] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) + ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -1813,14 +1813,14 @@ kcConH98Args new_or_data res_kind con_args = case con_args of PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ - map (cd_fld_type . unLoc) flds + map (cd_fld_spec . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () kcConGADTArgs new_or_data res_kind con_args = case con_args of PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ - map (cd_fld_type . unLoc) flds + map (cd_fld_spec . unLoc) flds kcConDecls :: Foldable f => NewOrData @@ -3893,7 +3893,7 @@ tcConIsInfixGADT con details RecConGADT{} -> return False PrefixConGADT _ arg_tys -- See Note [Infix GADT constructors] | isSymOcc (getOccName con) - , [_ty1,_ty2] <- map hsScaledThing arg_tys + , [_ty1,_ty2] <- arg_tys -> do { fix_env <- getFixityEnv ; return (con `elemNameEnv` fix_env) } | otherwise -> return False @@ -3924,13 +3924,13 @@ tcConGADTArgs exp_kind (RecConGADT _ fields) tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes - -> HsScaled on GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) -tcConArg exp_kind (HsScaled w bty) + -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) +tcConArg exp_kind (CFS (_, src) unp str w bty) = do { traceTc "tcConArg 1" (ppr bty) ; arg_ty <- tcCheckLHsTypeInContext (getBangType bty) exp_kind ; w' <- tcDataConMult w ; traceTc "tcConArg 2" (ppr bty) - ; return (Scaled w' arg_ty, getBangStrictness bty) } + ; return (Scaled w' arg_ty, HsSrcBang src (HsBang unp str)) } tcRecConDeclFields :: ContextKind -> LocatedL [LConDeclField GhcRn] @@ -3939,7 +3939,7 @@ tcRecConDeclFields exp_kind fields = mapM (tcConArg exp_kind) btys where -- We need a one-to-one mapping from field_names to btys - combined = map (\(L _ f) -> (cd_fld_names f, cd_fld_type f)) + combined = map (\(L _ f) -> (cd_fld_names f, cd_fld_spec f)) (unLoc fields) explode (ns,ty) = zip ns (repeat ty) exploded = concatMap explode combined ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -3,6 +3,7 @@ {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE DataKinds #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -689,7 +690,7 @@ cvtConstr :: TH.Name -- ^ name of first constructor of parent type cvtConstr _ do_con_name (NormalC c strtys) = do { c' <- do_con_name c ; tys' <- mapM cvt_arg strtys - ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing (PrefixCon noTypeArgs (map hsLinear tys')) } + ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing (PrefixCon noTypeArgs tys') } cvtConstr parent_con do_con_name (RecC c varstrtys) = do { c' <- do_con_name c @@ -702,7 +703,7 @@ cvtConstr _ do_con_name (InfixC st1 c st2) ; st1' <- cvt_arg st1 ; st2' <- cvt_arg st2 ; returnLA $ mkConDeclH98 noAnn c' Nothing Nothing - (InfixCon (hsLinear st1') (hsLinear st2')) } + (InfixCon st1' st2') } cvtConstr parent_con do_con_name (ForallC tvs ctxt con) = do { tvs' <- cvtTvs tvs @@ -741,7 +742,7 @@ cvtConstr _ do_con_name (GadtC c strtys ty) = case nonEmpty c of { c' <- mapM do_con_name c ; args <- mapM cvt_arg strtys ; ty' <- cvtType ty - ; mk_gadt_decl c' (PrefixConGADT noExtField $ map hsLinear args) ty'} + ; mk_gadt_decl c' (PrefixConGADT noExtField args) ty'} cvtConstr parent_con do_con_name (RecGadtC c varstrtys ty) = case nonEmpty c of Nothing -> failWith RecGadtNoCons @@ -775,13 +776,13 @@ cvtSrcStrictness NoSourceStrictness = NoSrcStrict cvtSrcStrictness SourceLazy = SrcLazy cvtSrcStrictness SourceStrict = SrcStrict -cvt_arg :: (TH.Bang, TH.Type) -> CvtM (LHsType GhcPs) +cvt_arg :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) cvt_arg (Bang su ss, ty) = do { ty'' <- cvtType ty ; let ty' = parenthesizeHsType appPrec ty'' su' = cvtSrcUnpackedness su ss' = cvtSrcStrictness ss - ; returnLA $ HsBangTy (noAnn, NoSourceText) (HsBang su' ss') ty' } + ; return $ CFS noAnn su' ss' hsNoMultAnn ty' } cvt_id_arg :: TH.Name -- ^ parent constructor name -> (TH.Name, TH.Bang, TH.Type) -> CvtM (LConDeclField GhcPs) @@ -792,7 +793,7 @@ cvt_id_arg parent_con (i, str, ty) { cd_fld_ext = noExtField , cd_fld_names = [L (l2l li) $ FieldOcc noExtField (L li i')] - , cd_fld_type = hsNoMultAnn ty' + , cd_fld_spec = ty' , cd_fld_doc = Nothing} } cvtDerivs :: [TH.DerivClause] -> CvtM (HsDeriving GhcPs) ===================================== compiler/Language/Haskell/Syntax/Decls.hs ===================================== @@ -1122,7 +1122,7 @@ or contexts in two parts: -- | The arguments in a Haskell98-style data constructor. type HsConDeclH98Details pass - = HsConDetails Void (HsScaled OnArrow pass (LBangType pass)) (XRec pass [LConDeclField pass]) + = HsConDetails Void (HsConFieldSpec OnArrow pass) (XRec pass [LConDeclField pass]) -- The Void argument to HsConDetails here is a reflection of the fact that -- type applications are not allowed in data constructor declarations. @@ -1133,7 +1133,7 @@ type HsConDeclH98Details pass -- derived Show instances—see Note [Infix GADT constructors] in -- GHC.Tc.TyCl—but that is an orthogonal concern.) data HsConDeclGADTDetails pass - = PrefixConGADT !(XPrefixConGADT pass) [HsScaled OnArrow pass (LBangType pass)] + = PrefixConGADT !(XPrefixConGADT pass) [HsConFieldSpec OnArrow pass] | RecConGADT !(XRecConGADT pass) (XRec pass [LConDeclField pass]) | XConDeclGADTDetails !(XXConDeclGADTDetails pass) ===================================== compiler/Language/Haskell/Syntax/Extension.hs ===================================== @@ -682,6 +682,11 @@ type family XXTyVarBndr x type family XConDeclField x type family XXConDeclField x +-- --------------------------------------------------------------------- +-- ConFieldSpec type families +type family XConFieldSpec x +type family XXConFieldSpec x + -- --------------------------------------------------------------------- -- FieldOcc type families type family XCFieldOcc x ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -23,7 +23,7 @@ GHC.Hs.Type: Abstract syntax: user-defined types -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* module Language.Haskell.Syntax.Type ( HsScaled(..), - hsMultIsLinear, hsScaledThing, hsScaledGeneralize, + hsMultIsLinear, hsScaledThing, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), pattern HsUnrestrictedArrow, XUnannotated, XLinearAnn, XExplicitMult, XXMultAnnOn, @@ -57,6 +57,7 @@ module Language.Haskell.Syntax.Type ( ConDeclField(..), LConDeclField, HsConDetails(..), noTypeArgs, + HsConFieldSpec(..), hsConFieldSpecGeneralize, FieldOcc(..), LFieldOcc, @@ -67,7 +68,7 @@ module Language.Haskell.Syntax.Type ( import {-# SOURCE #-} Language.Haskell.Syntax.Expr ( HsUntypedSplice ) -import Language.Haskell.Syntax.Basic ( HsBang(..) ) +import Language.Haskell.Syntax.Basic ( HsBang(..), SrcStrictness, SrcUnpackedness ) import Language.Haskell.Syntax.Extension import Language.Haskell.Syntax.Specificity @@ -983,13 +984,10 @@ type family XXMultAnnOn (on :: HsMultAnnOnWhat) mult p data HsScaled on pass a = HsScaled (HsMultAnnOn on (LHsType pass) pass) a deriving (Functor) -hsScaledGeneralize :: HsScaled on pass a -> HsScaled on1 pass a -hsScaledGeneralize = unsafeCoerce - -hsMultIsLinear :: Bool -> HsScaled on pass a -> Bool -hsMultIsLinear _ (HsScaled (HsUnannotated HsUnannOne _) _) = True -hsMultIsLinear linear (HsScaled (HsUnannotated HsUnannMany _) _) = not linear -hsMultIsLinear _ (HsScaled HsLinearAnn{} _) = True +hsMultIsLinear :: Bool -> HsMultAnnOn on mult pass -> Bool +hsMultIsLinear _ (HsUnannotated HsUnannOne _) = True +hsMultIsLinear linear (HsUnannotated HsUnannMany _) = not linear +hsMultIsLinear _ HsLinearAnn{} = True hsMultIsLinear _ _ = False hsScaledThing :: HsScaled on pass a -> a @@ -1098,7 +1096,7 @@ data ConDeclField pass -- Record fields have Haddock docs on them = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_type :: HsScaled OnRecField pass (LBangType pass), + cd_fld_spec :: HsConFieldSpec OnRecField pass, cd_fld_doc :: Maybe (LHsDoc pass)} | XConDeclField !(XXConDeclField pass) @@ -1129,6 +1127,16 @@ data HsConDetails tyarg arg rec noTypeArgs :: [Void] noTypeArgs = [] +data HsConFieldSpec on pass + = CFS { cfs_ext :: XConFieldSpec pass + , cfs_unpack :: SrcUnpackedness + , cfs_bang :: SrcStrictness + , cfs_multiplicity :: HsMultAnnOn on (LHsType pass) pass + , cfs_type :: LHsType pass } + +hsConFieldSpecGeneralize :: HsConFieldSpec on pass -> HsConFieldSpec on1 pass +hsConFieldSpecGeneralize = unsafeCoerce + {- Note [ConDeclField pass] ~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4448,13 +4448,29 @@ instance (ExactPrint a) => ExactPrint (HsScaled OnArrow GhcPs a) where arr' <- markArrow arr return (HsScaled arr' t') -instance (ExactPrint a) => ExactPrint (HsScaled OnRecField GhcPs a) where +-- instance (ExactPrint a) => ExactPrint (HsScaled OnRecField GhcPs a) where +-- getAnnotationEntry = const NoEntryVal +-- setAnnotationAnchor a _ _ _ = a +-- exact (HsScaled mult t) = do +-- mult' <- markRecFieldMult mult +-- t' <- markAnnotated t +-- return (HsScaled mult' t') + +instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (HsScaled mult t) = do + exact (CFS an unp str arr t) = do + t' <- markAnnotated t + arr' <- markArrow arr + return (CFS an unp str arr' t') + +instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where + getAnnotationEntry = const NoEntryVal + setAnnotationAnchor a _ _ _ = a + exact (CFS an unp str mult t) = do mult' <- markRecFieldMult mult t' <- markAnnotated t - return (HsScaled mult' t') + return (CFS an unp str mult' t') -- --------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs ===================================== @@ -295,14 +295,14 @@ ppCtor sDocContext dat subdocs con at ConDeclH98{con_args = con_args'} = -- AZ:TODO get rid of the concatMap concatMap (lookupCon sDocContext subdocs) [con_name con] ++ f con_args' where - f :: HsConDetails v (HsScaled on GhcRn (LHsType GhcRn)) (LocatedL [LocatedA (ConDeclField GhcRn)]) -> [String] - f (PrefixCon _ args) = [typeSig name $ (map hsScaledThing args) ++ [resType]] + f :: HsConDetails v (HsConFieldSpec on GhcRn) (LocatedL [LocatedA (ConDeclField GhcRn)]) -> [String] + f (PrefixCon _ args) = [typeSig name $ (map cfs_type args) ++ [resType]] f (InfixCon a1 a2) = f $ PrefixCon [] [a1, a2] f (RecCon (L _ recs)) = - f (PrefixCon [] $ map (cd_fld_type . unLoc) recs) + f (PrefixCon [] $ map (cd_fld_spec . unLoc) recs) ++ concat [ (concatMap (lookupCon sDocContext subdocs . noLocA . unLoc . foLabel . unLoc) (cd_fld_names r)) - ++ [out sDocContext (map (foExt . unLoc) $ cd_fld_names r) `typeSig` [resType, hsScaledThing $ cd_fld_type r]] + ++ [out sDocContext (map (foExt . unLoc) $ cd_fld_names r) `typeSig` [resType, cfs_type $ cd_fld_spec r]] | r <- map unLoc recs ] @@ -356,8 +356,8 @@ ppCtor Nothing -> tau_ty tau_ty = foldr mkFunTy res_ty $ case args of - PrefixConGADT _ pos_args -> map hsScaledThing pos_args - RecConGADT _ (L _ flds) -> map (hsScaledThing . cd_fld_type . unL) flds + PrefixConGADT _ pos_args -> map cfs_type pos_args + RecConGADT _ (L _ flds) -> map (cfs_type . cd_fld_spec . unL) flds mkFunTy a b = noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) a b) ppFixity :: SDocContext -> (Name, Fixity) -> [String] ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -964,7 +964,7 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = hsep [ header_ , ppOcc - , hsep (map (ppLParendType unicode . hsScaledThing) args) + , hsep (map (ppLParendType unicode . cfs_type) args) ] -- Record constructor, e.g. 'Identity { runIdentity :: a }' RecCon _ -> header_ <+> ppOcc @@ -974,9 +974,9 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = | otherwise -> hsep [ header_ - , ppLParendType unicode (hsScaledThing arg1) + , ppLParendType unicode (cfs_type arg1) , ppOccInfix - , ppLParendType unicode (hsScaledThing arg2) + , ppLParendType unicode (cfs_type arg2) ] ConDeclGADT{} | hasArgDocs || not (isEmpty fieldPart) -> ppOcc @@ -993,15 +993,15 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = -- GADT record declarations RecConGADT _ _ -> doConstrArgsWithDocs [] -- GADT prefix data constructors - PrefixConGADT _ args | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing args) + PrefixConGADT _ args | hasArgDocs -> doConstrArgsWithDocs (map cfs_type args) _ -> empty ConDeclH98{con_args = con_args'} -> case con_args' of -- H98 record declarations RecCon (L _ fields) -> doRecordFields fields -- H98 prefix data constructors - PrefixCon _ args | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing args) + PrefixCon _ args | hasArgDocs -> doConstrArgsWithDocs (map cfs_type args) -- H98 infix data constructor - InfixCon arg1 arg2 | hasArgDocs -> doConstrArgsWithDocs (map hsScaledThing [arg1, arg2]) + InfixCon arg1 arg2 | hasArgDocs -> doConstrArgsWithDocs (map cfs_type [arg1, arg2]) _ -> empty doRecordFields fields = @@ -1035,7 +1035,7 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = decltt ( cat (punctuate comma (map (ppBinder . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode ltype (dcolon unicode) - <+> ppLType unicode (hsScaledThing ltype) + <+> ppLType unicode (cfs_type ltype) ) <-> rDoc mbDoc where @@ -1047,8 +1047,8 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd -ppRecFieldMultAnn :: Bool -> HsScaled on DocNameI a -> LaTeX -> LaTeX -ppRecFieldMultAnn unicode (HsScaled arr _) following = case arr of +ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX +ppRecFieldMultAnn unicode (CFS _ _ _ arr _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1350,7 +1350,7 @@ ppShortConstrParts summary dataInst con unicode qual = in case det of -- Prefix constructor, e.g. 'Just a' PrefixCon _ args -> - ( header_ <+> hsep (ppOcc : map (ppLParendType unicode qual HideEmptyContexts . hsScaledThing) args) + ( header_ <+> hsep (ppOcc : map (ppLParendType unicode qual HideEmptyContexts . cfs_type) args) , noHtml , noHtml ) @@ -1368,9 +1368,9 @@ ppShortConstrParts summary dataInst con unicode qual = InfixCon arg1 arg2 -> ( header_ <+> hsep - [ ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg1) + [ ppLParendType unicode qual HideEmptyContexts (cfs_type arg1) , ppOccInfix - , ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg2) + , ppLParendType unicode qual HideEmptyContexts (cfs_type arg2) ] , noHtml , noHtml @@ -1431,7 +1431,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = | otherwise -> hsep [ header_ <+> ppOcc - , hsep (map (ppLParendType unicode qual HideEmptyContexts . hsScaledThing) args) + , hsep (map (ppLParendType unicode qual HideEmptyContexts . cfs_type) args) , fixity ] -- Record constructor, e.g. 'Identity { runIdentity :: a }' @@ -1441,9 +1441,9 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = | hasArgDocs -> header_ <+> ppOcc <+> fixity | otherwise -> hsep - [ header_ <+> ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg1) + [ header_ <+> ppLParendType unicode qual HideEmptyContexts (cfs_type arg1) , ppOccInfix - , ppLParendType unicode qual HideEmptyContexts (hsScaledThing arg2) + , ppLParendType unicode qual HideEmptyContexts (cfs_type arg2) , fixity ] -- GADT constructor, e.g. 'Foo :: Int -> Foo' @@ -1483,7 +1483,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = doConstrArgsWithDocs args = subFields pkg qual $ case con of ConDeclH98{} -> [ (ppLParendType unicode qual HideEmptyContexts arg, mdoc, []) - | (i, arg) <- zip [0 ..] (map hsScaledThing args) + | (i, arg) <- zip [0 ..] (map cfs_type args) , let mdoc = Map.lookup i argDocs ] ConDeclGADT{} -> @@ -1543,7 +1543,7 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = ] ) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) - <+> ppLType unicode qual HideEmptyContexts (hsScaledThing ltype) + <+> ppLType unicode qual HideEmptyContexts (cfs_type ltype) , mbDoc , [] ) @@ -1555,8 +1555,8 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd -ppRecFieldMultAnn :: Unicode -> Qualification -> HsScaled on DocNameI a -> Html -> Html -ppRecFieldMultAnn unicode qual (HsScaled arr _) following = case arr of +ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html +ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following @@ -1565,7 +1565,7 @@ ppShortField :: Bool -> Unicode -> Qualification -> ConDeclField DocNameI -> Htm ppShortField summary unicode qual (ConDeclField _ names ltype _) = hsep (punctuate comma (map ((ppBinder summary) . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) - <+> ppLType unicode qual HideEmptyContexts (hsScaledThing ltype) + <+> ppLType unicode qual HideEmptyContexts (cfs_type ltype) -- | Pretty print an expanded pattern (for bundled patterns) ppSideBySidePat ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -494,13 +494,10 @@ synifyDataCon use_gadt_syntax dc = linear_tys = zipWith - ( \(Scaled mult ty) bang -> + ( \(Scaled mult ty) (HsSrcBang st (HsBang unp str)) -> let tySyn = synifyType WithinType [] ty multSyn = synifyMultRec [] mult - bangTy = case bang of - (HsSrcBang _ (HsBang NoSrcUnpack NoSrcStrict)) -> tySyn - (HsSrcBang src bang') -> noLocA $ HsBangTy (noAnn, src) bang' tySyn - in HsScaled multSyn bangTy + in CFS (noAnn, st) unp str multSyn tySyn ) arg_tys (dataConSrcBangs dc) @@ -518,15 +515,15 @@ synifyDataCon use_gadt_syntax dc = mk_h98_arg_tys = case (use_named_field_syntax, use_infix_syntax) of (True, True) -> Left "synifyDataCon: contradiction!" (True, False) -> return $ RecCon (noLocA field_tys) - (False, False) -> return $ PrefixCon noTypeArgs (map hsScaledGeneralize linear_tys) - (False, True) -> case map hsScaledGeneralize linear_tys of + (False, False) -> return $ PrefixCon noTypeArgs (map hsConFieldSpecGeneralize linear_tys) + (False, True) -> case map hsConFieldSpecGeneralize linear_tys of [a, b] -> return $ InfixCon a b _ -> Left "synifyDataCon: infix with non-2 args?" mk_gadt_arg_tys :: HsConDeclGADTDetails GhcRn mk_gadt_arg_tys | use_named_field_syntax = RecConGADT noExtField (noLocA field_tys) - | otherwise = PrefixConGADT noExtField (map hsScaledGeneralize linear_tys) + | otherwise = PrefixConGADT noExtField (map hsConFieldSpecGeneralize linear_tys) in -- finally we get synifyDataCon's result! if use_gadt_syntax ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -220,7 +220,7 @@ getGADTConType -- tau_ty :: LHsType DocNameI tau_ty = case args of RecConGADT _ flds -> mkFunTy (noLocA (HsRecTy noAnn (unLoc flds))) res_ty - PrefixConGADT _ pos_args -> foldr mkFunTy res_ty (map hsScaledThing pos_args) + PrefixConGADT _ pos_args -> foldr mkFunTy res_ty (map cfs_type pos_args) mkFunTy :: LHsType DocNameI -> LHsType DocNameI -> LHsType DocNameI mkFunTy a b = noLocA (HsFunTy noAnn (HsUnrestrictedArrow noExtField) a b) @@ -361,8 +361,8 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] field_avail (L _ (ConDeclField _ fs _ _)) = all (\f -> (unLoc . foLabel . unLoc $ f) `elem` names) fs - field_types :: [LConDeclField GhcRn] -> [HsScaled OnArrow GhcRn (LBangType GhcRn)] - field_types flds = [hsScaledGeneralize t | L _ (ConDeclField _ _ t _) <- flds] + field_types :: [LConDeclField GhcRn] -> [HsConFieldSpec OnArrow GhcRn] + field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t _) <- flds] keep _ = Nothing restrictDecls :: [Name] -> [LSig GhcRn] -> [LSig GhcRn] @@ -513,7 +513,7 @@ reparenBndrKind v at XBndrKind{} = v -- | Add parenthesis around the types in a 'ConDeclField' (see 'reparenTypePrec') reparenConDeclField :: XRecCond a => ConDeclField a -> ConDeclField a -reparenConDeclField (ConDeclField x n t d) = ConDeclField x n (fmap reparenLType t) d +reparenConDeclField (ConDeclField x n (CFS an unp str m t) d) = ConDeclField x n (CFS an unp str m (reparenLType t)) d reparenConDeclField c at XConDeclField{} = c ------------------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Create.hs ===================================== @@ -962,12 +962,12 @@ extractPatternSyn nm t tvs cons = let args = case con of ConDeclH98{con_args = con_args'} -> case con_args' of - PrefixCon _ args' -> map hsScaledThing args' - RecCon (L _ fields) -> hsScaledThing . cd_fld_type . unLoc <$> fields - InfixCon arg1 arg2 -> map hsScaledThing [arg1, arg2] + PrefixCon _ args' -> map cfs_type args' + RecCon (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields + InfixCon arg1 arg2 -> map cfs_type [arg1, arg2] ConDeclGADT{con_g_args = con_args'} -> case con_args' of - PrefixConGADT _ args' -> map hsScaledThing args' - RecConGADT _ (L _ fields) -> hsScaledThing . cd_fld_type . unLoc <$> fields + PrefixConGADT _ args' -> map cfs_type args' + RecConGADT _ (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields typ = longArrow args (data_ty con) typ' = case con of @@ -999,7 +999,7 @@ extractRecSel nm t tvs (L _ con : rest) = case getRecConArgs_maybe con of Just (L _ fields) | ((l, L _ (ConDeclField _ _nn ty _)) : _) <- matching_fields fields -> - pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (getBangType $ hsScaledThing ty)))))) + pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (cfs_type ty)))))) -- TODO : was getBangType $ hsScaledThing ty _ -> extractRecSel nm t tvs rest where matching_fields :: [LConDeclField GhcRn] -> [(SrcSpan, LConDeclField GhcRn)] ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -718,10 +718,10 @@ renameCon } ) -renameHsScaled - :: HsScaled on GhcRn (LHsType GhcRn) - -> RnM (HsScaled on DocNameI (LHsType DocNameI)) -renameHsScaled (HsScaled w ty) = HsScaled <$> renameMultAnnOn w <*> renameLType ty +renameHsConFieldSpec + :: HsConFieldSpec on GhcRn + -> RnM (HsConFieldSpec on DocNameI) +renameHsConFieldSpec (CFS _ unp str w ty) = CFS noExtField unp str <$> renameMultAnnOn w <*> renameLType ty renameH98Details :: HsConDeclH98Details GhcRn @@ -729,10 +729,10 @@ renameH98Details renameH98Details (RecCon (L l fields)) = do fields' <- mapM renameConDeclFieldField fields return (RecCon (L (locA l) fields')) -renameH98Details (PrefixCon ts ps) = PrefixCon ts <$> mapM renameHsScaled ps +renameH98Details (PrefixCon ts ps) = PrefixCon ts <$> mapM renameHsConFieldSpec ps renameH98Details (InfixCon a b) = do - a' <- renameHsScaled a - b' <- renameHsScaled b + a' <- renameHsConFieldSpec a + b' <- renameHsConFieldSpec b return (InfixCon a' b') renameGADTDetails @@ -741,12 +741,12 @@ renameGADTDetails renameGADTDetails (RecConGADT _ (L l fields)) = do fields' <- mapM renameConDeclFieldField fields return (RecConGADT noExtField (L (locA l) fields')) -renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsScaled ps +renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsConFieldSpec ps renameConDeclFieldField :: LConDeclField GhcRn -> RnM (LConDeclField DocNameI) renameConDeclFieldField (L l (ConDeclField _ names t doc)) = do names' <- mapM renameLFieldOcc names - t' <- renameHsScaled t + t' <- renameHsConFieldSpec t doc' <- mapM renameLDocHsSyn doc return $ L (locA l) (ConDeclField noExtField names' t' doc') ===================================== utils/haddock/haddock-api/src/Haddock/Types.hs ===================================== @@ -964,6 +964,9 @@ type instance XXLHsQTyVars DocNameI = DataConCantHappen type instance XConDeclField DocNameI = NoExtField type instance XXConDeclField DocNameI = DataConCantHappen +type instance XConFieldSpec DocNameI = NoExtField +type instance XXConFieldSpec DocNameI = DataConCantHappen + type instance XXPat DocNameI = DataConCantHappen type instance XXHsBindsLR DocNameI a = DataConCantHappen View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8bc7e5650d11199a3963b8b8c49d08dd81cfd5b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8bc7e5650d11199a3963b8b8c49d08dd81cfd5b1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 16:18:13 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 09 Jan 2025 11:18:13 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update test UnliftedNewtypesRunTypeRepPoly Message-ID: <677ff6c5f1869_30cb0810287c0924eb@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: dceda404 by Patrick at 2025-01-10T00:18:06+08:00 update test UnliftedNewtypesRunTypeRepPoly - - - - - 1 changed file: - testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs Changes: ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs ===================================== @@ -12,6 +12,7 @@ import GHC.Word (Word(W#)) import GHC.Exts (Int#,Word#) import GHC.Types +-- ensure newtype[instance] can be runtime-rep-polymorphic type N :: TYPE r -> TYPE r newtype N a = MkN a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dceda40499c9bef545ff6d8c59d52308e7632b6a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dceda40499c9bef545ff6d8c59d52308e7632b6a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 16:29:36 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 09 Jan 2025 11:29:36 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update test DataInstanceKindsDefaults Message-ID: <677ff970570fe_30cb0812e1cc89485d@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 481e4955 by Patrick at 2025-01-10T00:29:27+08:00 update test DataInstanceKindsDefaults - - - - - 1 changed file: - testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs Changes: ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -5,8 +5,12 @@ module DataInstanceKindsDefaults where import Data.Kind --- this test check if we defaults the kind of the data instance correctly --- error would be caught by the validity checker `checkNewDataCon` from `GHC.Tc.TyCl` +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. data family A :: k -> k newtype instance A a = MkA a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/481e4955e0a90847bc6ebfcc6f28cd01e6adc395 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/481e4955e0a90847bc6ebfcc6f28cd01e6adc395 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 17:19:25 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 09 Jan 2025 12:19:25 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] rts/printClosure: Print IPE information for thunks and functions Message-ID: <6780051d2968e_2012822275903778c@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 85b6d82c by Ben Gamari at 2025-01-09T12:19:18-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 1 changed file: - rts/Printer.c Changes: ===================================== rts/Printer.c ===================================== @@ -151,13 +151,20 @@ printClosure( const StgClosure *obj ) case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_0_2: case FUN_2_0: case FUN_STATIC: - debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); - printPtr((StgPtr)obj->header.info); + { + debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); + + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #if defined(PROFILING) - debugBelch(", %s", obj->header.prof.ccs->cc->label); + debugBelch(", %s", obj->header.prof.ccs->cc->label); #endif - printStdObjPayload(obj); - break; + printStdObjPayload(obj); + break; + } case PRIM: debugBelch("PRIM("); @@ -175,13 +182,19 @@ printClosure( const StgClosure *obj ) case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: case THUNK_STATIC: + { /* ToDo: will this work for THUNK_STATIC too? */ #if defined(PROFILING) printThunkObject((StgThunk *)obj,GET_PROF_DESC(info)); #else printThunkObject((StgThunk *)obj,"THUNK"); + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #endif break; + } case THUNK_SELECTOR: printStdObjHdr(obj, "THUNK_SELECTOR"); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85b6d82ccba34621feeaa6dd7565c9f0729222ba -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85b6d82ccba34621feeaa6dd7565c9f0729222ba You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 17:38:08 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 09 Jan 2025 12:38:08 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update note [Data family/instance return kinds] and [Defaulting result kind of... Message-ID: <6780098011909_24be952320d0780fe@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 8ef3c679 by Patrick at 2025-01-10T01:37:57+08:00 update note [Data family/instance return kinds] and [Defaulting result kind of newtype/data family instance] - - - - - 2 changed files: - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind + of an instance is then calculated by applying the data family tycon + to the patterns provided, as computed by the `tcInstInvisibleTyBinders + lhs_ty lhs_kind` in the tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky since it is guiding + instantiation (Note [Defaulting result kind of newtype/data family instance]). + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1011,7 +1011,7 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), -- , Note [Implementation of UnliftedDatatypes] - -- and Note [Defaulting kind of newtype/data family instance]. + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1037,12 +1037,11 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 -Note [Defaulting kind of newtype/data family instance] +Note [Defaulting result kind of newtype/data family instance] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to -default the result kind of a newtype instance to `Type` when -`-XUnliftedNewtypes` is not enabled. +default the result kind of a newtype instance to `Type`. Consider the following example: -- no UnliftedNewtypes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8ef3c67976e6900af54508606e16668314674ef2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8ef3c67976e6900af54508606e16668314674ef2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 17:45:03 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 09 Jan 2025 12:45:03 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Refine the note Message-ID: <67800b1f9d6d0_24be953b51b4796fc@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 39515181 by Patrick at 2025-01-10T01:44:55+08:00 Refine the note - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2229,9 +2229,9 @@ DF0 Where these kinds come from: with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind for newtypes/datatypes, otherwise it defaults to liftedTypeKind. This is checked or defaulted by the tc_kind_sig function within - tcDataFamInstHeader. Defaulting can be tricky since it is guiding - instantiation (Note [Defaulting result kind of newtype/data family instance]). - See also DF3, below. + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/39515181ddeca204f32724eacb04ac822fdf0153 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/39515181ddeca204f32724eacb04ac822fdf0153 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 17:59:23 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 09 Jan 2025 12:59:23 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add HsConFieldSpec Message-ID: <67800e7bab91_24be9565a2fc8347d@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 6013a6c3 by Sjoerd Visscher at 2025-01-09T18:59:15+01:00 Add HsConFieldSpec - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/printer/T18791.stderr - utils/check-exact/ExactPrint.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6013a6c3cb639f871d867d46f3f9ff9475a4b064 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6013a6c3cb639f871d867d46f3f9ff9475a4b064 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 18:13:13 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 09 Jan 2025 13:13:13 -0500 Subject: [Git][ghc/ghc][wip/T25576] 47 commits: Update GHCi :info type declaration printing (#24459) Message-ID: <678011b93b2f2_24be95839190852c4@gitlab.mail> Ben Gamari pushed to branch wip/T25576 at Glasgow Haskell Compiler / GHC Commits: 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 63d74f4d by Ben Gamari at 2025-01-09T13:13:01-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/upload.sh - .gitmodules - compiler/GHC/Builtin/Names.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/Unboxed.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Config/Linker.hs - compiler/GHC/Hs/Dump.hs - compiler/GHC/Hs/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e421ec3c8fc9688b3f7ee08c0d1baaf1cb7aa750...63d74f4d15ecaa8d711bd12fa64f77fce72b5f79 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e421ec3c8fc9688b3f7ee08c0d1baaf1cb7aa750...63d74f4d15ecaa8d711bd12fa64f77fce72b5f79 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 21:28:57 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 09 Jan 2025 16:28:57 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25334 Message-ID: <67803f99b3dd1_24be951ab4540940a5@gitlab.mail> Ben Gamari pushed new branch wip/T25334 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25334 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 22:29:54 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 09 Jan 2025 17:29:54 -0500 Subject: [Git][ghc/ghc][master] Add flags for switching off speculative evaluation. Message-ID: <67804de25cbc0_19fd9252ce5c1213@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 12 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/core-to-stg/T25284/A.hs - + testsuite/tests/core-to-stg/T25284/B.hs - + testsuite/tests/core-to-stg/T25284/Cls.hs - + testsuite/tests/core-to-stg/T25284/Main.hs - + testsuite/tests/core-to-stg/T25284/T25284.stdout - + testsuite/tests/core-to-stg/T25284/all.T Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2051,6 +2051,16 @@ conceptually. See also Note [Floats and FloatDecision] for how we maintain whole groups of floats and how far they go. +Note [Controlling Speculative Evaluation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Most of the time, speculative evaluation has a positive effect on performance, +but we have found a case where speculative evaluation of dictionary functions +leads to a performance regression #25284. + +Therefore we have some flags to control it. See the optimization section in +the User's Guide for the description of these flags and when to use them. + Note [Floats and FloatDecision] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We have a special datatype `Floats` for modelling a telescope of `FloatingBind` @@ -2275,7 +2285,15 @@ mkNonRecFloat env lev bndr rhs } is_hnf = exprIsHNF rhs - ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs + cfg = cpe_config env + + ok_for_spec = exprOkForSpecEval call_ok_for_spec rhs + -- See Note [Controlling Speculative Evaluation] + call_ok_for_spec x + | is_rec_call x = False + | not (cp_specEval cfg) = False + | not (cp_specEvalDFun cfg) && isDFunId x = False + | otherwise = True is_rec_call = (`elemUnVarSet` cpe_rec_ids env) -- See Note [Pin evaluatedness on floats] @@ -2517,6 +2535,11 @@ data CorePrepConfig = CorePrepConfig -- ^ Configuration for arity analysis ('exprEtaExpandArity'). -- See Note [Eta expansion of arguments in CorePrep] -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead + , cp_specEval :: !Bool + -- ^ Whether to perform speculative evaluation + -- See Note [Controlling Speculative Evaluation] + , cp_specEvalDFun :: !Bool + -- ^ Whether to perform speculative evaluation on DFuns } data CorePrepEnv ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -24,6 +24,8 @@ initCorePrepConfig hsc_env = do , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags then Just (initArityOpts dflags) else Nothing + , cp_specEval = gopt Opt_SpecEval dflags + , cp_specEvalDFun = gopt Opt_SpecEvalDictFun dflags } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1287,6 +1287,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] -- RegsGraph suffers performance regression. See #7679 -- , ([2], Opt_StaticArgumentTransformation) -- Static Argument Transformation needs investigation. See #9374 + , ([0,1,2], Opt_SpecEval) + , ([0,1,2], Opt_SpecEvalDictFun) ] ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -674,6 +674,9 @@ data GeneralFlag | Opt_NumConstantFolding | Opt_CoreConstantFolding | Opt_FastPAPCalls -- #6084 + | Opt_SpecEval + | Opt_SpecEvalDictFun -- See Note [Controlling Speculative Evaluation] + -- Inference flags | Opt_DoTagInferenceChecks @@ -912,6 +915,8 @@ optimisationFlags = EnumSet.fromList , Opt_WorkerWrapper , Opt_WorkerWrapperUnlift , Opt_SolveConstantDicts + , Opt_SpecEval + , Opt_SpecEvalDictFun ] -- | The set of flags which affect code generation and can change a program's ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2544,6 +2544,8 @@ fFlagsDeps = [ flagSpec "num-constant-folding" Opt_NumConstantFolding, flagSpec "core-constant-folding" Opt_CoreConstantFolding, flagSpec "fast-pap-calls" Opt_FastPAPCalls, + flagSpec "spec-eval" Opt_SpecEval, + flagSpec "spec-eval-dictfun" Opt_SpecEvalDictFun, flagSpec "cmm-control-flow" Opt_CmmControlFlow, flagSpec "show-warning-groups" Opt_ShowWarnGroups, flagSpec "hide-source-paths" Opt_HideSourcePaths, ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -405,6 +405,55 @@ as such you shouldn't need to set any of them explicitly. A flag intermediate language, where it is able to common up some subexpressions that differ in their types, but not their representation. +.. ghc-flag:: -fspec-eval + :shortdesc: Enables speculative evaluation. + :type: dynamic + :category: + :reverse: -fno-spec-eval + + :default: on + :since: 9.14.1 + + Enables speculative evaluation which usually results in fewer allocations. + Enabling speculative evaluation should not cause performance regressions. + If you encounter any, please open a ticket. + + Note that disabling this flag will switch off speculative evaluation + completely, causing :ghc-flag:`-fspec-eval-dictfun` to have + no effect. + +.. ghc-flag:: -fspec-eval-dictfun + :shortdesc: Enables speculative evaluation of dictionary functions. + :type: dynamic + :category: + :reverse: -fno-spec-eval-dictfun + + :default: on + :since: 9.14.1 + + Enables speculative (strict) evaluation of dictionary functions. + + This is best explained with an example :: + + instance C a => D a where ... + + g :: D a => a -> Int + g x = ... + + f :: C a => a -> Int + f x = g x + + Function `f` has to pass a `D a` dictionary to `g`, and uses a dictionary + function `C a => D a` to compute it. If speculative evaluation for + dictionary functions is enabled, this dictionary is computed + strictly. + + Speculative evalation of dictionary functions can lead to slightly better + performance, because a thunk is avoided. However, it results in unnecessary + computation and allocation if the dictionary goes unused. This causes + a significant increase in allocation if the dictionary is large. + See (:ghc-ticket:`25284`). + .. ghc-flag:: -fdicts-cheap :shortdesc: Make dictionary-valued expressions seem cheap to the optimiser. :type: dynamic ===================================== testsuite/tests/core-to-stg/T25284/A.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fspec-eval-dictfun #-} +module A (testX) where + +import qualified Cls + +-- this creates the big dictionary strictly because of speculative evaluation +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/B.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fno-spec-eval-dictfun #-} +module B (testX) where + +import qualified Cls + +-- this creates the big dictionary lazily +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/Cls.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE UndecidableInstances #-} + +module Cls where + +class HasConst a where constVal :: a + +instance Cls.HasConst Word where constVal = 123 + +instance Cls.HasConst Int where constVal = 456 + +-- this class has a big dictionary +class HasConst10 a where + constA :: a + constInt1 :: a -> Int + constInt1 _ = 1 + constInt2 :: a -> Int + constInt2 _ = 2 + constInt3 :: a -> Int + constInt3 _ = 3 + constInt4 :: a -> Int + constInt4 _ = 4 + constInt5 :: a -> Int + constInt5 _ = 5 + constInt6 :: a -> Int + constInt6 _ = 6 + constInt7 :: a -> Int + constInt7 _ = 7 + constInt8 :: a -> Int + constInt8 _ = 8 + constInt9 :: a -> Int + constInt9 _ = 9 + +instance HasConst a => HasConst10 a where + constA = constVal + +-- this doesn't use the big dictionary most of the time +printConst :: forall a. (Show a, HasConst10 a) + => a -> Int -> IO () +printConst x 5000 = print @a constA >> print (constInt8 x) +printConst _ _ = pure () ===================================== testsuite/tests/core-to-stg/T25284/Main.hs ===================================== @@ -0,0 +1,57 @@ +{- + + This tests that speculative evaluation for dictionary functions works as + expected, with a large dictionary that goes unused. + + - Module A: dictfun speculative evaluation enabled + - Module B: dictfun speculative evaluation disabled + + Speculative evaluation causes the unused large dictionary to be allocated + strictly in module A, so we expect more allocations than in module B. + + -} +module Main where + +import qualified A +import qualified B +import qualified Cls + +import Data.Word +import System.Mem (performGC) +import GHC.Stats +import Control.Monad + +{-# NOINLINE getAllocated #-} +getAllocated :: IO Word64 +getAllocated = do + performGC + allocated_bytes <$> getRTSStats + +main :: IO () +main = do + -- warm up (just in case) + _ <- testMain A.testX + _ <- testMain B.testX + + -- for real + a_alloc <- testMain A.testX + b_alloc <- testMain B.testX + + -- expect B to allocate less than A + let alloc_ratio :: Double + alloc_ratio = fromIntegral b_alloc / fromIntegral a_alloc + putStrLn ("expected alloc: " ++ show (alloc_ratio < 0.7)) + +iter :: (Int -> IO ()) -> Int -> Int -> IO () +iter m !i !j + | i < j = m i >> iter m (i+1) j + | otherwise = pure () + +{-# NOINLINE testMain #-} +testMain :: (forall b. (Show b, Cls.HasConst b) => b -> Int -> IO ()) + -> IO Word64 +testMain f = do + alloc0 <- getAllocated + iter (\i -> f (0::Int) i >> f (0::Word) i) 1 100000 + alloc1 <- getAllocated + pure (alloc1 - alloc0) ===================================== testsuite/tests/core-to-stg/T25284/T25284.stdout ===================================== @@ -0,0 +1,17 @@ +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +expected alloc: True ===================================== testsuite/tests/core-to-stg/T25284/all.T ===================================== @@ -0,0 +1,6 @@ +test('T25284', + [js_skip, # allocation counters aren't available on the JS backend + extra_files(['Main.hs', 'A.hs', 'B.hs', 'Cls.hs']), + extra_run_opts('+RTS -T -RTS')], + multimod_compile_and_run, + ['Main', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2309975247543a4f77009ea5c3c7a8ebe06dc60b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2309975247543a4f77009ea5c3c7a8ebe06dc60b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 9 22:30:54 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 09 Jan 2025 17:30:54 -0500 Subject: [Git][ghc/ghc][master] rts/printClosure: Print IPE information for thunks and functions Message-ID: <67804e1e1c049_19fd92a46eb0147cd@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 1 changed file: - rts/Printer.c Changes: ===================================== rts/Printer.c ===================================== @@ -151,13 +151,20 @@ printClosure( const StgClosure *obj ) case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_0_2: case FUN_2_0: case FUN_STATIC: - debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); - printPtr((StgPtr)obj->header.info); + { + debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); + + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #if defined(PROFILING) - debugBelch(", %s", obj->header.prof.ccs->cc->label); + debugBelch(", %s", obj->header.prof.ccs->cc->label); #endif - printStdObjPayload(obj); - break; + printStdObjPayload(obj); + break; + } case PRIM: debugBelch("PRIM("); @@ -175,13 +182,19 @@ printClosure( const StgClosure *obj ) case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: case THUNK_STATIC: + { /* ToDo: will this work for THUNK_STATIC too? */ #if defined(PROFILING) printThunkObject((StgThunk *)obj,GET_PROF_DESC(info)); #else printThunkObject((StgThunk *)obj,"THUNK"); + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #endif break; + } case THUNK_SELECTOR: printStdObjHdr(obj, "THUNK_SELECTOR"); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0161badc62318cd4476ac4c9ba128b4e3bab54bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0161badc62318cd4476ac4c9ba128b4e3bab54bc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 04:36:02 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 09 Jan 2025 23:36:02 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] update note [Data family/instance return kinds] Message-ID: <6780a3b227392_130e1f920c0c852eb@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: d7fa624d by Patrick at 2025-01-10T12:35:53+08:00 update note [Data family/instance return kinds] - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -2220,10 +2220,10 @@ DF0 Where these kinds come from: Instances: There are potentially *two* return kinds: * Master kind: - The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the `tcInstInvisibleTyBinders - lhs_ty lhs_kind` in the tcDataFamInstHeader. + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. * Instance kind: The kind specified by the user in GADT syntax. If H98 syntax is used, with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7fa624dc5cdc4a6e20838943f84bbb0301e7a74 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7fa624dc5cdc4a6e20838943f84bbb0301e7a74 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 07:35:31 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 10 Jan 2025 02:35:31 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: rts/printClosure: Print IPE information for thunks and functions Message-ID: <6780cdc3739f7_130e1f1df7be4960d8@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - b5175f46 by Rodrigo Mesquita at 2025-01-10T02:35:10-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - d67ed785 by Ben Gamari at 2025-01-10T02:35:10-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 3 changed files: - docs/users_guide/phases.rst - rts/Printer.c - utils/dump-decls/Main.hs Changes: ===================================== docs/users_guide/phases.rst ===================================== @@ -25,11 +25,12 @@ given compilation phase: Use ⟨cmd⟩ as the literate pre-processor. .. ghc-flag:: -pgmP ⟨cmd⟩ - :shortdesc: Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only) + :shortdesc: Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only) :type: dynamic :category: phase-programs - Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only). + Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only). + Note that the Haskell C pre-processor only pre-processes Haskell files. .. ghc-flag:: -pgmJSP ⟨cmd⟩ :shortdesc: Use ⟨cmd⟩ as the JavaScript C pre-processor (only for javascript-backend) @@ -177,7 +178,11 @@ the following flags: :type: dynamic :category: phase-options - Pass ⟨option⟩ to CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Pass ⟨option⟩ to the Haskell CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Note that the Haskell pre-processor options only apply to pre-processing + invocations on Haskell files, and, e.g., to use different options to + pre-process Javascript or Cmm, one should use ``-optJSP``, or + ``-optCmmP``, respectively). .. ghc-flag:: -optJSP ⟨option⟩ :shortdesc: pass ⟨option⟩ to JavaScript C pre-processor (only for javascript-backend) ===================================== rts/Printer.c ===================================== @@ -151,13 +151,20 @@ printClosure( const StgClosure *obj ) case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_0_2: case FUN_2_0: case FUN_STATIC: - debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); - printPtr((StgPtr)obj->header.info); + { + debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); + + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #if defined(PROFILING) - debugBelch(", %s", obj->header.prof.ccs->cc->label); + debugBelch(", %s", obj->header.prof.ccs->cc->label); #endif - printStdObjPayload(obj); - break; + printStdObjPayload(obj); + break; + } case PRIM: debugBelch("PRIM("); @@ -175,13 +182,19 @@ printClosure( const StgClosure *obj ) case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: case THUNK_STATIC: + { /* ToDo: will this work for THUNK_STATIC too? */ #if defined(PROFILING) printThunkObject((StgThunk *)obj,GET_PROF_DESC(info)); #else printThunkObject((StgThunk *)obj,"THUNK"); + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #endif break; + } case THUNK_SELECTOR: printStdObjHdr(obj, "THUNK_SELECTOR"); ===================================== utils/dump-decls/Main.hs ===================================== @@ -38,6 +38,7 @@ run root pkg_nm = runGhc (Just root) $ do , "-dppr-cols=1000" , "-fprint-explicit-runtime-reps" , "-fprint-explicit-foralls" + , "-fsuppress-unit-ids" ] dflags <- do dflags <- getSessionDynFlags View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85b6d82ccba34621feeaa6dd7565c9f0729222ba...d67ed785230b22af25c05983cd61d51bf4920806 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85b6d82ccba34621feeaa6dd7565c9f0729222ba...d67ed785230b22af25c05983cd61d51bf4920806 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 15:15:09 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 10 Jan 2025 10:15:09 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] format Message-ID: <6781397de9d28_1a7bc05e417727@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 1c92e447 by Patrick at 2025-01-10T16:18:58+08:00 format - - - - - 1 changed file: - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -1010,7 +1010,7 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- , Note [Implementation of UnliftedDatatypes] + -- Note [Implementation of UnliftedDatatypes] -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c92e4474e082185cf41bf2fb36c02545ff98376 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c92e4474e082185cf41bf2fb36c02545ff98376 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 15:15:26 2025 From: gitlab at gitlab.haskell.org (Serge S. Gulin (@gulin.serge)) Date: Fri, 10 Jan 2025 10:15:26 -0500 Subject: [Git][ghc/ghc][wip/llvm-debug-info] 5 commits: Add flags for switching off speculative evaluation. Message-ID: <6781398e9dac8_1a7bc069818484@gitlab.mail> Serge S. Gulin pushed to branch wip/llvm-debug-info at Glasgow Haskell Compiler / GHC Commits: 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 7b7239e1 by Ben Gamari at 2025-01-10T12:21:49+03:00 [WIP] llvmGen: Produce debug information metadata for functions Summary: It turns out that providing debug information in LLVM is relatively straightforward. At this moment this only provides debug information with procedure-level granularity. Test Plan: Validate, look at DWARF output, try poking around in GDB Reviewers: scpmw, simonmar, austin Subscribers: spacekitteh, cocreature, thomie Differential Revision: https://phabricator.haskell.org/D2343 - - - - - 51f12e32 by Ben Gamari at 2025-01-10T12:21:49+03:00 Fix distinction - - - - - 62eab54b by Serge S. Gulin at 2025-01-10T12:21:49+03:00 Code cleanup after rebase - - - - - 22 changed files: - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Llvm.hs - compiler/GHC/Llvm/MetaData.hs - compiler/GHC/Llvm/Ppr.hs - compiler/GHC/Llvm/Syntax.hs - docs/users_guide/using-optimisation.rst - rts/Printer.c - + testsuite/tests/core-to-stg/T25284/A.hs - + testsuite/tests/core-to-stg/T25284/B.hs - + testsuite/tests/core-to-stg/T25284/Cls.hs - + testsuite/tests/core-to-stg/T25284/Main.hs - + testsuite/tests/core-to-stg/T25284/T25284.stdout - + testsuite/tests/core-to-stg/T25284/all.T Changes: ===================================== compiler/GHC/CmmToLlvm.hs ===================================== @@ -26,13 +26,17 @@ import GHC.CmmToLlvm.Version import GHC.StgToCmm.CgUtils ( fixStgRegisters, CgStream ) import GHC.Cmm import GHC.Cmm.Dataflow.Label +import GHC.Cmm.DebugBlock import GHC.Types.Unique.DSM import GHC.Utils.BufHandle import GHC.Driver.DynFlags +import GHC.Data.FastString import GHC.Platform ( platformArch, Arch(..) ) + +import GHC.Unit.Module.Location + import GHC.Utils.Error -import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Logger @@ -45,12 +49,12 @@ import System.IO -- ----------------------------------------------------------------------------- -- | Top-level of the LLVM Code generator -- -llvmCodeGen :: Logger -> LlvmCgConfig -> Handle +llvmCodeGen :: Logger -> LlvmCgConfig -> DynFlags -> ModLocation -> Handle -> DUniqSupply -- ^ The deterministic uniq supply to run the CgStream. -- See Note [Deterministic Uniques in the CG] -> CgStream RawCmmGroup a -> IO a -llvmCodeGen logger cfg h dus cmm_stream +llvmCodeGen logger cfg dflags location h dus cmm_stream = withTiming logger (text "LLVM CodeGen") (const ()) $ do bufh <- newBufHandle h @@ -87,22 +91,22 @@ llvmCodeGen logger cfg h dus cmm_stream -- run code generation (a, _) <- runLlvm logger cfg llvm_ver bufh dus $ - llvmCodeGen' cfg cmm_stream + llvmCodeGen' dflags location cfg cmm_stream bFlush bufh return a -llvmCodeGen' :: LlvmCgConfig +llvmCodeGen' :: DynFlags -> ModLocation -> LlvmCgConfig -> CgStream RawCmmGroup a -> LlvmM a -llvmCodeGen' cfg cmm_stream +llvmCodeGen' dflags location cfg cmm_stream = do -- Preamble renderLlvm (llvmHeader cfg) (llvmHeader cfg) ghcInternalFunctions cmmMetaLlvmPrelude -- Procedures - a <- Stream.consume cmm_stream (GHC.CmmToLlvm.Base.liftUDSMT) (llvmGroupLlvmGens) + a <- Stream.consume cmm_stream (GHC.CmmToLlvm.Base.liftUDSMT) (llvmGroupLlvmGens dflags location) -- Declare aliases for forward references decls <- generateExternDecls @@ -112,8 +116,53 @@ llvmCodeGen' cfg cmm_stream -- Postamble cmmUsedLlvmGens + -- Debug metadata + debugInfoGen dflags location + return a +debugInfoGen :: DynFlags -> ModLocation -> LlvmM () +debugInfoGen dflags location + = do fileMeta <- getMetaUniqueId + subprogramsMeta <- getMetaUniqueId + cuMeta <- getMetaUniqueId + dwarfVersionMeta <- getMetaUniqueId + debugInfoVersionMeta <- getMetaUniqueId + cfg <- getConfig + metaSubs <- getMetaDecls + renderLlvm (ppLlvmMetas cfg metaSubs) (ppLlvmMetas cfg metaSubs) + subprograms <- getSubprograms + let metaHeader = + [ MetaUnnamed fileMeta NotDistinct $ MetaDIFile + { difFilename = fsLit $ fromMaybe "TODO" (ml_hs_file location) + , difDirectory = fsLit "" + } + , MetaUnnamed cuMeta Distinct $ MetaDICompileUnit + { dicuLanguage = fsLit "DW_LANG_Haskell" + , dicuFile = fileMeta + , dicuProducer = fsLit "ghc" + , dicuIsOptimized = llvmOptLevel dflags > 0 + , dicuSubprograms = MetaStruct $ map MetaNode subprograms + } + , MetaNamed (fsLit "llvm.dbg.cu") NotDistinct [ cuMeta ] + , MetaUnnamed subprogramsMeta NotDistinct $ MetaStruct [] + , MetaNamed (fsLit "llvm.module.flags") NotDistinct + [ dwarfVersionMeta + , debugInfoVersionMeta + ] + , MetaUnnamed dwarfVersionMeta NotDistinct $ MetaStruct + [ MetaVar $ LMLitVar $ LMIntLit 2 i32 + , MetaStr $ fsLit "Dwarf Version" + , MetaVar $ LMLitVar $ LMIntLit 4 i32 + ] + , MetaUnnamed debugInfoVersionMeta NotDistinct $ MetaStruct + [ MetaVar $ LMLitVar $ LMIntLit 2 i32 + , MetaStr $ fsLit "Debug Info Version" + , MetaVar $ LMLitVar $ LMIntLit 3 i32 + ] + ] + renderLlvm (ppLlvmMetas cfg metaHeader) (ppLlvmMetas cfg metaHeader) + llvmHeader :: IsDoc doc => LlvmCgConfig -> doc llvmHeader cfg = let target = llvmCgLlvmTarget cfg @@ -133,8 +182,12 @@ llvmHeader cfg = {-# SPECIALIZE llvmHeader :: LlvmCgConfig -> SDoc #-} {-# SPECIALIZE llvmHeader :: LlvmCgConfig -> HDoc #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -llvmGroupLlvmGens :: RawCmmGroup -> LlvmM () -llvmGroupLlvmGens cmm = do +llvmGroupLlvmGens :: DynFlags -> ModLocation -> RawCmmGroup -> LlvmM () +llvmGroupLlvmGens dflags location cmm = do + let debug_map :: LabelMap DebugBlock + debug_map + | (debugLevel dflags) >= 1 = debugToMap $ cmmDebugGen location cmm + | otherwise = mapEmpty -- Insert functions into map, collect data let split (CmmData s d' ) = return $ Just (s, d') @@ -151,7 +204,7 @@ llvmGroupLlvmGens cmm = do {-# SCC "llvm_datas_gen" #-} cmmDataLlvmGens cdata {-# SCC "llvm_procs_gen" #-} - mapM_ cmmLlvmGen cmm + mapM_ (cmmLlvmGen debug_map) cmm -- ----------------------------------------------------------------------------- -- | Do LLVM code generation on all these Cmms data sections. @@ -174,8 +227,8 @@ cmmDataLlvmGens statics (pprLlvmData cfg (concat gss', concat tss)) -- | Complete LLVM code generation phase for a single top-level chunk of Cmm. -cmmLlvmGen ::RawCmmDecl -> LlvmM () -cmmLlvmGen cmm at CmmProc{} = do +cmmLlvmGen :: LabelMap DebugBlock -> RawCmmDecl -> LlvmM () +cmmLlvmGen debug_map cmm at CmmProc{} = do -- rewrite assignments to global regs platform <- getPlatform @@ -190,11 +243,11 @@ cmmLlvmGen cmm at CmmProc{} = do -- pretty print - print as we go, since we produce HDocs, we know -- no nesting state needs to be maintained for the SDocs. forM_ llvmBC (\decl -> do - (hdoc, sdoc) <- pprLlvmCmmDecl decl + (hdoc, sdoc) <- pprLlvmCmmDecl debug_map decl renderLlvm (hdoc $$ empty) (sdoc $$ empty) ) -cmmLlvmGen _ = return () +cmmLlvmGen _ _ = return () -- ----------------------------------------------------------------------------- -- | Generate meta data nodes @@ -208,7 +261,7 @@ cmmMetaLlvmPrelude = do setUniqMeta uniq tbaaId parentId <- maybe (return Nothing) getUniqMeta parent -- Build definition - return $ MetaUnnamed tbaaId $ MetaStruct $ + return $ MetaUnnamed tbaaId NotDistinct $ MetaStruct $ case parentId of Just p -> [ MetaStr name, MetaNode p ] -- As of LLVM 4.0, a node without parents should be rendered as @@ -233,18 +286,19 @@ cmmMetaLlvmPrelude = do renderLlvm (ppLlvmMetas cfg metas) (ppLlvmMetas cfg metas) -mkNamedMeta :: LMString -> [MetaExpr] -> LlvmM [MetaDecl] -mkNamedMeta name exprs = do - (ids, decls) <- unzip <$> mapM f exprs - return $ decls ++ [MetaNamed name ids] where - f expr = do - i <- getMetaUniqueId - return (i, MetaUnnamed i expr) - -mkModuleFlagsMeta :: [ModuleFlag] -> LlvmM [MetaDecl] -mkModuleFlagsMeta = - mkNamedMeta "llvm.module.flags" . map moduleFlagToMetaExpr + mkModuleFlagsMeta :: [ModuleFlag] -> LlvmM [MetaDecl] + mkModuleFlagsMeta = + mkNamedMeta "llvm.module.flags" . map moduleFlagToMetaExpr + + mkNamedMeta :: LMString -> [MetaExpr] -> LlvmM [MetaDecl] + mkNamedMeta name exprs = do + (ids, decls) <- unzip <$> mapM f exprs + return $ decls ++ [MetaNamed name NotDistinct ids] + where + f expr = do + i <- getMetaUniqueId + return (i, MetaUnnamed i NotDistinct expr) mkStackAlignmentMeta :: Integer -> ModuleFlag mkStackAlignmentMeta alignment = ===================================== compiler/GHC/CmmToLlvm/Base.hs ===================================== @@ -20,6 +20,7 @@ module GHC.CmmToLlvm.Base ( markStackReg, checkStackReg, funLookup, funInsert, getLlvmVer, dumpIfSetLlvm, renderLlvm, markUsedVar, getUsedVars, + addMetaDecl, getMetaDecls, addSubprogram, getSubprograms, ghcInternalFunctions, getPlatform, getConfig, getMetaUniqueId, @@ -68,12 +69,13 @@ import Data.List (find, isPrefixOf) import qualified Data.List.NonEmpty as NE import Data.Ord (comparing) import qualified Control.Monad.IO.Class as IO +import GHC.Cmm.Dataflow.Label (Label) -- ---------------------------------------------------------------------------- -- * Some Data Types -- -type LlvmCmmDecl = GenCmmDecl [LlvmData] (Maybe RawCmmStatics) (ListGraph LlvmStatement) +type LlvmCmmDecl = GenCmmDecl [LlvmData] (Label, Maybe RawCmmStatics) (ListGraph LlvmStatement) type LlvmBasicBlock = GenBasicBlock LlvmStatement -- | Global registers live on proc entry @@ -287,6 +289,9 @@ data LlvmEnv = LlvmEnv , envFunMap :: LlvmEnvMap -- ^ Global functions so far, with type , envAliases :: UniqSet LMString -- ^ Globals that we had to alias, see [Llvm Forward References] , envUsedVars :: [LlvmVar] -- ^ Pointers to be added to llvm.used (see @cmmUsedLlvmGens@) + , envMetaDecls :: [MetaDecl] -- ^ Metadata declarations to be included in final output + , envSubprograms :: [MetaId] -- ^ 'MetaId's of the @DISubprogram@ metadata + -- nodes defined in this @DICompileUnit at . -- the following get cleared for every function (see @withClearVars@) , envVarMap :: LlvmEnvMap -- ^ Local variables so far, with type @@ -339,6 +344,8 @@ runLlvm logger cfg ver out us m = do , envVarMap = emptyUFM , envStackRegs = [] , envUsedVars = [] + , envMetaDecls = [] + , envSubprograms = [] , envAliases = emptyUniqSet , envVersion = ver , envConfig = cfg @@ -430,6 +437,24 @@ setUniqMeta f m = modifyEnv $ \env -> env { envUniqMeta = addToUFM (envUniqMeta getUniqMeta :: Unique -> LlvmM (Maybe MetaId) getUniqMeta s = getEnv (flip lookupUFM s . envUniqMeta) +-- | Add a @DISubprogram@ metadata declaration to the current compilation unit. +addSubprogram :: MetaId -> MetaExpr -> LlvmM () +addSubprogram metaId metaExpr = do + modifyEnv $ \env -> env { envSubprograms = metaId : envSubprograms env } + addMetaDecl (MetaUnnamed metaId Distinct metaExpr) + +getSubprograms :: LlvmM [MetaId] +getSubprograms = LlvmM $ \env -> return (envSubprograms env, env { envSubprograms = [] }) + +-- | Add a metadata declaration to the output. +addMetaDecl :: MetaDecl -> LlvmM () +addMetaDecl x = modifyEnv $ \env -> env { envMetaDecls = x : envMetaDecls env } + +-- | Retreive the list of metadata declarations found in the +-- current compilation unit. +getMetaDecls :: LlvmM [MetaDecl] +getMetaDecls = LlvmM $ \env -> return (envMetaDecls env, env { envMetaDecls = [] }) + -- ---------------------------------------------------------------------------- -- * Internal functions -- ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -60,7 +60,7 @@ genLlvmProc (CmmProc infos lbl live graph) = do (lmblocks, lmdata) <- basicBlocksCodeGen live blocks let info = mapLookup (g_entry graph) infos - proc = CmmProc info lbl live (ListGraph lmblocks) + proc = CmmProc (g_entry graph, info) lbl live (ListGraph lmblocks) return (proc:lmdata) genLlvmProc _ = panic "genLlvmProc: case that shouldn't reach here!" @@ -76,9 +76,9 @@ newtype UnreachableBlockId = UnreachableBlockId BlockId -- | Generate code for a list of blocks that make up a complete -- procedure. The first block in the list is expected to be the entry --- point. +-- point and will get the prologue. basicBlocksCodeGen :: LiveGlobalRegUses -> [CmmBlock] - -> LlvmM ([LlvmBasicBlock], [LlvmCmmDecl]) + -> LlvmM ([LlvmBasicBlock], [LlvmCmmDecl]) basicBlocksCodeGen _ [] = panic "no entry block!" basicBlocksCodeGen live cmmBlocks = do -- Emit the prologue ===================================== compiler/GHC/CmmToLlvm/Ppr.hs ===================================== @@ -14,12 +14,18 @@ import GHC.CmmToLlvm.Base import GHC.CmmToLlvm.Data import GHC.CmmToLlvm.Config -import GHC.Cmm.CLabel import GHC.Cmm +import GHC.Cmm.CLabel +import GHC.Cmm.Dataflow.Label ( mapLookup, LabelMap ) +import GHC.Cmm.DebugBlock import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Types.Unique +import GHC.Types.SrcLoc +import GHC.Types.Tickish ( GenTickish(SourceNote) ) + +import Data.Maybe ( maybeToList ) -- ---------------------------------------------------------------------------- -- * Top level @@ -43,13 +49,13 @@ pprLlvmData cfg (globals, types) = -- The HDoc we return is used to produce the final LLVM file, with the -- SDoc being returned alongside for use when @Opt_D_dump_llvm@ is set -- as we can't (currently) dump HDocs. -pprLlvmCmmDecl :: LlvmCmmDecl -> LlvmM (HDoc, SDoc) -pprLlvmCmmDecl (CmmData _ lmdata) = do +pprLlvmCmmDecl :: LabelMap DebugBlock -> LlvmCmmDecl -> LlvmM (HDoc, SDoc) +pprLlvmCmmDecl _ (CmmData _ lmdata) = do opts <- getConfig return ( vcat $ map (pprLlvmData opts) lmdata , vcat $ map (pprLlvmData opts) lmdata) -pprLlvmCmmDecl (CmmProc mb_info entry_lbl live (ListGraph blks)) +pprLlvmCmmDecl debug_map (CmmProc (label, mb_info) entry_lbl live (ListGraph blks)) = do let lbl = case mb_info of Nothing -> entry_lbl Just (CmmStaticsRaw info_lbl _) -> info_lbl @@ -74,9 +80,42 @@ pprLlvmCmmDecl (CmmProc mb_info entry_lbl live (ListGraph blks)) let infoTy = LMStruct $ map getStatType infoStatics return $ Just $ LMStaticStruc infoStatics infoTy + -- generate debug information metadata + subprogAnnot <- + case mapLookup label debug_map >>= dblSourceTick of + Just (SourceNote span name) -> do + let disName = getLexicalFastString name + let defName = llvmDefLabel disName + subprogMeta <- getMetaUniqueId + fileMeta <- getMetaUniqueId + typeMeta <- getMetaUniqueId + let fileDef = MetaUnnamed fileMeta NotDistinct + $ MetaDIFile { difFilename = srcSpanFile span + , difDirectory = fsLit "TODO" + } + typeMetaDef = + MetaUnnamed typeMeta NotDistinct + $ MetaDISubroutineType [MetaVar $ LMLitVar $ LMNullLit i1] + subprog = + MetaDISubprogram { disName = disName + , disLinkageName = defName + , disScope = fileMeta + , disFile = fileMeta + , disLine = srcSpanStartLine span + , disType = typeMeta + , disIsDefinition = True + } + addMetaDecl fileDef + addMetaDecl typeMetaDef + addSubprogram subprogMeta subprog + return $ Just $ MetaAnnot (fsLit "dbg") (MetaNode subprogMeta) + _ -> return Nothing + + let funcMetas = maybeToList subprogAnnot + let fun = LlvmFunction funDec funArgs llvmStdFunAttrs funSect - prefix lmblocks + prefix funcMetas lmblocks name = decName $ funcDecl fun defName = llvmDefLabel name funcDecl' = (funcDecl fun) { decName = defName } ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2051,6 +2051,16 @@ conceptually. See also Note [Floats and FloatDecision] for how we maintain whole groups of floats and how far they go. +Note [Controlling Speculative Evaluation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Most of the time, speculative evaluation has a positive effect on performance, +but we have found a case where speculative evaluation of dictionary functions +leads to a performance regression #25284. + +Therefore we have some flags to control it. See the optimization section in +the User's Guide for the description of these flags and when to use them. + Note [Floats and FloatDecision] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We have a special datatype `Floats` for modelling a telescope of `FloatingBind` @@ -2275,7 +2285,15 @@ mkNonRecFloat env lev bndr rhs } is_hnf = exprIsHNF rhs - ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs + cfg = cpe_config env + + ok_for_spec = exprOkForSpecEval call_ok_for_spec rhs + -- See Note [Controlling Speculative Evaluation] + call_ok_for_spec x + | is_rec_call x = False + | not (cp_specEval cfg) = False + | not (cp_specEvalDFun cfg) && isDFunId x = False + | otherwise = True is_rec_call = (`elemUnVarSet` cpe_rec_ids env) -- See Note [Pin evaluatedness on floats] @@ -2517,6 +2535,11 @@ data CorePrepConfig = CorePrepConfig -- ^ Configuration for arity analysis ('exprEtaExpandArity'). -- See Note [Eta expansion of arguments in CorePrep] -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead + , cp_specEval :: !Bool + -- ^ Whether to perform speculative evaluation + -- See Note [Controlling Speculative Evaluation] + , cp_specEvalDFun :: !Bool + -- ^ Whether to perform speculative evaluation on DFuns } data CorePrepEnv ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -131,7 +131,7 @@ codeOutput logger tmpfs llvm_config dflags unit_state this_mod filenm location g NcgCodeOutput -> outputAsm logger dflags this_mod location filenm dus1 final_stream ViaCCodeOutput -> outputC logger dflags filenm dus1 final_stream pkg_deps - LlvmCodeOutput -> outputLlvm logger llvm_config dflags filenm dus1 final_stream + LlvmCodeOutput -> outputLlvm logger llvm_config dflags location filenm dus1 final_stream JSCodeOutput -> outputJS logger llvm_config dflags filenm final_stream ; stubs_exist <- outputForeignStubs logger tmpfs dflags unit_state this_mod location stubs ; return (filenm, stubs_exist, foreign_fps, a) @@ -224,15 +224,15 @@ outputAsm logger dflags this_mod location filenm dus cmm_stream = do ************************************************************************ -} -outputLlvm :: Logger -> LlvmConfigCache -> DynFlags -> FilePath +outputLlvm :: Logger -> LlvmConfigCache -> DynFlags -> ModLocation -> FilePath -> DUniqSupply -- ^ The deterministic uniq supply to run the CgStream -- See Note [Deterministic Uniques in the CG] -> CgStream RawCmmGroup a -> IO a -outputLlvm logger llvm_config dflags filenm dus cmm_stream = do +outputLlvm logger llvm_config dflags location filenm dus cmm_stream = do lcg_config <- initLlvmCgConfig logger llvm_config dflags {-# SCC "llvm_output" #-} doOutput filenm $ \f -> {-# SCC "llvm_CodeGen" #-} - llvmCodeGen logger lcg_config f dus cmm_stream + llvmCodeGen logger lcg_config dflags location f dus cmm_stream {- ************************************************************************ ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -24,6 +24,8 @@ initCorePrepConfig hsc_env = do , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags then Just (initArityOpts dflags) else Nothing + , cp_specEval = gopt Opt_SpecEval dflags + , cp_specEvalDFun = gopt Opt_SpecEvalDictFun dflags } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1287,6 +1287,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] -- RegsGraph suffers performance regression. See #7679 -- , ([2], Opt_StaticArgumentTransformation) -- Static Argument Transformation needs investigation. See #9374 + , ([0,1,2], Opt_SpecEval) + , ([0,1,2], Opt_SpecEvalDictFun) ] ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -674,6 +674,9 @@ data GeneralFlag | Opt_NumConstantFolding | Opt_CoreConstantFolding | Opt_FastPAPCalls -- #6084 + | Opt_SpecEval + | Opt_SpecEvalDictFun -- See Note [Controlling Speculative Evaluation] + -- Inference flags | Opt_DoTagInferenceChecks @@ -912,6 +915,8 @@ optimisationFlags = EnumSet.fromList , Opt_WorkerWrapper , Opt_WorkerWrapperUnlift , Opt_SolveConstantDicts + , Opt_SpecEval + , Opt_SpecEvalDictFun ] -- | The set of flags which affect code generation and can change a program's ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2544,6 +2544,8 @@ fFlagsDeps = [ flagSpec "num-constant-folding" Opt_NumConstantFolding, flagSpec "core-constant-folding" Opt_CoreConstantFolding, flagSpec "fast-pap-calls" Opt_FastPAPCalls, + flagSpec "spec-eval" Opt_SpecEval, + flagSpec "spec-eval-dictfun" Opt_SpecEvalDictFun, flagSpec "cmm-control-flow" Opt_CmmControlFlow, flagSpec "show-warning-groups" Opt_ShowWarnGroups, flagSpec "hide-source-paths" Opt_HideSourcePaths, ===================================== compiler/GHC/Llvm.hs ===================================== @@ -42,6 +42,7 @@ module GHC.Llvm ( -- ** Metadata types MetaExpr(..), MetaAnnot(..), MetaDecl(..), MetaId(..), + Distinction(..), -- *** Module flags ModuleFlagBehavior(..), ModuleFlag(..), ===================================== compiler/GHC/Llvm/MetaData.hs ===================================== @@ -10,6 +10,7 @@ module GHC.Llvm.MetaData , ModuleFlagBehavior(..) , ModuleFlag(..) , moduleFlagToMetaExpr + , Distinction(..) ) where import GHC.Prelude @@ -87,6 +88,24 @@ data MetaExpr = MetaStr !LMString | MetaNode !MetaId | MetaVar !LlvmVar | MetaStruct [MetaExpr] + | MetaDIFile { difFilename :: !LMString + , difDirectory :: !LMString + } + | MetaDISubroutineType { distType :: ![MetaExpr] } + | MetaDICompileUnit { dicuLanguage :: !LMString + , dicuFile :: !MetaId + , dicuProducer :: !LMString + , dicuIsOptimized :: !Bool + , dicuSubprograms :: !MetaExpr + } + | MetaDISubprogram { disName :: !LMString + , disLinkageName :: !LMString + , disScope :: !MetaId + , disFile :: !MetaId + , disLine :: !Int + , disType :: !MetaId + , disIsDefinition :: !Bool + } deriving (Eq) -- | Associates some metadata with a specific label for attaching to an @@ -94,14 +113,17 @@ data MetaExpr = MetaStr !LMString data MetaAnnot = MetaAnnot LMString MetaExpr deriving (Eq) +-- | Is a metadata node @distinct@? +data Distinction = Distinct | NotDistinct + -- | Metadata declarations. Metadata can only be declared in global scope. data MetaDecl -- | Named metadata. Only used for communicating module information to -- LLVM. ('!name = !{ [!\] }' form). - = MetaNamed !LMString [MetaId] + = MetaNamed !LMString Distinction [MetaId] -- | Metadata node declaration. -- ('!0 = metadata !{ \ }' form). - | MetaUnnamed !MetaId !MetaExpr + | MetaUnnamed !MetaId Distinction !MetaExpr ---------------------------------------------------------------- -- Module flags ===================================== compiler/GHC/Llvm/Ppr.hs ===================================== @@ -1,6 +1,8 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE OverloadedStrings #-} -------------------------------------------------------------------------------- -- | Pretty print LLVM IR Code. @@ -131,16 +133,19 @@ ppLlvmMetas opts metas = lines_ $ map (ppLlvmMeta opts) metas -- | Print out an LLVM metadata definition. ppLlvmMeta :: IsLine doc => LlvmCgConfig -> MetaDecl -> doc -ppLlvmMeta opts (MetaUnnamed n m) - = ppMetaId n <+> equals <+> ppMetaExpr opts m +ppLlvmMeta opts (MetaUnnamed n d m) + = ppMetaId n <+> equals <+> ppDistinction d <+> ppMetaExpr opts m -ppLlvmMeta _opts (MetaNamed n m) - = exclamation <> ftext n <+> equals <+> exclamation <> braces nodes +ppLlvmMeta _opts (MetaNamed n d m) + = exclamation <> ftext n <+> equals <+> ppDistinction d <+> exclamation <> braces nodes where nodes = hcat $ intersperse comma $ map ppMetaId m {-# SPECIALIZE ppLlvmMeta :: LlvmCgConfig -> MetaDecl -> SDoc #-} {-# SPECIALIZE ppLlvmMeta :: LlvmCgConfig -> MetaDecl -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable +ppDistinction :: IsLine doc => Distinction -> doc +ppDistinction Distinct = text "distinct" +ppDistinction NotDistinct = empty -- | Print out a list of function definitions. ppLlvmFunctions :: IsDoc doc => LlvmCgConfig -> LlvmFunctions -> doc @@ -160,7 +165,7 @@ ppLlvmFunction opts fun = Nothing -> empty in vcat [line $ text "define" <+> ppLlvmFunctionHeader (funcDecl fun) (funcArgs fun) - <+> attrDoc <+> secDoc <+> prefixDoc + <+> attrDoc <+> secDoc <+> prefixDoc <+> ppMetaAnnots opts (funcMetadata fun) , line lbrace , ppLlvmBlocks opts (funcBody fun) , line rbrace @@ -302,6 +307,44 @@ ppMetaExpr opts = \case MetaNode n -> ppMetaId n MetaVar v -> ppVar opts v MetaStruct es -> char '!' <> braces (ppCommaJoin (ppMetaExpr opts) es) + MetaDIFile {..} -> + specialMetadata "DIFile" + [ ("filename" , doubleQuotes $ ftext difFilename) + , ("directory", doubleQuotes $ ftext difDirectory) + ] + MetaDISubroutineType {..} -> + specialMetadata "DISubroutineType" + [ ("types", ppMetaExpr opts $ MetaStruct distType ) ] + MetaDICompileUnit {..} -> + specialMetadata "DICompileUnit" + [ ("language" , ftext dicuLanguage) + , ("file" , ppMetaId dicuFile) + , ("producer" , doubleQuotes $ ftext dicuProducer) + , ("isOptimized", if dicuIsOptimized + then text "true" + else text "false") + , ("subprograms", ppMetaExpr opts $ dicuSubprograms) + ] + MetaDISubprogram {..} -> + specialMetadata "DISubprogram" + [ ("name" , doubleQuotes $ ftext disName) + , ("linkageName" , doubleQuotes $ ftext disLinkageName) + , ("scope" , ppMetaId disScope) + , ("file" , ppMetaId disFile) + , ("line" , int disLine) + , ("type" , ppMetaId disType) + , ("isDefinition", if disIsDefinition + then text "true" + else text "false") + ] + where + specialMetadata :: IsLine doc => String -> [(String, doc)] -> doc + specialMetadata nodeName fields = + char '!' + <> text nodeName + <> parens (hsep $ punctuate comma $ map (\(k,v) -> text k <> colon <+> v) fields) + + {-# SPECIALIZE ppMetaExpr :: LlvmCgConfig -> MetaExpr -> SDoc #-} {-# SPECIALIZE ppMetaExpr :: LlvmCgConfig -> MetaExpr -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable @@ -589,15 +632,15 @@ ppShuffle opts v1 v2 idxs = ppMetaAnnotExpr :: IsLine doc => LlvmCgConfig -> [MetaAnnot] -> LlvmExpression -> doc ppMetaAnnotExpr opts meta expr = - ppLlvmExpression opts expr <> ppMetaAnnots opts meta + ppLlvmExpression opts expr <> comma <+> ppMetaAnnots opts meta {-# SPECIALIZE ppMetaAnnotExpr :: LlvmCgConfig -> [MetaAnnot] -> LlvmExpression -> SDoc #-} {-# SPECIALIZE ppMetaAnnotExpr :: LlvmCgConfig -> [MetaAnnot] -> LlvmExpression -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable ppMetaAnnots :: IsLine doc => LlvmCgConfig -> [MetaAnnot] -> doc -ppMetaAnnots opts meta = hcat $ map ppMeta meta +ppMetaAnnots opts meta = hcat $ punctuate comma $ map ppMeta meta where ppMeta (MetaAnnot name e) - = comma <+> exclamation <> ftext name <+> + = exclamation <> ftext name <+> case e of MetaNode n -> ppMetaId n MetaStruct ms -> exclamation <> braces (ppCommaJoin (ppMetaExpr opts) ms) ===================================== compiler/GHC/Llvm/Syntax.hs ===================================== @@ -64,6 +64,9 @@ data LlvmFunction = LlvmFunction { -- | Prefix data funcPrefix :: Maybe LlvmStatic, + -- | Function metadata + funcMetadata :: [MetaAnnot], + -- | The body of the functions. funcBody :: LlvmBlocks } ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -405,6 +405,55 @@ as such you shouldn't need to set any of them explicitly. A flag intermediate language, where it is able to common up some subexpressions that differ in their types, but not their representation. +.. ghc-flag:: -fspec-eval + :shortdesc: Enables speculative evaluation. + :type: dynamic + :category: + :reverse: -fno-spec-eval + + :default: on + :since: 9.14.1 + + Enables speculative evaluation which usually results in fewer allocations. + Enabling speculative evaluation should not cause performance regressions. + If you encounter any, please open a ticket. + + Note that disabling this flag will switch off speculative evaluation + completely, causing :ghc-flag:`-fspec-eval-dictfun` to have + no effect. + +.. ghc-flag:: -fspec-eval-dictfun + :shortdesc: Enables speculative evaluation of dictionary functions. + :type: dynamic + :category: + :reverse: -fno-spec-eval-dictfun + + :default: on + :since: 9.14.1 + + Enables speculative (strict) evaluation of dictionary functions. + + This is best explained with an example :: + + instance C a => D a where ... + + g :: D a => a -> Int + g x = ... + + f :: C a => a -> Int + f x = g x + + Function `f` has to pass a `D a` dictionary to `g`, and uses a dictionary + function `C a => D a` to compute it. If speculative evaluation for + dictionary functions is enabled, this dictionary is computed + strictly. + + Speculative evalation of dictionary functions can lead to slightly better + performance, because a thunk is avoided. However, it results in unnecessary + computation and allocation if the dictionary goes unused. This causes + a significant increase in allocation if the dictionary is large. + See (:ghc-ticket:`25284`). + .. ghc-flag:: -fdicts-cheap :shortdesc: Make dictionary-valued expressions seem cheap to the optimiser. :type: dynamic ===================================== rts/Printer.c ===================================== @@ -151,13 +151,20 @@ printClosure( const StgClosure *obj ) case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_0_2: case FUN_2_0: case FUN_STATIC: - debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); - printPtr((StgPtr)obj->header.info); + { + debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); + + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #if defined(PROFILING) - debugBelch(", %s", obj->header.prof.ccs->cc->label); + debugBelch(", %s", obj->header.prof.ccs->cc->label); #endif - printStdObjPayload(obj); - break; + printStdObjPayload(obj); + break; + } case PRIM: debugBelch("PRIM("); @@ -175,13 +182,19 @@ printClosure( const StgClosure *obj ) case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: case THUNK_STATIC: + { /* ToDo: will this work for THUNK_STATIC too? */ #if defined(PROFILING) printThunkObject((StgThunk *)obj,GET_PROF_DESC(info)); #else printThunkObject((StgThunk *)obj,"THUNK"); + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #endif break; + } case THUNK_SELECTOR: printStdObjHdr(obj, "THUNK_SELECTOR"); ===================================== testsuite/tests/core-to-stg/T25284/A.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fspec-eval-dictfun #-} +module A (testX) where + +import qualified Cls + +-- this creates the big dictionary strictly because of speculative evaluation +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/B.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fno-spec-eval-dictfun #-} +module B (testX) where + +import qualified Cls + +-- this creates the big dictionary lazily +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/Cls.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE UndecidableInstances #-} + +module Cls where + +class HasConst a where constVal :: a + +instance Cls.HasConst Word where constVal = 123 + +instance Cls.HasConst Int where constVal = 456 + +-- this class has a big dictionary +class HasConst10 a where + constA :: a + constInt1 :: a -> Int + constInt1 _ = 1 + constInt2 :: a -> Int + constInt2 _ = 2 + constInt3 :: a -> Int + constInt3 _ = 3 + constInt4 :: a -> Int + constInt4 _ = 4 + constInt5 :: a -> Int + constInt5 _ = 5 + constInt6 :: a -> Int + constInt6 _ = 6 + constInt7 :: a -> Int + constInt7 _ = 7 + constInt8 :: a -> Int + constInt8 _ = 8 + constInt9 :: a -> Int + constInt9 _ = 9 + +instance HasConst a => HasConst10 a where + constA = constVal + +-- this doesn't use the big dictionary most of the time +printConst :: forall a. (Show a, HasConst10 a) + => a -> Int -> IO () +printConst x 5000 = print @a constA >> print (constInt8 x) +printConst _ _ = pure () ===================================== testsuite/tests/core-to-stg/T25284/Main.hs ===================================== @@ -0,0 +1,57 @@ +{- + + This tests that speculative evaluation for dictionary functions works as + expected, with a large dictionary that goes unused. + + - Module A: dictfun speculative evaluation enabled + - Module B: dictfun speculative evaluation disabled + + Speculative evaluation causes the unused large dictionary to be allocated + strictly in module A, so we expect more allocations than in module B. + + -} +module Main where + +import qualified A +import qualified B +import qualified Cls + +import Data.Word +import System.Mem (performGC) +import GHC.Stats +import Control.Monad + +{-# NOINLINE getAllocated #-} +getAllocated :: IO Word64 +getAllocated = do + performGC + allocated_bytes <$> getRTSStats + +main :: IO () +main = do + -- warm up (just in case) + _ <- testMain A.testX + _ <- testMain B.testX + + -- for real + a_alloc <- testMain A.testX + b_alloc <- testMain B.testX + + -- expect B to allocate less than A + let alloc_ratio :: Double + alloc_ratio = fromIntegral b_alloc / fromIntegral a_alloc + putStrLn ("expected alloc: " ++ show (alloc_ratio < 0.7)) + +iter :: (Int -> IO ()) -> Int -> Int -> IO () +iter m !i !j + | i < j = m i >> iter m (i+1) j + | otherwise = pure () + +{-# NOINLINE testMain #-} +testMain :: (forall b. (Show b, Cls.HasConst b) => b -> Int -> IO ()) + -> IO Word64 +testMain f = do + alloc0 <- getAllocated + iter (\i -> f (0::Int) i >> f (0::Word) i) 1 100000 + alloc1 <- getAllocated + pure (alloc1 - alloc0) ===================================== testsuite/tests/core-to-stg/T25284/T25284.stdout ===================================== @@ -0,0 +1,17 @@ +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +expected alloc: True ===================================== testsuite/tests/core-to-stg/T25284/all.T ===================================== @@ -0,0 +1,6 @@ +test('T25284', + [js_skip, # allocation counters aren't available on the JS backend + extra_files(['Main.hs', 'A.hs', 'B.hs', 'Cls.hs']), + extra_run_opts('+RTS -T -RTS')], + multimod_compile_and_run, + ['Main', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c31db33f83c765d51b535f2ad02745afd5c1d05...62eab54ba3dfedac4e3f7e76d1fc3d8d6d84d25b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c31db33f83c765d51b535f2ad02745afd5c1d05...62eab54ba3dfedac4e3f7e76d1fc3d8d6d84d25b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 15:16:10 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 10 Jan 2025 10:16:10 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] 37 commits: Add flags for switching off speculative evaluation. Message-ID: <678139b9e15ab_1a7bc05bc1888@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 96a72c6b by Patrick at 2025-01-10T15:14:29+00:00 relax newType instance check - - - - - a05acbcc by Patrick at 2025-01-10T15:14:29+00:00 include constructor in kind-checking for data family instance - - - - - 23c8f259 by Patrick at 2025-01-10T15:14:29+00:00 add test case for T25611 - - - - - c152e6bf by Patrick at 2025-01-10T15:14:29+00:00 add test for T25593 - - - - - 9909a336 by Patrick at 2025-01-10T15:14:29+00:00 add test for T25593 - - - - - 383fb3e8 by Patrick at 2025-01-10T15:14:29+00:00 Fix T25593 - - - - - 05f9a1b2 by Patrick at 2025-01-10T15:14:29+00:00 add test to ensure kind specialization is working as Note [Kind inference for data family instances] - - - - - 31d1304a by Patrick at 2025-01-10T15:14:29+00:00 update test InstanceConKindSpecializationDataFamily - - - - - a46c7ad1 by Patrick at 2025-01-10T15:14:29+00:00 update test InstanceConKindSpecializationDataFamily - - - - - cdcb46a5 by Patrick at 2025-01-10T15:14:29+00:00 Update Note [Implementation of UnliftedNewtypes] - - - - - 19d60a7a by Patrick at 2025-01-10T15:14:29+00:00 format - - - - - 616e09ef by Patrick at 2025-01-10T15:14:29+00:00 update Test `UnliftedNewtypesFamilyKindFail2`, `UnliftedNewtypesInstanceFail` for additional warning introduced by reintroduce datafam decls in kind check. - - - - - 09e0290b by Patrick at 2025-01-10T15:14:29+00:00 update comment - - - - - 57314ec1 by Patrick at 2025-01-10T15:14:29+00:00 Change UnliftedNewtypesUnassociatedFamilyFail to UnliftedNewtypesUnassociatedFamilyInfer. - - - - - 2464723e by Patrick at 2025-01-10T15:14:29+00:00 cleanup - - - - - a20cef68 by Patrick at 2025-01-10T15:14:29+00:00 Only kcConDecls for (A) newtype or (B) H98 style - - - - - b5c167f9 by Patrick at 2025-01-10T15:14:29+00:00 add isH98orNewType for clarity - - - - - bd85b20c by Patrick at 2025-01-10T15:14:29+00:00 tidy up - - - - - e262fe7a by Patrick at 2025-01-10T15:14:29+00:00 Check we defaults the result kind of the data instance correctly - - - - - a45fff74 by Patrick at 2025-01-10T15:14:29+00:00 add more examples to dataInstanceKindsDefaults - - - - - 4297215d by Patrick at 2025-01-10T15:14:29+00:00 arrange the fix to 25593 to another branch - - - - - 7375673b by Patrick at 2025-01-10T15:14:29+00:00 update Note [Kind inference for data family instances] - - - - - e3e6f1c0 by Patrick at 2025-01-10T15:14:29+00:00 format - - - - - 1271f33c by Patrick at 2025-01-10T15:14:29+00:00 update Note [Kind inference for data family instances] - - - - - b553e6b9 by Patrick at 2025-01-10T15:14:29+00:00 adding test case UnliftedNewtypesRunTypeRepPoly - - - - - 8f0b3553 by Patrick at 2025-01-10T15:14:29+00:00 rename etaExpandAlgTyCon -> maybeEtaExpandAlgTyCon and introduce etaExpandAlgTyCon to expand unconditionally - - - - - a1235ebf by Patrick at 2025-01-10T15:14:29+00:00 update note - - - - - 7746dda9 by Patrick at 2025-01-10T15:14:29+00:00 update note - - - - - b8b4a9b2 by Patrick at 2025-01-10T15:14:29+00:00 update note - - - - - c5d41a76 by Patrick at 2025-01-10T15:14:29+00:00 update test UnliftedNewtypesRunTypeRepPoly - - - - - fc9ee1b0 by Patrick at 2025-01-10T15:14:29+00:00 update test DataInstanceKindsDefaults - - - - - 0fd6a1bd by Patrick at 2025-01-10T15:14:29+00:00 update note [Data family/instance return kinds] and [Defaulting result kind of newtype/data family instance] - - - - - 7add32d8 by Patrick at 2025-01-10T15:14:29+00:00 Refine the note - - - - - b6e43cfd by Patrick at 2025-01-10T15:14:29+00:00 update note [Data family/instance return kinds] - - - - - 584ca538 by Patrick at 2025-01-10T15:14:29+00:00 format - - - - - 28 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - docs/users_guide/using-optimisation.rst - rts/Printer.c - + testsuite/tests/core-to-stg/T25284/A.hs - + testsuite/tests/core-to-stg/T25284/B.hs - + testsuite/tests/core-to-stg/T25284/Cls.hs - + testsuite/tests/core-to-stg/T25284/Main.hs - + testsuite/tests/core-to-stg/T25284/T25284.stdout - + testsuite/tests/core-to-stg/T25284/all.T - + testsuite/tests/indexed-types/should_compile/T25611.hs - testsuite/tests/indexed-types/should_compile/all.T - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs - testsuite/tests/indexed-types/should_fail/all.T - + testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs - + testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs - + testsuite/tests/typecheck/should_compile/UnliftedNewtypesUnassociatedFamilyInfer.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2051,6 +2051,16 @@ conceptually. See also Note [Floats and FloatDecision] for how we maintain whole groups of floats and how far they go. +Note [Controlling Speculative Evaluation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Most of the time, speculative evaluation has a positive effect on performance, +but we have found a case where speculative evaluation of dictionary functions +leads to a performance regression #25284. + +Therefore we have some flags to control it. See the optimization section in +the User's Guide for the description of these flags and when to use them. + Note [Floats and FloatDecision] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We have a special datatype `Floats` for modelling a telescope of `FloatingBind` @@ -2275,7 +2285,15 @@ mkNonRecFloat env lev bndr rhs } is_hnf = exprIsHNF rhs - ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs + cfg = cpe_config env + + ok_for_spec = exprOkForSpecEval call_ok_for_spec rhs + -- See Note [Controlling Speculative Evaluation] + call_ok_for_spec x + | is_rec_call x = False + | not (cp_specEval cfg) = False + | not (cp_specEvalDFun cfg) && isDFunId x = False + | otherwise = True is_rec_call = (`elemUnVarSet` cpe_rec_ids env) -- See Note [Pin evaluatedness on floats] @@ -2517,6 +2535,11 @@ data CorePrepConfig = CorePrepConfig -- ^ Configuration for arity analysis ('exprEtaExpandArity'). -- See Note [Eta expansion of arguments in CorePrep] -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead + , cp_specEval :: !Bool + -- ^ Whether to perform speculative evaluation + -- See Note [Controlling Speculative Evaluation] + , cp_specEvalDFun :: !Bool + -- ^ Whether to perform speculative evaluation on DFuns } data CorePrepEnv ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -24,6 +24,8 @@ initCorePrepConfig hsc_env = do , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags then Just (initArityOpts dflags) else Nothing + , cp_specEval = gopt Opt_SpecEval dflags + , cp_specEvalDFun = gopt Opt_SpecEvalDictFun dflags } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1287,6 +1287,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] -- RegsGraph suffers performance regression. See #7679 -- , ([2], Opt_StaticArgumentTransformation) -- Static Argument Transformation needs investigation. See #9374 + , ([0,1,2], Opt_SpecEval) + , ([0,1,2], Opt_SpecEvalDictFun) ] ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -674,6 +674,9 @@ data GeneralFlag | Opt_NumConstantFolding | Opt_CoreConstantFolding | Opt_FastPAPCalls -- #6084 + | Opt_SpecEval + | Opt_SpecEvalDictFun -- See Note [Controlling Speculative Evaluation] + -- Inference flags | Opt_DoTagInferenceChecks @@ -912,6 +915,8 @@ optimisationFlags = EnumSet.fromList , Opt_WorkerWrapper , Opt_WorkerWrapperUnlift , Opt_SolveConstantDicts + , Opt_SpecEval + , Opt_SpecEvalDictFun ] -- | The set of flags which affect code generation and can change a program's ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2544,6 +2544,8 @@ fFlagsDeps = [ flagSpec "num-constant-folding" Opt_NumConstantFolding, flagSpec "core-constant-folding" Opt_CoreConstantFolding, flagSpec "fast-pap-calls" Opt_FastPAPCalls, + flagSpec "spec-eval" Opt_SpecEval, + flagSpec "spec-eval-dictfun" Opt_SpecEvalDictFun, flagSpec "cmm-control-flow" Opt_CmmControlFlow, flagSpec "show-warning-groups" Opt_ShowWarnGroups, flagSpec "hide-source-paths" Opt_HideSourcePaths, ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors + -- Add constraints from the data constructors + -- Fix #25611 -- See Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +default the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -405,6 +405,55 @@ as such you shouldn't need to set any of them explicitly. A flag intermediate language, where it is able to common up some subexpressions that differ in their types, but not their representation. +.. ghc-flag:: -fspec-eval + :shortdesc: Enables speculative evaluation. + :type: dynamic + :category: + :reverse: -fno-spec-eval + + :default: on + :since: 9.14.1 + + Enables speculative evaluation which usually results in fewer allocations. + Enabling speculative evaluation should not cause performance regressions. + If you encounter any, please open a ticket. + + Note that disabling this flag will switch off speculative evaluation + completely, causing :ghc-flag:`-fspec-eval-dictfun` to have + no effect. + +.. ghc-flag:: -fspec-eval-dictfun + :shortdesc: Enables speculative evaluation of dictionary functions. + :type: dynamic + :category: + :reverse: -fno-spec-eval-dictfun + + :default: on + :since: 9.14.1 + + Enables speculative (strict) evaluation of dictionary functions. + + This is best explained with an example :: + + instance C a => D a where ... + + g :: D a => a -> Int + g x = ... + + f :: C a => a -> Int + f x = g x + + Function `f` has to pass a `D a` dictionary to `g`, and uses a dictionary + function `C a => D a` to compute it. If speculative evaluation for + dictionary functions is enabled, this dictionary is computed + strictly. + + Speculative evalation of dictionary functions can lead to slightly better + performance, because a thunk is avoided. However, it results in unnecessary + computation and allocation if the dictionary goes unused. This causes + a significant increase in allocation if the dictionary is large. + See (:ghc-ticket:`25284`). + .. ghc-flag:: -fdicts-cheap :shortdesc: Make dictionary-valued expressions seem cheap to the optimiser. :type: dynamic ===================================== rts/Printer.c ===================================== @@ -151,13 +151,20 @@ printClosure( const StgClosure *obj ) case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_0_2: case FUN_2_0: case FUN_STATIC: - debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); - printPtr((StgPtr)obj->header.info); + { + debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); + + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #if defined(PROFILING) - debugBelch(", %s", obj->header.prof.ccs->cc->label); + debugBelch(", %s", obj->header.prof.ccs->cc->label); #endif - printStdObjPayload(obj); - break; + printStdObjPayload(obj); + break; + } case PRIM: debugBelch("PRIM("); @@ -175,13 +182,19 @@ printClosure( const StgClosure *obj ) case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: case THUNK_STATIC: + { /* ToDo: will this work for THUNK_STATIC too? */ #if defined(PROFILING) printThunkObject((StgThunk *)obj,GET_PROF_DESC(info)); #else printThunkObject((StgThunk *)obj,"THUNK"); + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #endif break; + } case THUNK_SELECTOR: printStdObjHdr(obj, "THUNK_SELECTOR"); ===================================== testsuite/tests/core-to-stg/T25284/A.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fspec-eval-dictfun #-} +module A (testX) where + +import qualified Cls + +-- this creates the big dictionary strictly because of speculative evaluation +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/B.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fno-spec-eval-dictfun #-} +module B (testX) where + +import qualified Cls + +-- this creates the big dictionary lazily +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/Cls.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE UndecidableInstances #-} + +module Cls where + +class HasConst a where constVal :: a + +instance Cls.HasConst Word where constVal = 123 + +instance Cls.HasConst Int where constVal = 456 + +-- this class has a big dictionary +class HasConst10 a where + constA :: a + constInt1 :: a -> Int + constInt1 _ = 1 + constInt2 :: a -> Int + constInt2 _ = 2 + constInt3 :: a -> Int + constInt3 _ = 3 + constInt4 :: a -> Int + constInt4 _ = 4 + constInt5 :: a -> Int + constInt5 _ = 5 + constInt6 :: a -> Int + constInt6 _ = 6 + constInt7 :: a -> Int + constInt7 _ = 7 + constInt8 :: a -> Int + constInt8 _ = 8 + constInt9 :: a -> Int + constInt9 _ = 9 + +instance HasConst a => HasConst10 a where + constA = constVal + +-- this doesn't use the big dictionary most of the time +printConst :: forall a. (Show a, HasConst10 a) + => a -> Int -> IO () +printConst x 5000 = print @a constA >> print (constInt8 x) +printConst _ _ = pure () ===================================== testsuite/tests/core-to-stg/T25284/Main.hs ===================================== @@ -0,0 +1,57 @@ +{- + + This tests that speculative evaluation for dictionary functions works as + expected, with a large dictionary that goes unused. + + - Module A: dictfun speculative evaluation enabled + - Module B: dictfun speculative evaluation disabled + + Speculative evaluation causes the unused large dictionary to be allocated + strictly in module A, so we expect more allocations than in module B. + + -} +module Main where + +import qualified A +import qualified B +import qualified Cls + +import Data.Word +import System.Mem (performGC) +import GHC.Stats +import Control.Monad + +{-# NOINLINE getAllocated #-} +getAllocated :: IO Word64 +getAllocated = do + performGC + allocated_bytes <$> getRTSStats + +main :: IO () +main = do + -- warm up (just in case) + _ <- testMain A.testX + _ <- testMain B.testX + + -- for real + a_alloc <- testMain A.testX + b_alloc <- testMain B.testX + + -- expect B to allocate less than A + let alloc_ratio :: Double + alloc_ratio = fromIntegral b_alloc / fromIntegral a_alloc + putStrLn ("expected alloc: " ++ show (alloc_ratio < 0.7)) + +iter :: (Int -> IO ()) -> Int -> Int -> IO () +iter m !i !j + | i < j = m i >> iter m (i+1) j + | otherwise = pure () + +{-# NOINLINE testMain #-} +testMain :: (forall b. (Show b, Cls.HasConst b) => b -> Int -> IO ()) + -> IO Word64 +testMain f = do + alloc0 <- getAllocated + iter (\i -> f (0::Int) i >> f (0::Word) i) 1 100000 + alloc1 <- getAllocated + pure (alloc1 - alloc0) ===================================== testsuite/tests/core-to-stg/T25284/T25284.stdout ===================================== @@ -0,0 +1,17 @@ +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +expected alloc: True ===================================== testsuite/tests/core-to-stg/T25284/all.T ===================================== @@ -0,0 +1,6 @@ +test('T25284', + [js_skip, # allocation counters aren't available on the JS backend + extra_files(['Main.hs', 'A.hs', 'B.hs', 'Cls.hs']), + extra_run_opts('+RTS -T -RTS')], + multimod_compile_and_run, + ['Main', '']) ===================================== testsuite/tests/indexed-types/should_compile/T25611.hs ===================================== @@ -0,0 +1,9 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611 where + +import Data.Kind + +data family Fix :: (k -> Type) -> k +newtype instance Fix f = In { out :: f (Fix f) } ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,5 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('T25611', normal, compile, ['']) +test('dataInstanceKindsDefaults', normal, compile, ['']) ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module InstanceConKindSpecializationDataFamily where + +import GHC.Prim (Int#) + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs ===================================== @@ -0,0 +1,33 @@ +{-# LANGUAGE GADTSyntax #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE RankNTypes #-} + +module UnliftedNewtypesRunTypeRepPoly where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- ensure newtype[instance] can be runtime-rep-polymorphic + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesUnassociatedFamilyInfer.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module UnliftedNewtypesUnassociatedFamily where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -696,6 +696,7 @@ test('T505', normal, compile, ['']) test('T12928', normal, compile, ['']) test('UnliftedNewtypesGnd', normal, compile, ['']) test('UnliftedNewtypesUnassociatedFamily', normal, compile, ['']) +test('UnliftedNewtypesUnassociatedFamilyInfer', normal, compile, ['']) test('UnliftedNewtypesUnifySig', normal, compile, ['']) test('UnliftedNewtypesForall', normal, compile, ['']) test('UnlifNewUnify', normal, compile, ['']) @@ -932,3 +933,5 @@ test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) test('T25597', normal, compile, ['']) +test('InstanceConKindSpecializationDataFamily', normal, compile, ['']) +test('UnliftedNewtypesRunTypeRepPoly', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c92e4474e082185cf41bf2fb36c02545ff98376...584ca538b36c58ede0cb414bb96a614f8dbbd1ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c92e4474e082185cf41bf2fb36c02545ff98376...584ca538b36c58ede0cb414bb96a614f8dbbd1ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 15:22:00 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 10 Jan 2025 10:22:00 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: user_guide: Note -pgmP/-optP are for /Haskell/-CPP Message-ID: <67813b18acaae_1a7be870882485e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: efb786dd by Rodrigo Mesquita at 2025-01-10T10:17:39-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - 1c80092a by Ben Gamari at 2025-01-10T10:17:39-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2 changed files: - docs/users_guide/phases.rst - utils/dump-decls/Main.hs Changes: ===================================== docs/users_guide/phases.rst ===================================== @@ -25,11 +25,12 @@ given compilation phase: Use ⟨cmd⟩ as the literate pre-processor. .. ghc-flag:: -pgmP ⟨cmd⟩ - :shortdesc: Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only) + :shortdesc: Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only) :type: dynamic :category: phase-programs - Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only). + Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only). + Note that the Haskell C pre-processor only pre-processes Haskell files. .. ghc-flag:: -pgmJSP ⟨cmd⟩ :shortdesc: Use ⟨cmd⟩ as the JavaScript C pre-processor (only for javascript-backend) @@ -177,7 +178,11 @@ the following flags: :type: dynamic :category: phase-options - Pass ⟨option⟩ to CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Pass ⟨option⟩ to the Haskell CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Note that the Haskell pre-processor options only apply to pre-processing + invocations on Haskell files, and, e.g., to use different options to + pre-process Javascript or Cmm, one should use ``-optJSP``, or + ``-optCmmP``, respectively). .. ghc-flag:: -optJSP ⟨option⟩ :shortdesc: pass ⟨option⟩ to JavaScript C pre-processor (only for javascript-backend) ===================================== utils/dump-decls/Main.hs ===================================== @@ -38,6 +38,7 @@ run root pkg_nm = runGhc (Just root) $ do , "-dppr-cols=1000" , "-fprint-explicit-runtime-reps" , "-fprint-explicit-foralls" + , "-fsuppress-unit-ids" ] dflags <- do dflags <- getSessionDynFlags View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d67ed785230b22af25c05983cd61d51bf4920806...1c80092a23f01279cca64e5907787e10137904a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d67ed785230b22af25c05983cd61d51bf4920806...1c80092a23f01279cca64e5907787e10137904a4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 15:42:45 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Fri, 10 Jan 2025 10:42:45 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add HsConFieldSpec Message-ID: <67813ff5a52fb_141d7c059411448@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: a5f3100b by Sjoerd Visscher at 2025-01-10T10:54:57+01:00 Add HsConFieldSpec - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Extension.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/printer/T18791.stderr - utils/check-exact/ExactPrint.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a5f3100bb88e677a314a99cfe824d449b6c2ec8b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a5f3100bb88e677a314a99cfe824d449b6c2ec8b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 16:09:21 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 10 Jan 2025 11:09:21 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Fix #25611. Message-ID: <67814631cb539_141d732ad5c139bc@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: d26d48d3 by Patrick at 2025-01-10T23:41:55+08:00 Fix #25611. This patch enhances the kind inference for data family instances, by including the RHS's constraints when kind-checking LHS. Type checker changes: In `tcDataFamInstHeader`, `kcConDecls` the H98-style decls and newtype decls, even those in GADT syntax, but NOT for general GADT decls. Testsuite changes: 1. The test to ensure kind specialization remains correctly handled even if we include the RHS's constrains: InstanceConKindSpecializationDataFamily UnliftedNewtypesRunTypeRepPoly 2. Infer result kind from datacon, Example in #25611: T25611 3. Two tests with additional errors report: UnliftedNewtypesFamilyKindFail2 UnliftedNewtypesInstanceFail 4. Due to better kind inference, move should_fail test UnliftedNewtypesUnassociatedFamilyFail to should_compile test UnliftedNewtypesUnassociatedFamilyInfer. Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 15 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/T25611.hs - testsuite/tests/indexed-types/should_compile/all.T - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs - testsuite/tests/indexed-types/should_fail/all.T - + testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs - + testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs - + testsuite/tests/typecheck/should_compile/UnliftedNewtypesUnassociatedFamilyInfer.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors + -- Add constraints from the data constructors + -- Fix #25611 -- See Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +default the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/T25611.hs ===================================== @@ -0,0 +1,9 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611 where + +import Data.Kind + +data family Fix :: (k -> Type) -> k +newtype instance Fix f = In { out :: f (Fix f) } ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,5 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('T25611', normal, compile, ['']) +test('dataInstanceKindsDefaults', normal, compile, ['']) ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module InstanceConKindSpecializationDataFamily where + +import GHC.Prim (Int#) + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs ===================================== @@ -0,0 +1,33 @@ +{-# LANGUAGE GADTSyntax #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE RankNTypes #-} + +module UnliftedNewtypesRunTypeRepPoly where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- ensure newtype[instance] can be runtime-rep-polymorphic + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesUnassociatedFamilyInfer.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module UnliftedNewtypesUnassociatedFamily where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -696,6 +696,7 @@ test('T505', normal, compile, ['']) test('T12928', normal, compile, ['']) test('UnliftedNewtypesGnd', normal, compile, ['']) test('UnliftedNewtypesUnassociatedFamily', normal, compile, ['']) +test('UnliftedNewtypesUnassociatedFamilyInfer', normal, compile, ['']) test('UnliftedNewtypesUnifySig', normal, compile, ['']) test('UnliftedNewtypesForall', normal, compile, ['']) test('UnlifNewUnify', normal, compile, ['']) @@ -932,3 +933,5 @@ test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) test('T25597', normal, compile, ['']) +test('InstanceConKindSpecializationDataFamily', normal, compile, ['']) +test('UnliftedNewtypesRunTypeRepPoly', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d26d48d38b8781d9e3b0bbd97d8b892ab1b4fad1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d26d48d38b8781d9e3b0bbd97d8b892ab1b4fad1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 16:15:45 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 10 Jan 2025 11:15:45 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Fix #25611. Enhances the kind inference for data family instances, Message-ID: <678147b1b8d8e_141d7355368145c7@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 4be2f3be by Patrick at 2025-01-11T00:14:52+08:00 Fix #25611. Enhances the kind inference for data family instances, by including the RHS's constraints when kind-checking LHS. Type checker changes: In `tcDataFamInstHeader`, `kcConDecls` the H98-style decls and newtype decls, even those in GADT syntax, but NOT for general GADT decls. Testsuite changes: 1. The test to ensure kind specialization remains correctly handled even if we include the RHS's constrains: InstanceConKindSpecializationDataFamily UnliftedNewtypesRunTypeRepPoly 2. Infer result kind from datacon, Example in #25611: T25611 3. Two tests with additional errors report: UnliftedNewtypesFamilyKindFail2 UnliftedNewtypesInstanceFail 4. Due to better kind inference, move should_fail test UnliftedNewtypesUnassociatedFamilyFail to should_compile test UnliftedNewtypesUnassociatedFamilyInfer. Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 15 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/T25611.hs - testsuite/tests/indexed-types/should_compile/all.T - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs - testsuite/tests/indexed-types/should_fail/all.T - + testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs - + testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs - + testsuite/tests/typecheck/should_compile/UnliftedNewtypesUnassociatedFamilyInfer.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors + -- Add constraints from the data constructors + -- Fix #25611 -- See Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +default the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/T25611.hs ===================================== @@ -0,0 +1,9 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611 where + +import Data.Kind + +data family Fix :: (k -> Type) -> k +newtype instance Fix f = In { out :: f (Fix f) } ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,5 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('T25611', normal, compile, ['']) +test('dataInstanceKindsDefaults', normal, compile, ['']) ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_compile/InstanceConKindSpecializationDataFamily.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module InstanceConKindSpecializationDataFamily where + +import GHC.Prim (Int#) + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesRunTypeRepPoly.hs ===================================== @@ -0,0 +1,33 @@ +{-# LANGUAGE GADTSyntax #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE RankNTypes #-} + +module UnliftedNewtypesRunTypeRepPoly where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- ensure newtype[instance] can be runtime-rep-polymorphic + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/typecheck/should_compile/UnliftedNewtypesUnassociatedFamilyInfer.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module UnliftedNewtypesUnassociatedFamily where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -696,6 +696,7 @@ test('T505', normal, compile, ['']) test('T12928', normal, compile, ['']) test('UnliftedNewtypesGnd', normal, compile, ['']) test('UnliftedNewtypesUnassociatedFamily', normal, compile, ['']) +test('UnliftedNewtypesUnassociatedFamilyInfer', normal, compile, ['']) test('UnliftedNewtypesUnifySig', normal, compile, ['']) test('UnliftedNewtypesForall', normal, compile, ['']) test('UnlifNewUnify', normal, compile, ['']) @@ -932,3 +933,5 @@ test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) test('T25597', normal, compile, ['']) +test('InstanceConKindSpecializationDataFamily', normal, compile, ['']) +test('UnliftedNewtypesRunTypeRepPoly', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4be2f3be9c9bddff1e064c96695ea59087c90a50 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4be2f3be9c9bddff1e064c96695ea59087c90a50 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 16:47:17 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Fri, 10 Jan 2025 11:47:17 -0500 Subject: [Git][ghc/ghc][wip/T18462] Restrict XBangTy and XRectTy to GhcPs phase Message-ID: <67814f156d1e7_141d7834e24236e0@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 9103745e by Sjoerd Visscher at 2025-01-10T17:46:55+01:00 Restrict XBangTy and XRectTy to GhcPs phase - - - - - 25 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/rename/should_fail/T22478b.stderr - utils/check-exact/ExactPrint.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/GhcUtils.hs - utils/haddock/haddock-api/src/Haddock/Interface/Create.hs - utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs - utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs - utils/haddock/haddock-api/src/Haddock/Types.hs Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -530,6 +530,8 @@ deriving instance Data (HsType GhcPs) deriving instance Data (HsType GhcRn) deriving instance Data (HsType GhcTc) +deriving instance Data (HsTypeGhcPsExt GhcPs) + -- deriving instance (DataIdLR p p) => Data (HsTyLit p) deriving instance Data (HsTyLit GhcPs) deriving instance Data (HsTyLit GhcRn) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -32,6 +32,7 @@ module GHC.Hs.Type ( pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, + HsTypeGhcPsExt(..), HsForAllTelescope(..), EpAnnForallVis, EpAnnForallInvis, HsTyVarBndr(..), LHsTyVarBndr, AnnTyVarBndr(..), HsBndrKind(..), @@ -55,7 +56,6 @@ module GHC.Hs.Type ( LBangType, BangType, HsSrcBang(..), HsImplBang(..), SrcStrictness(..), SrcUnpackedness(..), - getBangType, getBangStrictness, ConDeclField(..), LConDeclField, pprConDeclFields, @@ -108,7 +108,6 @@ import {-# SOURCE #-} GHC.Hs.Expr ( pprUntypedSplice, HsUntypedSpliceResult(..) import Language.Haskell.Syntax.Extension import GHC.Core.DataCon ( SrcStrictness(..), SrcUnpackedness(..) , HsSrcBang(..), HsImplBang(..) - , mkHsSrcBang ) import GHC.Hs.Extension import GHC.Parser.Annotation @@ -136,25 +135,6 @@ import Data.Data (Data) import qualified Data.Semigroup as S import GHC.Data.Bag -{- -************************************************************************ -* * -\subsection{Bang annotations} -* * -************************************************************************ --} - -getBangType :: LHsType (GhcPass p) -> LHsType (GhcPass p) -getBangType (L _ (HsBangTy _ _ lty)) = lty -getBangType (L _ (HsDocTy x (L _ (HsBangTy _ _ lty)) lds)) = - addCLocA lty lds (HsDocTy x lty lds) -getBangType lty = lty - -getBangStrictness :: LHsType (GhcPass p) -> HsSrcBang -getBangStrictness (L _ (HsBangTy (_, s) b _)) = HsSrcBang s b -getBangStrictness (L _ (HsDocTy _ (L _ (HsBangTy (_, s) b _)) _)) = HsSrcBang s b -getBangStrictness _ = (mkHsSrcBang NoSourceText NoSrcUnpack NoSrcStrict) - {- ************************************************************************ * * @@ -504,7 +484,9 @@ type instance XWildCardTy GhcPs = EpToken "_" type instance XWildCardTy GhcRn = NoExtField type instance XWildCardTy GhcTc = NoExtField -type instance XXType (GhcPass _) = HsCoreTy +type instance XXType GhcPs = HsTypeGhcPsExt GhcPs +type instance XXType GhcRn = HsCoreTy +type instance XXType GhcTc = DataConCantHappen -- An escape hatch for tunnelling a Core 'Type' through 'HsType'. -- For more details on how this works, see: @@ -519,6 +501,15 @@ type instance XStrTy (GhcPass _) = SourceText type instance XCharTy (GhcPass _) = SourceText type instance XXTyLit (GhcPass _) = DataConCantHappen +data HsTypeGhcPsExt pass + = HsCoreTy HsCoreTy + + | HsBangTy (XBangTy pass) -- Contains the SourceText in GHC passes. + HsBang (LHsType pass) -- Bang-style type annotations + + | HsRecTy (XRecTy pass) + [LConDeclField pass] -- Only in data type declarations + data EpLinearArrow = EpPct1 !(EpToken "%1") !(TokRarrow) | EpLolly !(EpToken "⊸") @@ -1311,7 +1302,7 @@ hsPlainTypeField = mkConFieldSpec (HsLinearAnn noAnn) mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs mkConFieldSpec mult (L l (HsDocTy x ty lds)) = case mkConFieldSpec mult ty of CFS ann unp str mult' t -> CFS ann unp str mult' (L l (HsDocTy x t lds)) -mkConFieldSpec mult (L _ (HsBangTy ann (HsBang unp str) t)) = CFS ann unp str mult t +mkConFieldSpec mult (L _ (XHsType (HsBangTy ann (HsBang unp str) t))) = CFS ann unp str mult t mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t instance Outputable (XRecGhc (IdGhcP p)) => @@ -1410,8 +1401,6 @@ ppr_mono_ty (HsForAllTy { hst_tele = tele, hst_body = ty }) ppr_mono_ty (HsQualTy { hst_ctxt = ctxt, hst_body = ty }) = sep [pprLHsContextAlways ctxt, ppr_mono_lty ty] -ppr_mono_ty (HsBangTy _ b ty) = ppr b <> ppr_mono_lty ty -ppr_mono_ty (HsRecTy _ flds) = pprConDeclFields flds ppr_mono_ty (HsTyVar _ prom (L _ name)) = pprOccWithTick Prefix prom name ppr_mono_ty (HsFunTy _ mult ty1 ty2) = ppr_fun_ty mult ty1 ty2 ppr_mono_ty (HsTupleTy _ con tys) @@ -1468,7 +1457,12 @@ ppr_mono_ty (HsParTy _ ty) ppr_mono_ty (HsDocTy _ ty doc) = pprWithDoc doc $ ppr_mono_lty ty -ppr_mono_ty (XHsType t) = ppr t +ppr_mono_ty (XHsType t) = case ghcPass @p of + GhcPs -> case t of + HsCoreTy ty -> ppr ty + HsBangTy _ b ty -> ppr b <> ppr_mono_lty ty + HsRecTy _ flds -> pprConDeclFields flds + GhcRn -> ppr t -------------------------- ppr_fun_ty :: (OutputableBndrId p) @@ -1487,13 +1481,11 @@ quote_tuple NotPromoted doc = doc -------------------------- -- | @'hsTypeNeedsParens' p t@ returns 'True' if the type @t@ needs parentheses -- under precedence @p at . -hsTypeNeedsParens :: PprPrec -> HsType (GhcPass p) -> Bool +hsTypeNeedsParens :: forall p. IsPass p => PprPrec -> HsType (GhcPass p) -> Bool hsTypeNeedsParens p = go_hs_ty where go_hs_ty (HsForAllTy{}) = p >= funPrec go_hs_ty (HsQualTy{}) = p >= funPrec - go_hs_ty (HsBangTy{}) = p > topPrec - go_hs_ty (HsRecTy{}) = False go_hs_ty (HsTyVar{}) = False go_hs_ty (HsFunTy{}) = p >= funPrec -- Special-case unary boxed tuple applications so that they are @@ -1524,7 +1516,12 @@ hsTypeNeedsParens p = go_hs_ty go_hs_ty (HsOpTy{}) = p >= opPrec go_hs_ty (HsParTy{}) = False go_hs_ty (HsDocTy _ (L _ t) _) = go_hs_ty t - go_hs_ty (XHsType ty) = go_core_ty ty + go_hs_ty (XHsType t) = case ghcPass @p of + GhcPs -> case t of + HsCoreTy ty -> go_core_ty ty + HsBangTy{} -> p > topPrec + HsRecTy{} -> False + GhcRn -> go_core_ty t go_core_ty (TyVarTy{}) = False go_core_ty (AppTy{}) = p >= appPrec @@ -1556,8 +1553,6 @@ lhsTypeHasLeadingPromotionQuote ty go (HsQualTy{ hst_ctxt = ctxt, hst_body = body}) | (L _ (c:_)) <- ctxt = goL c | otherwise = goL body - go (HsBangTy{}) = False - go (HsRecTy{}) = False go (HsTyVar _ p _) = isPromoted p go (HsFunTy _ _ arg _) = goL arg go (HsListTy{}) = False @@ -1581,7 +1576,7 @@ lhsTypeHasLeadingPromotionQuote ty -- | @'parenthesizeHsType' p ty@ checks if @'hsTypeNeedsParens' p ty@ is -- true, and if so, surrounds @ty@ with an 'HsParTy'. Otherwise, it simply -- returns @ty at . -parenthesizeHsType :: PprPrec -> LHsType (GhcPass p) -> LHsType (GhcPass p) +parenthesizeHsType :: IsPass p => PprPrec -> LHsType (GhcPass p) -> LHsType (GhcPass p) parenthesizeHsType p lty@(L loc ty) | hsTypeNeedsParens p ty = L loc (HsParTy noAnn lty) | otherwise = lty @@ -1590,8 +1585,7 @@ parenthesizeHsType p lty@(L loc ty) -- @c@ such that @'hsTypeNeedsParens' p c@ is true, and if so, surrounds @c@ -- with an 'HsParTy' to form a parenthesized @ctxt at . Otherwise, it simply -- returns @ctxt@ unchanged. -parenthesizeHsContext :: PprPrec - -> LHsContext (GhcPass p) -> LHsContext (GhcPass p) +parenthesizeHsContext :: IsPass p => PprPrec -> LHsContext (GhcPass p) -> LHsContext (GhcPass p) parenthesizeHsContext p lctxt@(L loc ctxt) = case ctxt of [c] -> L loc [parenthesizeHsType p c] ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -444,7 +444,6 @@ con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn) con_arg_docs n = IM.fromList . catMaybes . zipWith f [n..] where f n (HsDocTy _ _ lds) = Just (n, unLoc lds) - f n (HsBangTy _ _ (L _ (HsDocTy _ _ lds))) = Just (n, unLoc lds) f _ _ = Nothing isValD :: HsDecl a -> Bool ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1943,12 +1943,6 @@ instance ToHie (LocatedA (HsType GhcRn)) where [ toHie a , toHie doc ] - HsBangTy _ _ ty -> - [ toHie ty - ] - HsRecTy _ fields -> - [ toHie fields - ] HsExplicitListTy _ _ tys -> [ toHie tys ] ===================================== compiler/GHC/Parser.y ===================================== @@ -2324,7 +2324,7 @@ atype :: { LHsType GhcPs } | PREFIX_TILDE atype {% amsA' (sLL $1 $> (mkBangTy (glR $1) SrcLazy $2)) } | PREFIX_BANG atype {% amsA' (sLL $1 $> (mkBangTy (glR $1) SrcStrict $2)) } - | '{' fielddecls '}' {% do { decls <- amsA' (sLL $1 $> $ HsRecTy (AnnList (listAsAnchorM $2) (ListBraces (epTok $1) (epTok $3)) [] noAnn []) $2) + | '{' fielddecls '}' {% do { decls <- amsA' (sLL $1 $> $ XHsType $ HsRecTy (AnnList (listAsAnchorM $2) (ListBraces (epTok $1) (epTok $3)) [] noAnn []) $2) ; checkRecordSyntax decls }} -- Constructor sigs only ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -805,7 +805,7 @@ mkGadtDecl loc names dcol ty = do (args, res_ty, (ops, cps), csa) <- case body_ty of - L ll (HsFunTy _ hsArr (L (EpAnn anc _ cs) (HsRecTy an rf)) res_ty) -> do + L ll (HsFunTy _ hsArr (L (EpAnn anc _ cs) (XHsType (HsRecTy an rf))) res_ty) -> do arr <- case hsArr of HsUnrestrictedArrow arr -> return arr _ -> do addError $ mkPlainErrorMsgEnvelope (getLocA body_ty) $ @@ -1537,8 +1537,8 @@ instance Outputable (ArgPatBuilder GhcPs) where ppr (ArgPatBuilderArgPat p) = ppr p mkBangTy :: EpaLocation -> SrcStrictness -> LHsType GhcPs -> HsType GhcPs -mkBangTy tok_loc strictness = - HsBangTy ((noAnn, noAnn, tok_loc), NoSourceText) (HsBang NoSrcUnpack strictness) +mkBangTy tok_loc strictness lty = + XHsType (HsBangTy ((noAnn, noAnn, tok_loc), NoSourceText) (HsBang NoSrcUnpack strictness) lty) -- | Result of parsing @{-\# UNPACK \#-}@ or @{-\# NOUNPACK \#-}@. data UnpackednessPragma = @@ -1555,11 +1555,11 @@ addUnpackednessP (L lprag (UnpackednessPragma anns prag unpk)) ty = do -- such as ~T or !T, then add the pragma to the existing HsBangTy. -- -- Otherwise, wrap the type in a new HsBangTy constructor. - addUnpackedness (o,c) (L _ (HsBangTy ((_,_,tl), NoSourceText) bang t)) + addUnpackedness (o,c) (L _ (XHsType (HsBangTy ((_,_,tl), NoSourceText) bang t))) | HsBang NoSrcUnpack strictness <- bang - = HsBangTy ((o,c,tl), prag) (HsBang unpk strictness) t + = XHsType (HsBangTy ((o,c,tl), prag) (HsBang unpk strictness) t) addUnpackedness (o,c) t - = HsBangTy ((o,c,noAnn), prag) (HsBang unpk NoSrcStrict) t + = XHsType (HsBangTy ((o,c,noAnn), prag) (HsBang unpk NoSrcStrict) t) --------------------------------------------------------------------------- -- | Check for monad comprehensions @@ -2333,7 +2333,7 @@ dataConBuilderDetails :: LocatedA DataConBuilder -> HsConDeclH98Details GhcPs -- Detect when the record syntax is used: -- data T = MkT { ... } dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) - | [L (EpAnn anc _ cs) (HsRecTy an fields)] <- toList flds + | [L (EpAnn anc _ cs) (XHsType (HsRecTy an fields))] <- toList flds = RecCon (L (EpAnn anc an cs) fields) -- Normal prefix constructor, e.g. data T = MkT A B C @@ -2369,7 +2369,7 @@ instance DisambTD DataConBuilder where return $ L (addCommentsToEpAnn l cs) (InfixDataConBuilder lhs data_con rhs) where l = combineLocsA lhs rhs - check_no_ops (HsBangTy _ _ t) = check_no_ops (unLoc t) + check_no_ops (XHsType (HsBangTy _ _ t)) = check_no_ops (unLoc t) check_no_ops (HsOpTy{}) = addError $ mkPlainErrorMsgEnvelope (locA l) $ (PsErrInvalidInfixDataCon (unLoc lhs) (unLoc tc) (unLoc rhs)) ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -571,31 +571,6 @@ rnHsTyKi env (HsParTy _ ty) = do { (ty', fvs) <- rnLHsTyKi env ty ; return (HsParTy noAnn ty', fvs) } -rnHsTyKi env (HsBangTy x b ty) - = do { (ty', fvs) <- rnLHsTyKi env ty - ; return (HsBangTy x b ty', fvs) } - -rnHsTyKi env ty@(HsRecTy _ flds) - = do { let ctxt = rtke_ctxt env - ; fls <- get_fields ctxt - ; (flds', fvs) <- rnConDeclFields ctxt fls flds - ; return (HsRecTy noExtField flds', fvs) } - where - get_fields ctxt@(ConDeclCtx names) - = do res <- concatMapM (lookupConstructorFields . unLoc) names - if equalLength res names - -- Lookup can fail when the record syntax is incorrect, e.g. - -- data D = D Int { fld :: Bool }. See T7943. - then return res - else err ctxt - get_fields ctxt = err ctxt - - err ctxt = - do { addErr $ - TcRnWithHsDocContext ctxt $ - TcRnIllegalRecordSyntax (Left ty) - ; return [] } - rnHsTyKi env (HsFunTy u mult ty1 ty2) = do { (ty1', fvs1) <- rnLHsTyKi env ty1 ; (ty2', fvs2) <- rnLHsTyKi env ty2 @@ -666,7 +641,7 @@ rnHsTyKi env (HsDocTy x ty haddock_doc) ; return (HsDocTy x ty' haddock_doc', fvs) } -- See Note [Renaming HsCoreTys] -rnHsTyKi env (XHsType ty) +rnHsTyKi env (XHsType (HsCoreTy ty)) = do mapM_ (check_in_scope . nameRdrName) fvs_list return (XHsType ty, fvs) where @@ -681,6 +656,23 @@ rnHsTyKi env (XHsType ty) TcRnWithHsDocContext (rtke_ctxt env) $ TcRnNotInScope (notInScopeErr WL_LocalOnly rdr_name) rdr_name [] [] +rnHsTyKi env ty@(XHsType (HsBangTy _ bang (L _ inner))) = do + -- While top-level bangs at this point are eliminated (eg !(Maybe Int)), + -- other kinds of bangs are not (eg ((!Maybe) Int)). These kinds of + -- bangs are invalid, so fail. (#7210, #14761) + addErr $ + TcRnWithHsDocContext (rtke_ctxt env) $ + TcRnUnexpectedAnnotation ty bang + rnHsTyKi env inner + +rnHsTyKi env ty@(XHsType (HsRecTy {})) = do + -- Record types (which only show up temporarily in constructor + -- signatures) should have been removed by now + addErr $ + TcRnWithHsDocContext (rtke_ctxt env) $ + TcRnIllegalRecordSyntax ty + return (HsWildCardTy noExtField, emptyFVs) -- trick to avoid `failWithTc` + rnHsTyKi env ty@(HsExplicitListTy _ ip tys) = do { checkDataKinds env ty ; (tys', fvs) <- mapFvRn (rnLHsTyKi env) tys @@ -2066,10 +2058,6 @@ extract_lty :: LHsType GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lty (L _ ty) acc = case ty of HsTyVar _ _ ltv -> extract_tv ltv acc - HsBangTy _ _ ty -> extract_lty ty acc - HsRecTy _ flds -> foldr (extract_scaled_lty - . cd_fld_spec . unLoc) acc - flds HsAppTy _ ty1 ty2 -> extract_lty ty1 $ extract_lty ty2 acc HsAppKindTy _ ty k -> extract_lty ty $ ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -1383,21 +1383,6 @@ rn_ty_pat (HsSpliceTy _ splice) = do | hsTypeNeedsParens maxPrec hs_ty = L loc (HsParTy noAnn lhs_ty) | otherwise = lhs_ty -rn_ty_pat (HsBangTy an bang_src lty) = do - ctxt <- askDocContext - lty'@(L _ ty') <- rn_lty_pat lty - liftRn $ addErr $ - TcRnWithHsDocContext ctxt $ - TcRnUnexpectedAnnotation ty' bang_src - pure (HsBangTy an bang_src lty') - -rn_ty_pat ty at HsRecTy{} = do - ctxt <- askDocContext - liftRn $ addErr $ - TcRnWithHsDocContext ctxt $ - TcRnIllegalRecordSyntax (Left ty) - pure (HsWildCardTy noExtField) -- trick to avoid `failWithTc` - rn_ty_pat ty@(XHsType{}) = do ctxt <- askDocContext liftRnFV $ rnHsType ctxt ty ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -2127,7 +2127,7 @@ nlHsAppType e s = noLocA (HsAppType noAnn e hs_ty) hs_ty = mkHsWildCardBndrs $ parenthesizeHsType appPrec $ nlHsCoreTy s nlHsCoreTy :: HsCoreTy -> LHsType GhcPs -nlHsCoreTy = noLocA . XHsType +nlHsCoreTy = noLocA . XHsType . HsCoreTy mkCoerceClassMethEqn :: Class -- the class being derived -> [TyVar] -- the tvs in the instance head (this includes @@ -2244,10 +2244,10 @@ genAuxBindSpecSig :: SrcSpan -> AuxBindSpec -> LHsSigWcType GhcPs genAuxBindSpecSig loc spec = case spec of DerivTag2Con tycon _ -> mk_sig $ L (noAnnSrcSpan loc) $ - XHsType $ mkSpecForAllTys (tyConTyVars tycon) $ + XHsType $ HsCoreTy $ mkSpecForAllTys (tyConTyVars tycon) $ intTy `mkVisFunTyMany` mkParentType tycon DerivMaxTag _ _ - -> mk_sig (L (noAnnSrcSpan loc) (XHsType intTy)) + -> mk_sig (L (noAnnSrcSpan loc) (XHsType (HsCoreTy intTy))) DerivDataDataType _ _ _ -> mk_sig (nlHsTyVar NotPromoted dataType_RDR) DerivDataConstr _ _ _ ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1005,9 +1005,9 @@ instance Diagnostic TcRnMessage where HsBang _ _ -> "strictness" in text "Unexpected" <+> text err <+> text "annotation:" <+> ppr ty $$ text err <+> text "annotation cannot appear nested inside a type" - TcRnIllegalRecordSyntax either_ty_ty + TcRnIllegalRecordSyntax ty -> mkSimpleDecorated $ - text "Record syntax is illegal here:" <+> either ppr ppr either_ty_ty + text "Record syntax is illegal here:" <+> ppr ty TcRnInvalidVisibleKindArgument arg ty -> mkSimpleDecorated $ ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -2261,7 +2261,7 @@ data TcRnMessage where typecheck/should_fail/T7210 rename/should_fail/T22478b -} - TcRnUnexpectedAnnotation :: !(HsType GhcRn) -> !HsBang -> TcRnMessage + TcRnUnexpectedAnnotation :: !(HsType GhcPs) -> !HsBang -> TcRnMessage {-| TcRnIllegalRecordSyntax is an error indicating an illegal use of record syntax. @@ -2272,7 +2272,7 @@ data TcRnMessage where rename/should_fail/T9077 rename/should_fail/T22478b -} - TcRnIllegalRecordSyntax :: Either (HsType GhcPs) (HsType GhcRn) -> TcRnMessage + TcRnIllegalRecordSyntax :: HsType GhcPs -> TcRnMessage {-| TcRnInvalidVisibleKindArgument is an error for a kind application on a target type that cannot accept it. ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -1098,15 +1098,6 @@ tcHsType :: TcTyMode -> HsType GhcRn -> ExpKind -> TcM TcType tcHsType mode (HsParTy _ ty) exp_kind = tcLHsType mode ty exp_kind tcHsType mode (HsDocTy _ ty _) exp_kind = tcLHsType mode ty exp_kind -tcHsType _ ty@(HsBangTy _ bang _) _ - -- While top-level bangs at this point are eliminated (eg !(Maybe Int)), - -- other kinds of bangs are not (eg ((!Maybe) Int)). These kinds of - -- bangs are invalid, so fail. (#7210, #14761) - = failWith $ TcRnUnexpectedAnnotation ty bang -tcHsType _ ty@(HsRecTy {}) _ - -- Record types (which only show up temporarily in constructor - -- signatures) should have been removed by now - = failWithTc $ TcRnIllegalRecordSyntax (Right ty) -- HsSpliced is an annotation produced by 'GHC.Rename.Splice.rnSpliceType'. -- Here we get rid of it and add the finalizers to the global environment ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -282,8 +282,6 @@ no_anon_wc_ty lty = go lty HsIParamTy _ _ ty -> go ty HsKindSig _ ty kind -> go ty && go kind HsDocTy _ ty _ -> go ty - HsBangTy _ _ ty -> go ty - HsRecTy _ flds -> gos $ concatMap (hsConFieldSpecToHsTypes . cd_fld_spec . unLoc) flds HsExplicitListTy _ _ tys -> gos tys HsExplicitTupleTy _ _ tys -> gos tys HsForAllTy { hst_tele = tele ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1802,7 +1802,7 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc kcConArgTys :: NewOrData -> TcKind -> [HsConFieldSpec on GhcRn] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext ty exp_kind tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -3927,7 +3927,7 @@ tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatype -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (CFS (_, src) unp str w bty) = do { traceTc "tcConArg 1" (ppr bty) - ; arg_ty <- tcCheckLHsTypeInContext (getBangType bty) exp_kind + ; arg_ty <- tcCheckLHsTypeInContext bty exp_kind ; w' <- tcDataConMult w ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, HsSrcBang src (HsBang unp str)) } ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -909,12 +909,6 @@ data HsType pass | HsDocTy (XDocTy pass) (LHsType pass) (LHsDoc pass) -- A documented type - | HsBangTy (XBangTy pass) -- Contains the SourceText in GHC passes. - HsBang (LHsType pass) -- Bang-style type annotations - - | HsRecTy (XRecTy pass) - [LConDeclField pass] -- Only in data type declarations - | HsExplicitListTy -- A promoted explicit list (XExplicitListTy pass) PromotionFlag -- whether explicitly promoted, for pretty printer ===================================== testsuite/tests/rename/should_fail/T22478b.stderr ===================================== @@ -5,7 +5,7 @@ T22478b.hs:16:14: error: [GHC-10498] • In an equation for ‘fOutOfOrder’ T22478b.hs:18:10: error: [GHC-18932] - • Unexpected strictness annotation: Int + • Unexpected strictness annotation: !Int strictness annotation cannot appear nested inside a type • In a type argument in a pattern ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4041,22 +4041,6 @@ instance ExactPrint (HsType GhcPs) where exact (HsDocTy an ty doc) = do ty' <- markAnnotated ty return (HsDocTy an ty' doc) - exact (HsBangTy ((o,c,tk), mt) (HsBang up str) ty) = do - (o',c') <- - case mt of - NoSourceText -> return (o,c) - SourceText src -> do - debugM $ "HsBangTy: src=" ++ showAst src - o' <- printStringAtAA o (unpackFS src) - c' <- markEpToken c - return (o',c') - tk' <- - case str of - SrcLazy -> printStringAtAA tk "~" - SrcStrict -> printStringAtAA tk "!" - NoSrcStrict -> return tk - ty' <- markAnnotated ty - return (HsBangTy ((o',c',tk'), mt) (HsBang up str) ty') exact (HsExplicitListTy (sq,o,c) prom tys) = do sq' <- if (isPromoted prom) then markEpToken sq ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs ===================================== @@ -98,7 +98,6 @@ dropHsDocTy = drop_sig_ty drop_ty (HsForAllTy x a e) = HsForAllTy x a (drop_lty e) drop_ty (HsQualTy x a e) = HsQualTy x a (drop_lty e) - drop_ty (HsBangTy x a b) = HsBangTy x a (drop_lty b) drop_ty (HsAppTy x a b) = HsAppTy x (drop_lty a) (drop_lty b) drop_ty (HsAppKindTy x a b) = HsAppKindTy x (drop_lty a) (drop_lty b) drop_ty (HsFunTy x w a b) = HsFunTy x w (drop_lty a) (drop_lty b) ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -597,7 +597,7 @@ ppSubSigLike unicode typ argDocs subdocs leader = do_sig_args 0 leader typ , decltt (ppLContextNoArrow lctxt unicode) <+> nl ) : do_largs n (darrow unicode) ltype - do_args n leader (HsFunTy _ _w (L _ (HsRecTy _ fields)) r) = + do_args n leader (HsFunTy _ _w (L _ (XHsType (HsRecTy _ fields))) r) = [ (decltt ldr, latex <+> nl) | (L _ field, ldr) <- zip fields (leader <+> gadtOpen : repeat gadtComma) , let latex = ppSideBySideField subdocs unicode field @@ -1320,7 +1320,6 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u = HsLinearAnn _ -> lollipop u HsUnannotated _ _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u <+> arrow u -ppr_mono_ty (HsBangTy _ b ty) u = ppBang b <> ppLParendType u ty ppr_mono_ty (HsTyVar _ NotPromoted (L _ name)) _ = ppDocName name ppr_mono_ty (HsTyVar _ IsPromoted (L _ name)) _ = char '\'' <> ppDocName name ppr_mono_ty (HsTupleTy _ con tys) u = tupleParens con (map (ppLType u) tys) @@ -1329,8 +1328,9 @@ ppr_mono_ty (HsKindSig _ ty kind) u = parens (ppr_mono_lty ty u <+> dcolon u <+> ppr_mono_ty (HsListTy _ ty) u = brackets (ppr_mono_lty ty u) ppr_mono_ty (HsIParamTy _ (L _ n) ty) u = ppIPName n <+> dcolon u <+> ppr_mono_lty ty u ppr_mono_ty (HsSpliceTy v _) _ = dataConCantHappen v -ppr_mono_ty (HsRecTy{}) _ = text "{..}" -ppr_mono_ty (XHsType{}) _ = error "ppr_mono_ty HsCoreTy" +ppr_mono_ty (XHsType (HsBangTy _ b ty)) u = ppBang b <> ppLParendType u ty +ppr_mono_ty (XHsType HsRecTy{}) _ = text "{..}" +ppr_mono_ty (XHsType HsCoreTy{}) _ = error "ppr_mono_ty HsCoreTy" ppr_mono_ty (HsExplicitListTy _ IsPromoted tys) u = Pretty.quote $ brackets $ hsep $ punctuate comma $ map (ppLType u) tys ppr_mono_ty (HsExplicitListTy _ NotPromoted tys) u = brackets $ hsep $ punctuate comma $ map (ppLType u) tys ppr_mono_ty (HsExplicitTupleTy _ IsPromoted tys) u = Pretty.quote $ parenList $ map (ppLType u) tys ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -335,7 +335,7 @@ ppSubSigLike unicode qual typ argDocs subdocs sep emptyCtxts = do_sig_args 0 sep | otherwise = (leader <+> ppLContextNoArrow lctxt unicode qual emptyCtxts, Nothing, []) : do_largs n (darrow unicode) ltype - do_args n leader (HsFunTy _ _w (L _ (HsRecTy _ fields)) r) = + do_args n leader (HsFunTy _ _w (L _ (XHsType (HsRecTy _ fields))) r) = [ (ldr <+> html, mdoc, subs) | (L _ field, ldr) <- zip fields (leader <+> gadtOpen : repeat gadtComma) , let (html, mdoc, subs) = ppSideBySideField subdocs unicode qual field @@ -1808,8 +1808,6 @@ ppr_mono_ty (HsQualTy _ ctxt ty) unicode qual emptyCtxts = -- UnicodeSyntax alternatives ppr_mono_ty (HsTyVar _ _ (L _ name)) True _ _ | getOccString (getName name) == "(->)" = toHtml "(→)" -ppr_mono_ty (HsBangTy _ b ty) u q _ = - ppBang b +++ ppLParendType u q HideEmptyContexts ty ppr_mono_ty (HsTyVar _ prom (L _ name)) _ q _ | isPromoted prom = promoQuote (ppDocName q Prefix True name) | otherwise = ppDocName q Prefix True name @@ -1835,11 +1833,13 @@ ppr_mono_ty (HsListTy _ ty) u q _ = brackets (ppr_mono_lty ty u q HideEmptyConte ppr_mono_ty (HsIParamTy _ (L _ n) ty) u q _ = ppIPName n <+> dcolon u <+> ppr_mono_lty ty u q HideEmptyContexts ppr_mono_ty (HsSpliceTy v _) _ _ _ = dataConCantHappen v -ppr_mono_ty (HsRecTy{}) _ _ _ = toHtml "{..}" +ppr_mono_ty (XHsType (HsBangTy _ b ty)) u q _ = + ppBang b +++ ppLParendType u q HideEmptyContexts ty +ppr_mono_ty (XHsType (HsRecTy{})) _ _ _ = toHtml "{..}" -- Can now legally occur in ConDeclGADT, the output here is to provide a -- placeholder in the signature, which is followed by the field -- declarations. -ppr_mono_ty (XHsType{}) _ _ _ = error "ppr_mono_ty HsCoreTy" +ppr_mono_ty (XHsType HsCoreTy{}) _ _ _ = error "ppr_mono_ty HsCoreTy" ppr_mono_ty (HsExplicitListTy _ IsPromoted tys) u q _ = promoQuote $ brackets $ hsep $ punctuate comma $ map (ppLType u q HideEmptyContexts) tys ppr_mono_ty (HsExplicitListTy _ NotPromoted tys) u q _ = brackets $ hsep $ punctuate comma $ map (ppLType u q HideEmptyContexts) tys ppr_mono_ty (HsExplicitTupleTy _ IsPromoted tys) u q _ = promoQuote $ parenList $ map (ppLType u q HideEmptyContexts) tys ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -196,14 +196,14 @@ hsConFieldSpecToFunTy (hsConFieldSpecGeneralize -> cfs) tgt = noLocA (HsFunTy noAnn (cfs_multiplicity cfs) (hsConFieldSpecToHsTypeNoMult cfs) tgt) hsConFieldSpecToHsTypeNoMult - :: (XRec pass (HsType pass) ~ GenLocated e (HsType pass), HasAnnotation e, NoAnn (XBangTy pass)) + :: (XRec pass (HsType pass) ~ GenLocated e (HsType pass), HasAnnotation e, NoAnn (XBangTy pass), XXType pass ~ HsTypeGhcPsExt pass) => HsConFieldSpec on pass -> LHsType pass hsConFieldSpecToHsTypeNoMult (CFS _ unp str _ t) = case t of L l (HsDocTy x ty doc) -> L l (HsDocTy x (mkBang unp str ty) doc) _ -> mkBang unp str t where mkBang NoSrcUnpack NoSrcStrict ty = ty - mkBang u s ty = noLocA (HsBangTy noAnn (HsBang u s) ty) + mkBang u s ty = noLocA (XHsType (HsBangTy noAnn (HsBang u s) ty)) getGADTConType :: ConDecl DocNameI -> LHsSigType DocNameI -- The full type of a GADT data constructor We really only get this in @@ -234,7 +234,7 @@ getGADTConType -- tau_ty :: LHsType DocNameI tau_ty = case args of - RecConGADT _ flds -> mkFunTy (noLocA (HsRecTy noAnn (unLoc flds))) res_ty + RecConGADT _ flds -> mkFunTy (noLocA (XHsType (HsRecTy noAnn (unLoc flds)))) res_ty PrefixConGADT _ pos_args -> foldr hsConFieldSpecToFunTy res_ty pos_args mkFunTy :: LHsType DocNameI -> LHsType DocNameI -> LHsType DocNameI @@ -426,11 +426,9 @@ reparenTypePrec = go where -- Shorter name for 'reparenType' go :: Precedence -> HsType a -> HsType a - go _ (HsBangTy x b ty) = HsBangTy x b (reparenLType ty) go _ (HsTupleTy x con tys) = HsTupleTy x con (map reparenLType tys) go _ (HsSumTy x tys) = HsSumTy x (map reparenLType tys) go _ (HsListTy x ty) = HsListTy x (reparenLType ty) - go _ (HsRecTy x flds) = HsRecTy x (map (mapXRec @a reparenConDeclField) flds) go p (HsDocTy x ty d) = HsDocTy x (goL p ty) d go _ (HsExplicitListTy x p tys) = HsExplicitListTy x p (map reparenLType tys) go _ (HsExplicitTupleTy x p tys) = HsExplicitTupleTy x p (map reparenLType tys) ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Create.hs ===================================== @@ -962,12 +962,12 @@ extractPatternSyn nm t tvs cons = let args = case con of ConDeclH98{con_args = con_args'} -> case con_args' of - PrefixCon _ args' -> map hsConFieldSpecToHsTypeNoMult args' - RecCon (L _ fields) -> hsConFieldSpecToHsTypeNoMult . cd_fld_spec . unLoc <$> fields - InfixCon arg1 arg2 -> map hsConFieldSpecToHsTypeNoMult [arg1, arg2] + PrefixCon _ args' -> map cfs_type args' + RecCon (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields + InfixCon arg1 arg2 -> map cfs_type [arg1, arg2] ConDeclGADT{con_g_args = con_args'} -> case con_args' of - PrefixConGADT _ args' -> map hsConFieldSpecToHsTypeNoMult args' - RecConGADT _ (L _ fields) -> hsConFieldSpecToHsTypeNoMult . cd_fld_spec . unLoc <$> fields + PrefixConGADT _ args' -> map cfs_type args' + RecConGADT _ (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields typ = longArrow args (data_ty con) typ' = case con of ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -362,7 +362,6 @@ renameType t = case t of ltype' <- renameLType ltype return (HsQualTy{hst_xqual = noAnn, hst_ctxt = lcontext', hst_body = ltype'}) HsTyVar _ ip (L l n) -> return . HsTyVar noAnn ip . L l =<< renameName n - HsBangTy _ b ltype -> return . HsBangTy noAnn b =<< renameLType ltype HsStarTy _ isUni -> return (HsStarTy noAnn isUni) HsAppTy _ a b -> do a' <- renameLType a @@ -403,8 +402,7 @@ renameType t = case t of doc' <- renameLDocHsSyn doc return (HsDocTy noAnn ty' doc') HsTyLit _ x -> return (HsTyLit noAnn (renameTyLit x)) - HsRecTy _ a -> HsRecTy noAnn <$> mapM renameConDeclFieldField a - XHsType a -> pure (XHsType a) + XHsType a -> pure (XHsType (HsCoreTy a)) HsExplicitListTy _ a b -> HsExplicitListTy noAnn a <$> mapM renameLType b -- Special-case unary boxed tuples so that they are pretty-printed as -- `'MkSolo x`, not `'(x)` ===================================== utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs ===================================== @@ -111,8 +111,6 @@ renameType (HsIParamTy x ip lt) = HsIParamTy x ip <$> renameLType lt renameType (HsKindSig x lt lk) = HsKindSig x <$> renameLType lt <*> pure lk renameType t@(HsSpliceTy _ _) = pure t renameType (HsDocTy x lt doc) = HsDocTy x <$> renameLType lt <*> pure doc -renameType (HsBangTy x bang lt) = HsBangTy x bang <$> renameLType lt -renameType t@(HsRecTy _ _) = pure t renameType t@(XHsType _) = pure t renameType (HsExplicitListTy x ip ltys) = HsExplicitListTy x ip <$> renameLTypes ltys ===================================== utils/haddock/haddock-api/src/Haddock/Types.hs ===================================== @@ -866,7 +866,7 @@ type instance XExplicitListTy DocNameI = EpAnn NoEpAnns type instance XExplicitTupleTy DocNameI = EpAnn NoEpAnns type instance XTyLit DocNameI = EpAnn NoEpAnns type instance XWildCardTy DocNameI = EpAnn NoEpAnns -type instance XXType DocNameI = HsCoreTy +type instance XXType DocNameI = HsTypeGhcPsExt DocNameI type instance XNumTy DocNameI = NoExtField type instance XStrTy DocNameI = NoExtField View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9103745e24a3b7534a996b78b6a2ebf938c4b06d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9103745e24a3b7534a996b78b6a2ebf938c4b06d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 19:58:18 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 10 Jan 2025 14:58:18 -0500 Subject: [Git][ghc/ghc][master] user_guide: Note -pgmP/-optP are for /Haskell/-CPP Message-ID: <67817bda92945_807da618988237a8@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - 1 changed file: - docs/users_guide/phases.rst Changes: ===================================== docs/users_guide/phases.rst ===================================== @@ -25,11 +25,12 @@ given compilation phase: Use ⟨cmd⟩ as the literate pre-processor. .. ghc-flag:: -pgmP ⟨cmd⟩ - :shortdesc: Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only) + :shortdesc: Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only) :type: dynamic :category: phase-programs - Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only). + Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only). + Note that the Haskell C pre-processor only pre-processes Haskell files. .. ghc-flag:: -pgmJSP ⟨cmd⟩ :shortdesc: Use ⟨cmd⟩ as the JavaScript C pre-processor (only for javascript-backend) @@ -177,7 +178,11 @@ the following flags: :type: dynamic :category: phase-options - Pass ⟨option⟩ to CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Pass ⟨option⟩ to the Haskell CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Note that the Haskell pre-processor options only apply to pre-processing + invocations on Haskell files, and, e.g., to use different options to + pre-process Javascript or Cmm, one should use ``-optJSP``, or + ``-optCmmP``, respectively). .. ghc-flag:: -optJSP ⟨option⟩ :shortdesc: pass ⟨option⟩ to JavaScript C pre-processor (only for javascript-backend) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/023f36f516aa4bd9453903d5039cf8eec6010731 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/023f36f516aa4bd9453903d5039cf8eec6010731 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 19:58:57 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 10 Jan 2025 14:58:57 -0500 Subject: [Git][ghc/ghc][master] dump-decls: Suppress unit-ids Message-ID: <67817c01a53b9_807da7ced1827833@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 1 changed file: - utils/dump-decls/Main.hs Changes: ===================================== utils/dump-decls/Main.hs ===================================== @@ -38,6 +38,7 @@ run root pkg_nm = runGhc (Just root) $ do , "-dppr-cols=1000" , "-fprint-explicit-runtime-reps" , "-fprint-explicit-foralls" + , "-fsuppress-unit-ids" ] dflags <- do dflags <- getSessionDynFlags View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1c133f2fed2c006b1158fc2d6b33aa8b9069b2e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1c133f2fed2c006b1158fc2d6b33aa8b9069b2e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 10 20:17:37 2025 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Fri, 10 Jan 2025 15:17:37 -0500 Subject: [Git][ghc/ghc][wip/T25621] Delete validDerivPred in favor of instPredTerminates/checkInstTermination Message-ID: <678180619b99a_807da98019831754@gitlab.mail> Ryan Scott pushed to branch wip/T25621 at Glasgow Haskell Compiler / GHC Commits: 61ec9613 by Ryan Scott at 2025-01-10T08:21:43-05:00 Delete validDerivPred in favor of instPredTerminates/checkInstTermination In a previous commit, the functionality of `validDerivPred` was reduced to only check for the Paterson conditions (i.e., termination). This is something which the `checkInstTermination` function already checks for, however. As such, `validDerivPred` is redundant. This commit removes `validDerivPred`, splits out `instPredTerminates` (a pure subset of `checkInstTermination` that can more-or-less be used as a drop-in replacement for `validDerivPred`), and uses `instPredTerminates` in the places it can be used. - - - - - 4 changed files: - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Validity.hs Changes: ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -1103,8 +1103,7 @@ tyCoVarsOfTypesWellScoped = scopedSort . tyCoVarsOfTypesList It is slightly odd to find the TyCons of a type. Especially since, via a type family reduction or axiom, a type that doesn't mention T might start to mention T. -This function is used in only three places: -* In GHC.Tc.Validity.validDerivPred, when identifying "exotic" predicates. +This function is used in only two places: * In GHC.Tc.Errors.Ppr.pprTcSolverReportMsg, when trying to print a helpful error about overlapping instances * In utils/dump-decls/Main.hs, an ill-documented module. ===================================== compiler/GHC/Tc/Deriv/Infer.hs ===================================== @@ -29,7 +29,7 @@ import GHC.Tc.Utils.TcType import GHC.Tc.Solver( pickQuantifiablePreds, simplifyTopImplic ) import GHC.Tc.Solver.Solve( solveWanteds ) import GHC.Tc.Solver.Monad ( runTcS ) -import GHC.Tc.Validity (checkValidTheta, validDerivPred) +import GHC.Tc.Validity (checkValidTheta, instPredTerminates) import GHC.Tc.Utils.Unify (buildImplicationFor) import GHC.Tc.Zonk.TcType ( zonkWC ) import GHC.Tc.Zonk.Env ( ZonkFlexi(..), initZonkEnv ) @@ -820,7 +820,7 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs , ds_cls = clas, ds_tys = inst_tys, ds_theta = deriv_rhs , ds_skol_info = skol_info, ds_user_ctxt = user_ctxt }) = setSrcSpan loc $ - addErrCtxt (derivInstCtxt (mkClassPred clas inst_tys)) $ + addErrCtxt (derivInstCtxt inst_head) $ do { -- See [STEP DAC BUILD] -- Generate the implication constraints, one for each method, to solve @@ -850,8 +850,7 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs ; let residual_simple = approximateWC False solved_wanteds -- False: ignore any non-quantifiable constraints, -- including equalities hidden under Given equalities - head_size = pSizeClassPred clas inst_tys - good = mapMaybeBag get_good residual_simple + good = mapMaybeBag get_good residual_simple -- Returns @Just p@ (where @p@ is the type of the Ct) if a Ct -- satisfies the Paterson conditions (and is therefore suitable to @@ -859,8 +858,9 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs -- @Nothing@ otherwise. See Note [Valid 'deriving' predicate] -- (Wrinkle: The Paterson conditions) in GHC.Tc.Validity. get_good :: Ct -> Maybe PredType - get_good ct | validDerivPred head_size p = Just p - | otherwise = Nothing + get_good ct + | isNothing (instPredTerminates p inst_head) = Just p + | otherwise = Nothing where p = ctPred ct ; traceTc "simplifyDeriv outputs" $ @@ -902,6 +902,8 @@ simplifyDeriv (DS { ds_loc = loc, ds_tvs = tvs -- See (B3) in Note [Valid 'deriving' predicate] in GHC.Tc.Validity. ; return min_theta } + where + inst_head = mkClassPred clas inst_tys {- Note [Overlap and deriving] ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -2223,7 +2223,7 @@ expand into anything else. They are: For now we treat them as being size zero, but (#22696) I think we should actually treat them as big (like any other ype family) because we don't -want to abstract over them in e.g. validDerivPred. +want to abstract over them. The type-family termination test, in GHC.Tc.Validity.checkFamInstRhs, already has a separate call to isStuckTypeFamily, so the `F` above will still be accepted. ===================================== compiler/GHC/Tc/Validity.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Tc.Validity ( Rank(..), UserTypeCtxt(..), checkValidType, checkValidMonoType, checkValidTheta, - checkValidInstance, checkValidInstHead, validDerivPred, + checkValidInstance, checkValidInstHead, instPredTerminates, checkTySynRhs, checkEscapingKind, checkValidCoAxiom, checkValidCoAxBranch, checkFamPatBinders, checkTyFamEqnValidityInfo, @@ -1879,11 +1879,10 @@ B3. Finally, the constraints are checked by `checkValidTheta`. This step differs Also, in order to be absolutely sure that the inferred context will terminate, GHC explicitly checks that the inferred context satisfies the - Paterson conditions. This check is implemented in the `validDerivPred` + Paterson conditions. This check is implemented in the `instPredTerminates` function. (See "Wrinkle: The Paterson conditions" below for more on this.) - While `validDerivPred` is similar to other things defined in - GHC.Tc.Deriv.Infer, we define it here in GHC.Tc.Validity because it is quite - similar to `checkInstTermination`. + Note that `instPredTerminates` is the same function that powers + `checkInstTermination`. -------------------------------------- -- Wrinkle: The Paterson conditions -- @@ -1940,25 +1939,6 @@ still need to be able to write instances for them ourselves. So we allow instances only in the defining module. -} -validDerivPred :: PatersonSize -> PredType -> Bool --- See Note [Valid 'deriving' predicate] (Wrinkle: The Paterson conditions) -validDerivPred head_size pred - = case classifyPredType pred of - -- Equality constraints don't need to be checked in order to satisfy - -- the Paterson conditions, so we simply return True here. (They are - -- validity checked elsewhere in `approximateWC`, however. - -- See Note [ApproximateWC] in GHC.Tc.Types.Constraint.) - EqPred {} -> True - -- Similarly, we don't need to check quantified constraints for - -- Paterson condition purposes, so simply return True here. (It - -- doesn't really matter what we return here, since `approximateWC` - -- won't quantify over a quantified constraint anywya.) - ForAllPred {} -> True - ClassPred cls tys -> check_size (pSizeClassPred cls tys) - IrredPred {} -> check_size (pSizeType pred) - where - check_size pred_size = isNothing (pred_size `ltPatersonSize` head_size) - {- ************************************************************************ * * @@ -2108,10 +2088,39 @@ splitInstTyForValidity = split_context [] . drop_foralls | isInvisibleFunArg af = split_context (pred:preds) tau split_context preds ty = (reverse preds, ty) +-- | @'checkInstTermation' theta head_pred@ checks if the instance context +-- @theta@ satisfies the Paterson conditions (i.e., checks if it would +-- terminate) if put into an instance of the form @instance theta => head_pred at . +-- See @Note [Paterson conditions]@. If it doesn't satisfy the Paterson +-- conditions, throw an error. +-- +-- This function is like 'instPredTerminates', except that this function is +-- monadic and works over an entire instance context instead of just a single +-- instance constraint. checkInstTermination :: ThetaType -> TcPredType -> TcM () --- See Note [Paterson conditions] -checkInstTermination theta head_pred - = check_preds emptyVarSet theta +checkInstTermination theta head_pred = + let terminates :: PredType -> Maybe TcRnMessage + terminates theta_pred = instPredTerminates theta_pred head_pred + + terminationErrors :: [Maybe TcRnMessage] + terminationErrors = map terminates theta + + firstTerminationError :: Maybe TcRnMessage + firstTerminationError = asum terminationErrors in + + case firstTerminationError of + Just err -> failWithTc err + Nothing -> pure () + +-- | @'instPredTerminates' theta_pred head_pred@ checks if the instance +-- constraint @theta_pred@ satisfies the Paterson conditions (i.e., checks if it +-- would terminate) if put into an instance of the form +-- @instance theta_pred => head_pred at . See @Note [Paterson conditions]@. +-- If it does satisfy the Paterson conditions, return 'Nothing'. Otherwise, +-- return @'Just' err@, where @err@ is the reason why it does not terminate. +instPredTerminates :: PredType -> TcPredType -> Maybe TcRnMessage +instPredTerminates theta_pred head_pred + = check emptyVarSet theta_pred where head_size = pSizeType head_pred -- This is inconsistent and probably wrong. pSizeType does not filter out @@ -2121,13 +2130,13 @@ checkInstTermination theta head_pred -- for why I didn't change it. See Note [Invisible arguments and termination] -- in GHC.Tc.Utils.TcType - check_preds :: VarSet -> [PredType] -> TcM () - check_preds foralld_tvs preds = mapM_ (check foralld_tvs) preds + check_preds :: VarSet -> [PredType] -> Maybe TcRnMessage + check_preds foralld_tvs preds = asum $ map (check foralld_tvs) preds - check :: VarSet -> PredType -> TcM () + check :: VarSet -> PredType -> Maybe TcRnMessage check foralld_tvs pred = case classifyPredType pred of - EqPred {} -> return () -- See #4200. + EqPred {} -> Nothing -- See #4200. IrredPred {} -> check2 (pSizeTypeX foralld_tvs pred) ClassPred cls tys @@ -2145,8 +2154,8 @@ checkInstTermination theta head_pred where check2 pred_size = case pred_size `ltPatersonSize` head_size of - Just pc_failure -> failWithTc $ TcRnPatersonCondFailure pc_failure InInstanceDecl pred head_pred - Nothing -> return () + Just pc_failure -> Just $ TcRnPatersonCondFailure pc_failure InInstanceDecl pred head_pred + Nothing -> Nothing {- Note [Instances and constraint synonyms] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61ec961314e0438aac8dbf2e6878bc8618288925 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61ec961314e0438aac8dbf2e6878bc8618288925 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 06:49:45 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Sat, 11 Jan 2025 01:49:45 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/fix-912-bootstrap Message-ID: <6782148945b2b_1ea66c14912e446755@gitlab.mail> Cheng Shao pushed new branch wip/fix-912-bootstrap at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fix-912-bootstrap You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 06:59:22 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Sat, 11 Jan 2025 01:59:22 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/rm-ci-timings Message-ID: <678216caab429_286945c0d5056ab@gitlab.mail> Cheng Shao pushed new branch wip/rm-ci-timings at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/rm-ci-timings You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 07:50:32 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 11 Jan 2025 02:50:32 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Fix #25611. Enhances the kind inference for data family instances, Message-ID: <678222c814aeb_2869456fce6c71ca@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: d8cd9bf8 by Patrick at 2025-01-11T15:47:36+08:00 Fix #25611. Enhances the kind inference for data family instances, by including the RHS's constraints when kind-checking LHS. Type checker changes: In `tcDataFamInstHeader`, `kcConDecls` the H98-style decls and newtype decls, even those in GADT syntax, but NOT for general GADT decls. Testsuite changes: 1. The test to ensure kind specialization remains correctly handled even if we include the RHS's constrains: * T25611d 2. Infer result kind from datacon. * H98 newtype case: T25611a * H98 data case: T25611b 3. Two tests with additional errors report: * UnliftedNewtypesFamilyKindFail2 * UnliftedNewtypesInstanceFail 4. Due to better kind inference, move should_fail test UnliftedNewtypesUnassociatedFamilyFail to should_compile test T25611c. 5. Additional test to we default the kind of the data instance correctly without UnliftedNewtypes or UnliftedDatatypes: * DataInstanceKindsDefaults Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 18 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs - testsuite/tests/indexed-types/should_fail/all.T - + testsuite/tests/rep-poly/DataInstanceKindsDefaults.hs - + testsuite/tests/rep-poly/T25611a.hs - + testsuite/tests/rep-poly/T25611b.hs - + testsuite/tests/rep-poly/T25611c.hs - + testsuite/tests/rep-poly/T25611d.hs - testsuite/tests/rep-poly/all.T - + testsuite/tests/typecheck/should_compile/T25611_InstanceConKindSpecializationDataFamily.hs - + testsuite/tests/typecheck/should_compile/T25611_UnliftedNewtypesRunTypeRepPoly.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/rep-poly/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/rep-poly/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- new instance Fix2 f where In2 f (Fix2 f) :: Fix2 f ===================================== testsuite/tests/rep-poly/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/rep-poly/T25611c.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module UnliftedNewtypesUnassociatedFamily where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/rep-poly/T25611d.hs ===================================== @@ -0,0 +1,37 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -111,6 +111,11 @@ test('RepPolyWrappedVar', normal, compile_fail, ['']) test('RepPolyWrappedVar2', [js_skip], compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ############################################################################### ## The following tests require rewriting in RuntimeReps, ## ===================================== testsuite/tests/typecheck/should_compile/T25611_InstanceConKindSpecializationDataFamily.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module InstanceConKindSpecializationDataFamily where + +import GHC.Prim (Int#) + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# ===================================== testsuite/tests/typecheck/should_compile/T25611_UnliftedNewtypesRunTypeRepPoly.hs ===================================== @@ -0,0 +1,33 @@ +{-# LANGUAGE GADTSyntax #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE RankNTypes #-} + +module UnliftedNewtypesRunTypeRepPoly where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- ensure newtype[instance] can be runtime-rep-polymorphic + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -931,4 +931,4 @@ test('T23501b', normal, compile, ['']) test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) -test('T25597', normal, compile, ['']) +test('T25597', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d8cd9bf8ad9e8aeb5c8282efaf6c31377cf1c45a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d8cd9bf8ad9e8aeb5c8282efaf6c31377cf1c45a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 07:53:02 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 11 Jan 2025 02:53:02 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Fix #25611. Enhances the kind inference for data family instances, Message-ID: <6782235e2394d_2869456fcd6811159@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 3b1d373c by Patrick at 2025-01-11T15:52:42+08:00 Fix #25611. Enhances the kind inference for data family instances, by including the RHS's constraints when kind-checking LHS. Type checker changes: In `tcDataFamInstHeader`, `kcConDecls` the H98-style decls and newtype decls, even those in GADT syntax, but NOT for general GADT decls. Testsuite changes: 1. The test to ensure kind specialization remains correctly handled even if we include the RHS's constrains: * T25611d 2. Infer result kind from datacon. * H98 newtype case: T25611a * H98 data case: T25611b 3. Two tests with additional errors report: * UnliftedNewtypesFamilyKindFail2 * UnliftedNewtypesInstanceFail 4. Due to better kind inference, move should_fail test UnliftedNewtypesUnassociatedFamilyFail to should_compile test T25611c. 5. Additional test to we default the kind of the data instance correctly without UnliftedNewtypes or UnliftedDatatypes: * DataInstanceKindsDefaults Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 16 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs - testsuite/tests/indexed-types/should_fail/all.T - + testsuite/tests/rep-poly/DataInstanceKindsDefaults.hs - + testsuite/tests/rep-poly/T25611a.hs - + testsuite/tests/rep-poly/T25611b.hs - + testsuite/tests/rep-poly/T25611c.hs - + testsuite/tests/rep-poly/T25611d.hs - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/rep-poly/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/rep-poly/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- new instance Fix2 f where In2 f (Fix2 f) :: Fix2 f ===================================== testsuite/tests/rep-poly/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/rep-poly/T25611c.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module UnliftedNewtypesUnassociatedFamily where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/rep-poly/T25611d.hs ===================================== @@ -0,0 +1,37 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -111,6 +111,11 @@ test('RepPolyWrappedVar', normal, compile_fail, ['']) test('RepPolyWrappedVar2', [js_skip], compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ############################################################################### ## The following tests require rewriting in RuntimeReps, ## ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -931,4 +931,4 @@ test('T23501b', normal, compile, ['']) test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) -test('T25597', normal, compile, ['']) +test('T25597', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b1d373cc523c0bb783694f5608a5ac7dbe5b129 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3b1d373cc523c0bb783694f5608a5ac7dbe5b129 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 08:05:30 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 11 Jan 2025 03:05:30 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] 3 commits: user_guide: Note -pgmP/-optP are for /Haskell/-CPP Message-ID: <6782264acf305_2869456fcd401613b@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 56d509ab by Patrick at 2025-01-11T16:04:36+08:00 Fix #25611. Enhances the kind inference for data family instances, by including the RHS's constraints when kind-checking LHS. Type checker changes: In `tcDataFamInstHeader`, `kcConDecls` the H98-style decls and newtype decls, even those in GADT syntax, but NOT for general GADT decls. Testsuite changes: 1. The test to ensure kind specialization remains correctly handled even if we include the RHS's constrains: * T25611d 2. Infer result kind from datacon. * H98 newtype case: T25611a * H98 data case: T25611b 3. Two tests with additional errors report: * UnliftedNewtypesFamilyKindFail2 * UnliftedNewtypesInstanceFail 4. Due to better kind inference, move should_fail test UnliftedNewtypesUnassociatedFamilyFail to should_compile test T25611c. 5. Additional test to we default the kind of the data instance correctly without UnliftedNewtypes or UnliftedDatatypes: * DataInstanceKindsDefaults Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 18 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - docs/users_guide/phases.rst - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs - testsuite/tests/indexed-types/should_fail/all.T - + testsuite/tests/rep-poly/DataInstanceKindsDefaults.hs - + testsuite/tests/rep-poly/T25611a.hs - + testsuite/tests/rep-poly/T25611b.hs - + testsuite/tests/rep-poly/T25611c.hs - + testsuite/tests/rep-poly/T25611d.hs - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T - utils/dump-decls/Main.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== docs/users_guide/phases.rst ===================================== @@ -25,11 +25,12 @@ given compilation phase: Use ⟨cmd⟩ as the literate pre-processor. .. ghc-flag:: -pgmP ⟨cmd⟩ - :shortdesc: Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only) + :shortdesc: Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only) :type: dynamic :category: phase-programs - Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only). + Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only). + Note that the Haskell C pre-processor only pre-processes Haskell files. .. ghc-flag:: -pgmJSP ⟨cmd⟩ :shortdesc: Use ⟨cmd⟩ as the JavaScript C pre-processor (only for javascript-backend) @@ -177,7 +178,11 @@ the following flags: :type: dynamic :category: phase-options - Pass ⟨option⟩ to CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Pass ⟨option⟩ to the Haskell CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Note that the Haskell pre-processor options only apply to pre-processing + invocations on Haskell files, and, e.g., to use different options to + pre-process Javascript or Cmm, one should use ``-optJSP``, or + ``-optCmmP``, respectively). .. ghc-flag:: -optJSP ⟨option⟩ :shortdesc: pass ⟨option⟩ to JavaScript C pre-processor (only for javascript-backend) ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/rep-poly/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/rep-poly/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/rep-poly/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/rep-poly/T25611c.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module UnliftedNewtypesUnassociatedFamily where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/rep-poly/T25611d.hs ===================================== @@ -0,0 +1,37 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -111,6 +111,11 @@ test('RepPolyWrappedVar', normal, compile_fail, ['']) test('RepPolyWrappedVar2', [js_skip], compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ############################################################################### ## The following tests require rewriting in RuntimeReps, ## ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -931,4 +931,4 @@ test('T23501b', normal, compile, ['']) test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) -test('T25597', normal, compile, ['']) +test('T25597', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) ===================================== utils/dump-decls/Main.hs ===================================== @@ -38,6 +38,7 @@ run root pkg_nm = runGhc (Just root) $ do , "-dppr-cols=1000" , "-fprint-explicit-runtime-reps" , "-fprint-explicit-foralls" + , "-fsuppress-unit-ids" ] dflags <- do dflags <- getSessionDynFlags View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3b1d373cc523c0bb783694f5608a5ac7dbe5b129...56d509abfcd167daed1dbaf4c66766e09b417a8c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3b1d373cc523c0bb783694f5608a5ac7dbe5b129...56d509abfcd167daed1dbaf4c66766e09b417a8c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 10:45:31 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 11 Jan 2025 05:45:31 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Fix #25611. Enhances the kind inference for data family instances, Message-ID: <67824bcb422a0_3998f821a32c152ec@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 0fc37ff6 by Patrick at 2025-01-11T18:44:47+08:00 Fix #25611. Enhances the kind inference for data family instances, by including the RHS's constraints when kind-checking LHS. Type checker changes: In `tcDataFamInstHeader`, `kcConDecls` the H98-style decls and newtype decls, even those in GADT syntax, but NOT for general GADT decls. Testsuite changes: 1. The test to ensure kind specialization remains correctly handled even if we include the RHS's constrains: * T25611d 2. Infer result kind from datacon. * H98 newtype case: T25611a * H98 data case: T25611b 3. Two tests with additional errors report: * UnliftedNewtypesFamilyKindFail2 * UnliftedNewtypesInstanceFail 4. Due to better kind inference, move should_fail test UnliftedNewtypesUnassociatedFamilyFail to should_compile test T25611c. 5. Additional test to we default the kind of the data instance correctly without UnliftedNewtypes or UnliftedDatatypes: * DataInstanceKindsDefaults Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 16 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs - testsuite/tests/indexed-types/should_fail/all.T - + testsuite/tests/rep-poly/DataInstanceKindsDefaults.hs - + testsuite/tests/rep-poly/T25611a.hs - + testsuite/tests/rep-poly/T25611b.hs - + testsuite/tests/rep-poly/T25611c.hs - + testsuite/tests/rep-poly/T25611d.hs - testsuite/tests/rep-poly/all.T - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/rep-poly/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/rep-poly/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/rep-poly/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/rep-poly/T25611c.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module UnliftedNewtypesUnassociatedFamily where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/rep-poly/T25611d.hs ===================================== @@ -0,0 +1,38 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/rep-poly/all.T ===================================== @@ -111,6 +111,11 @@ test('RepPolyWrappedVar', normal, compile_fail, ['']) test('RepPolyWrappedVar2', [js_skip], compile, ['']) test('UnliftedNewtypesCoerceFail', normal, compile_fail, ['']) test('UnliftedNewtypesLevityBinder', normal, compile_fail, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ############################################################################### ## The following tests require rewriting in RuntimeReps, ## ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -931,4 +931,4 @@ test('T23501b', normal, compile, ['']) test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) -test('T25597', normal, compile, ['']) +test('T25597', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0fc37ff6b8d502d5001f44b2619cc32d36c75984 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0fc37ff6b8d502d5001f44b2619cc32d36c75984 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 11:58:57 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Sat, 11 Jan 2025 06:58:57 -0500 Subject: [Git][ghc/ghc][wip/T18462] 2 commits: Restrict XBangTy and XRectTy to GhcPs phase Message-ID: <67825d01140d_3c4d14a5efb081155@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 20d3b00a by Sjoerd Visscher at 2025-01-11T12:58:07+01:00 Restrict XBangTy and XRectTy to GhcPs phase - - - - - 0a19e6ac by Sjoerd Visscher at 2025-01-11T12:58:31+01:00 Showing error message regressions - - - - - 28 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/TyCl.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/parser/should_fail/T3811c.stderr - testsuite/tests/parser/should_fail/unpack_inside_type.stderr - testsuite/tests/rename/should_fail/T22478b.stderr - testsuite/tests/typecheck/should_fail/T7210.stderr - utils/check-exact/ExactPrint.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/GhcUtils.hs - utils/haddock/haddock-api/src/Haddock/Interface/Create.hs - utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs - utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs - utils/haddock/haddock-api/src/Haddock/Types.hs Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -530,6 +530,8 @@ deriving instance Data (HsType GhcPs) deriving instance Data (HsType GhcRn) deriving instance Data (HsType GhcTc) +deriving instance Data (HsTypeGhcPsExt GhcPs) + -- deriving instance (DataIdLR p p) => Data (HsTyLit p) deriving instance Data (HsTyLit GhcPs) deriving instance Data (HsTyLit GhcRn) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -32,6 +32,7 @@ module GHC.Hs.Type ( pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, + HsTypeGhcPsExt(..), HsForAllTelescope(..), EpAnnForallVis, EpAnnForallInvis, HsTyVarBndr(..), LHsTyVarBndr, AnnTyVarBndr(..), HsBndrKind(..), @@ -55,7 +56,6 @@ module GHC.Hs.Type ( LBangType, BangType, HsSrcBang(..), HsImplBang(..), SrcStrictness(..), SrcUnpackedness(..), - getBangType, getBangStrictness, ConDeclField(..), LConDeclField, pprConDeclFields, @@ -108,7 +108,6 @@ import {-# SOURCE #-} GHC.Hs.Expr ( pprUntypedSplice, HsUntypedSpliceResult(..) import Language.Haskell.Syntax.Extension import GHC.Core.DataCon ( SrcStrictness(..), SrcUnpackedness(..) , HsSrcBang(..), HsImplBang(..) - , mkHsSrcBang ) import GHC.Hs.Extension import GHC.Parser.Annotation @@ -136,25 +135,6 @@ import Data.Data (Data) import qualified Data.Semigroup as S import GHC.Data.Bag -{- -************************************************************************ -* * -\subsection{Bang annotations} -* * -************************************************************************ --} - -getBangType :: LHsType (GhcPass p) -> LHsType (GhcPass p) -getBangType (L _ (HsBangTy _ _ lty)) = lty -getBangType (L _ (HsDocTy x (L _ (HsBangTy _ _ lty)) lds)) = - addCLocA lty lds (HsDocTy x lty lds) -getBangType lty = lty - -getBangStrictness :: LHsType (GhcPass p) -> HsSrcBang -getBangStrictness (L _ (HsBangTy (_, s) b _)) = HsSrcBang s b -getBangStrictness (L _ (HsDocTy _ (L _ (HsBangTy (_, s) b _)) _)) = HsSrcBang s b -getBangStrictness _ = (mkHsSrcBang NoSourceText NoSrcUnpack NoSrcStrict) - {- ************************************************************************ * * @@ -504,7 +484,9 @@ type instance XWildCardTy GhcPs = EpToken "_" type instance XWildCardTy GhcRn = NoExtField type instance XWildCardTy GhcTc = NoExtField -type instance XXType (GhcPass _) = HsCoreTy +type instance XXType GhcPs = HsTypeGhcPsExt GhcPs +type instance XXType GhcRn = HsCoreTy +type instance XXType GhcTc = DataConCantHappen -- An escape hatch for tunnelling a Core 'Type' through 'HsType'. -- For more details on how this works, see: @@ -519,6 +501,15 @@ type instance XStrTy (GhcPass _) = SourceText type instance XCharTy (GhcPass _) = SourceText type instance XXTyLit (GhcPass _) = DataConCantHappen +data HsTypeGhcPsExt pass + = HsCoreTy HsCoreTy + + | HsBangTy (XBangTy pass) -- Contains the SourceText in GHC passes. + HsBang (LHsType pass) -- Bang-style type annotations + + | HsRecTy (XRecTy pass) + [LConDeclField pass] -- Only in data type declarations + data EpLinearArrow = EpPct1 !(EpToken "%1") !(TokRarrow) | EpLolly !(EpToken "⊸") @@ -1311,7 +1302,7 @@ hsPlainTypeField = mkConFieldSpec (HsLinearAnn noAnn) mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs mkConFieldSpec mult (L l (HsDocTy x ty lds)) = case mkConFieldSpec mult ty of CFS ann unp str mult' t -> CFS ann unp str mult' (L l (HsDocTy x t lds)) -mkConFieldSpec mult (L _ (HsBangTy ann (HsBang unp str) t)) = CFS ann unp str mult t +mkConFieldSpec mult (L _ (XHsType (HsBangTy ann (HsBang unp str) t))) = CFS ann unp str mult t mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t instance Outputable (XRecGhc (IdGhcP p)) => @@ -1410,8 +1401,6 @@ ppr_mono_ty (HsForAllTy { hst_tele = tele, hst_body = ty }) ppr_mono_ty (HsQualTy { hst_ctxt = ctxt, hst_body = ty }) = sep [pprLHsContextAlways ctxt, ppr_mono_lty ty] -ppr_mono_ty (HsBangTy _ b ty) = ppr b <> ppr_mono_lty ty -ppr_mono_ty (HsRecTy _ flds) = pprConDeclFields flds ppr_mono_ty (HsTyVar _ prom (L _ name)) = pprOccWithTick Prefix prom name ppr_mono_ty (HsFunTy _ mult ty1 ty2) = ppr_fun_ty mult ty1 ty2 ppr_mono_ty (HsTupleTy _ con tys) @@ -1468,7 +1457,12 @@ ppr_mono_ty (HsParTy _ ty) ppr_mono_ty (HsDocTy _ ty doc) = pprWithDoc doc $ ppr_mono_lty ty -ppr_mono_ty (XHsType t) = ppr t +ppr_mono_ty (XHsType t) = case ghcPass @p of + GhcPs -> case t of + HsCoreTy ty -> ppr ty + HsBangTy _ b ty -> ppr b <> ppr_mono_lty ty + HsRecTy _ flds -> pprConDeclFields flds + GhcRn -> ppr t -------------------------- ppr_fun_ty :: (OutputableBndrId p) @@ -1487,13 +1481,11 @@ quote_tuple NotPromoted doc = doc -------------------------- -- | @'hsTypeNeedsParens' p t@ returns 'True' if the type @t@ needs parentheses -- under precedence @p at . -hsTypeNeedsParens :: PprPrec -> HsType (GhcPass p) -> Bool +hsTypeNeedsParens :: forall p. IsPass p => PprPrec -> HsType (GhcPass p) -> Bool hsTypeNeedsParens p = go_hs_ty where go_hs_ty (HsForAllTy{}) = p >= funPrec go_hs_ty (HsQualTy{}) = p >= funPrec - go_hs_ty (HsBangTy{}) = p > topPrec - go_hs_ty (HsRecTy{}) = False go_hs_ty (HsTyVar{}) = False go_hs_ty (HsFunTy{}) = p >= funPrec -- Special-case unary boxed tuple applications so that they are @@ -1524,7 +1516,12 @@ hsTypeNeedsParens p = go_hs_ty go_hs_ty (HsOpTy{}) = p >= opPrec go_hs_ty (HsParTy{}) = False go_hs_ty (HsDocTy _ (L _ t) _) = go_hs_ty t - go_hs_ty (XHsType ty) = go_core_ty ty + go_hs_ty (XHsType t) = case ghcPass @p of + GhcPs -> case t of + HsCoreTy ty -> go_core_ty ty + HsBangTy{} -> p > topPrec + HsRecTy{} -> False + GhcRn -> go_core_ty t go_core_ty (TyVarTy{}) = False go_core_ty (AppTy{}) = p >= appPrec @@ -1556,8 +1553,6 @@ lhsTypeHasLeadingPromotionQuote ty go (HsQualTy{ hst_ctxt = ctxt, hst_body = body}) | (L _ (c:_)) <- ctxt = goL c | otherwise = goL body - go (HsBangTy{}) = False - go (HsRecTy{}) = False go (HsTyVar _ p _) = isPromoted p go (HsFunTy _ _ arg _) = goL arg go (HsListTy{}) = False @@ -1581,7 +1576,7 @@ lhsTypeHasLeadingPromotionQuote ty -- | @'parenthesizeHsType' p ty@ checks if @'hsTypeNeedsParens' p ty@ is -- true, and if so, surrounds @ty@ with an 'HsParTy'. Otherwise, it simply -- returns @ty at . -parenthesizeHsType :: PprPrec -> LHsType (GhcPass p) -> LHsType (GhcPass p) +parenthesizeHsType :: IsPass p => PprPrec -> LHsType (GhcPass p) -> LHsType (GhcPass p) parenthesizeHsType p lty@(L loc ty) | hsTypeNeedsParens p ty = L loc (HsParTy noAnn lty) | otherwise = lty @@ -1590,8 +1585,7 @@ parenthesizeHsType p lty@(L loc ty) -- @c@ such that @'hsTypeNeedsParens' p c@ is true, and if so, surrounds @c@ -- with an 'HsParTy' to form a parenthesized @ctxt at . Otherwise, it simply -- returns @ctxt@ unchanged. -parenthesizeHsContext :: PprPrec - -> LHsContext (GhcPass p) -> LHsContext (GhcPass p) +parenthesizeHsContext :: IsPass p => PprPrec -> LHsContext (GhcPass p) -> LHsContext (GhcPass p) parenthesizeHsContext p lctxt@(L loc ctxt) = case ctxt of [c] -> L loc [parenthesizeHsType p c] ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -444,7 +444,6 @@ con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn) con_arg_docs n = IM.fromList . catMaybes . zipWith f [n..] where f n (HsDocTy _ _ lds) = Just (n, unLoc lds) - f n (HsBangTy _ _ (L _ (HsDocTy _ _ lds))) = Just (n, unLoc lds) f _ _ = Nothing isValD :: HsDecl a -> Bool ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1943,12 +1943,6 @@ instance ToHie (LocatedA (HsType GhcRn)) where [ toHie a , toHie doc ] - HsBangTy _ _ ty -> - [ toHie ty - ] - HsRecTy _ fields -> - [ toHie fields - ] HsExplicitListTy _ _ tys -> [ toHie tys ] ===================================== compiler/GHC/Parser.y ===================================== @@ -2324,7 +2324,7 @@ atype :: { LHsType GhcPs } | PREFIX_TILDE atype {% amsA' (sLL $1 $> (mkBangTy (glR $1) SrcLazy $2)) } | PREFIX_BANG atype {% amsA' (sLL $1 $> (mkBangTy (glR $1) SrcStrict $2)) } - | '{' fielddecls '}' {% do { decls <- amsA' (sLL $1 $> $ HsRecTy (AnnList (listAsAnchorM $2) (ListBraces (epTok $1) (epTok $3)) [] noAnn []) $2) + | '{' fielddecls '}' {% do { decls <- amsA' (sLL $1 $> $ XHsType $ HsRecTy (AnnList (listAsAnchorM $2) (ListBraces (epTok $1) (epTok $3)) [] noAnn []) $2) ; checkRecordSyntax decls }} -- Constructor sigs only ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -805,7 +805,7 @@ mkGadtDecl loc names dcol ty = do (args, res_ty, (ops, cps), csa) <- case body_ty of - L ll (HsFunTy _ hsArr (L (EpAnn anc _ cs) (HsRecTy an rf)) res_ty) -> do + L ll (HsFunTy _ hsArr (L (EpAnn anc _ cs) (XHsType (HsRecTy an rf))) res_ty) -> do arr <- case hsArr of HsUnrestrictedArrow arr -> return arr _ -> do addError $ mkPlainErrorMsgEnvelope (getLocA body_ty) $ @@ -1537,8 +1537,8 @@ instance Outputable (ArgPatBuilder GhcPs) where ppr (ArgPatBuilderArgPat p) = ppr p mkBangTy :: EpaLocation -> SrcStrictness -> LHsType GhcPs -> HsType GhcPs -mkBangTy tok_loc strictness = - HsBangTy ((noAnn, noAnn, tok_loc), NoSourceText) (HsBang NoSrcUnpack strictness) +mkBangTy tok_loc strictness lty = + XHsType (HsBangTy ((noAnn, noAnn, tok_loc), NoSourceText) (HsBang NoSrcUnpack strictness) lty) -- | Result of parsing @{-\# UNPACK \#-}@ or @{-\# NOUNPACK \#-}@. data UnpackednessPragma = @@ -1555,11 +1555,11 @@ addUnpackednessP (L lprag (UnpackednessPragma anns prag unpk)) ty = do -- such as ~T or !T, then add the pragma to the existing HsBangTy. -- -- Otherwise, wrap the type in a new HsBangTy constructor. - addUnpackedness (o,c) (L _ (HsBangTy ((_,_,tl), NoSourceText) bang t)) + addUnpackedness (o,c) (L _ (XHsType (HsBangTy ((_,_,tl), NoSourceText) bang t))) | HsBang NoSrcUnpack strictness <- bang - = HsBangTy ((o,c,tl), prag) (HsBang unpk strictness) t + = XHsType (HsBangTy ((o,c,tl), prag) (HsBang unpk strictness) t) addUnpackedness (o,c) t - = HsBangTy ((o,c,noAnn), prag) (HsBang unpk NoSrcStrict) t + = XHsType (HsBangTy ((o,c,noAnn), prag) (HsBang unpk NoSrcStrict) t) --------------------------------------------------------------------------- -- | Check for monad comprehensions @@ -2333,7 +2333,7 @@ dataConBuilderDetails :: LocatedA DataConBuilder -> HsConDeclH98Details GhcPs -- Detect when the record syntax is used: -- data T = MkT { ... } dataConBuilderDetails (L _ (PrefixDataConBuilder flds _)) - | [L (EpAnn anc _ cs) (HsRecTy an fields)] <- toList flds + | [L (EpAnn anc _ cs) (XHsType (HsRecTy an fields))] <- toList flds = RecCon (L (EpAnn anc an cs) fields) -- Normal prefix constructor, e.g. data T = MkT A B C @@ -2369,7 +2369,7 @@ instance DisambTD DataConBuilder where return $ L (addCommentsToEpAnn l cs) (InfixDataConBuilder lhs data_con rhs) where l = combineLocsA lhs rhs - check_no_ops (HsBangTy _ _ t) = check_no_ops (unLoc t) + check_no_ops (XHsType (HsBangTy _ _ t)) = check_no_ops (unLoc t) check_no_ops (HsOpTy{}) = addError $ mkPlainErrorMsgEnvelope (locA l) $ (PsErrInvalidInfixDataCon (unLoc lhs) (unLoc tc) (unLoc rhs)) ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -571,31 +571,6 @@ rnHsTyKi env (HsParTy _ ty) = do { (ty', fvs) <- rnLHsTyKi env ty ; return (HsParTy noAnn ty', fvs) } -rnHsTyKi env (HsBangTy x b ty) - = do { (ty', fvs) <- rnLHsTyKi env ty - ; return (HsBangTy x b ty', fvs) } - -rnHsTyKi env ty@(HsRecTy _ flds) - = do { let ctxt = rtke_ctxt env - ; fls <- get_fields ctxt - ; (flds', fvs) <- rnConDeclFields ctxt fls flds - ; return (HsRecTy noExtField flds', fvs) } - where - get_fields ctxt@(ConDeclCtx names) - = do res <- concatMapM (lookupConstructorFields . unLoc) names - if equalLength res names - -- Lookup can fail when the record syntax is incorrect, e.g. - -- data D = D Int { fld :: Bool }. See T7943. - then return res - else err ctxt - get_fields ctxt = err ctxt - - err ctxt = - do { addErr $ - TcRnWithHsDocContext ctxt $ - TcRnIllegalRecordSyntax (Left ty) - ; return [] } - rnHsTyKi env (HsFunTy u mult ty1 ty2) = do { (ty1', fvs1) <- rnLHsTyKi env ty1 ; (ty2', fvs2) <- rnLHsTyKi env ty2 @@ -666,7 +641,7 @@ rnHsTyKi env (HsDocTy x ty haddock_doc) ; return (HsDocTy x ty' haddock_doc', fvs) } -- See Note [Renaming HsCoreTys] -rnHsTyKi env (XHsType ty) +rnHsTyKi env (XHsType (HsCoreTy ty)) = do mapM_ (check_in_scope . nameRdrName) fvs_list return (XHsType ty, fvs) where @@ -681,6 +656,23 @@ rnHsTyKi env (XHsType ty) TcRnWithHsDocContext (rtke_ctxt env) $ TcRnNotInScope (notInScopeErr WL_LocalOnly rdr_name) rdr_name [] [] +rnHsTyKi env ty@(XHsType (HsBangTy _ bang (L _ inner))) = do + -- While top-level bangs at this point are eliminated (eg !(Maybe Int)), + -- other kinds of bangs are not (eg ((!Maybe) Int)). These kinds of + -- bangs are invalid, so fail. (#7210, #14761) + addErr $ + TcRnWithHsDocContext (rtke_ctxt env) $ + TcRnUnexpectedAnnotation ty bang + rnHsTyKi env inner + +rnHsTyKi env ty@(XHsType (HsRecTy {})) = do + -- Record types (which only show up temporarily in constructor + -- signatures) should have been removed by now + addErr $ + TcRnWithHsDocContext (rtke_ctxt env) $ + TcRnIllegalRecordSyntax ty + return (HsWildCardTy noExtField, emptyFVs) -- trick to avoid `failWithTc` + rnHsTyKi env ty@(HsExplicitListTy _ ip tys) = do { checkDataKinds env ty ; (tys', fvs) <- mapFvRn (rnLHsTyKi env) tys @@ -2066,10 +2058,6 @@ extract_lty :: LHsType GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lty (L _ ty) acc = case ty of HsTyVar _ _ ltv -> extract_tv ltv acc - HsBangTy _ _ ty -> extract_lty ty acc - HsRecTy _ flds -> foldr (extract_scaled_lty - . cd_fld_spec . unLoc) acc - flds HsAppTy _ ty1 ty2 -> extract_lty ty1 $ extract_lty ty2 acc HsAppKindTy _ ty k -> extract_lty ty $ ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -1383,21 +1383,6 @@ rn_ty_pat (HsSpliceTy _ splice) = do | hsTypeNeedsParens maxPrec hs_ty = L loc (HsParTy noAnn lhs_ty) | otherwise = lhs_ty -rn_ty_pat (HsBangTy an bang_src lty) = do - ctxt <- askDocContext - lty'@(L _ ty') <- rn_lty_pat lty - liftRn $ addErr $ - TcRnWithHsDocContext ctxt $ - TcRnUnexpectedAnnotation ty' bang_src - pure (HsBangTy an bang_src lty') - -rn_ty_pat ty at HsRecTy{} = do - ctxt <- askDocContext - liftRn $ addErr $ - TcRnWithHsDocContext ctxt $ - TcRnIllegalRecordSyntax (Left ty) - pure (HsWildCardTy noExtField) -- trick to avoid `failWithTc` - rn_ty_pat ty@(XHsType{}) = do ctxt <- askDocContext liftRnFV $ rnHsType ctxt ty ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -2127,7 +2127,7 @@ nlHsAppType e s = noLocA (HsAppType noAnn e hs_ty) hs_ty = mkHsWildCardBndrs $ parenthesizeHsType appPrec $ nlHsCoreTy s nlHsCoreTy :: HsCoreTy -> LHsType GhcPs -nlHsCoreTy = noLocA . XHsType +nlHsCoreTy = noLocA . XHsType . HsCoreTy mkCoerceClassMethEqn :: Class -- the class being derived -> [TyVar] -- the tvs in the instance head (this includes @@ -2244,10 +2244,10 @@ genAuxBindSpecSig :: SrcSpan -> AuxBindSpec -> LHsSigWcType GhcPs genAuxBindSpecSig loc spec = case spec of DerivTag2Con tycon _ -> mk_sig $ L (noAnnSrcSpan loc) $ - XHsType $ mkSpecForAllTys (tyConTyVars tycon) $ + XHsType $ HsCoreTy $ mkSpecForAllTys (tyConTyVars tycon) $ intTy `mkVisFunTyMany` mkParentType tycon DerivMaxTag _ _ - -> mk_sig (L (noAnnSrcSpan loc) (XHsType intTy)) + -> mk_sig (L (noAnnSrcSpan loc) (XHsType (HsCoreTy intTy))) DerivDataDataType _ _ _ -> mk_sig (nlHsTyVar NotPromoted dataType_RDR) DerivDataConstr _ _ _ ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1005,9 +1005,9 @@ instance Diagnostic TcRnMessage where HsBang _ _ -> "strictness" in text "Unexpected" <+> text err <+> text "annotation:" <+> ppr ty $$ text err <+> text "annotation cannot appear nested inside a type" - TcRnIllegalRecordSyntax either_ty_ty + TcRnIllegalRecordSyntax ty -> mkSimpleDecorated $ - text "Record syntax is illegal here:" <+> either ppr ppr either_ty_ty + text "Record syntax is illegal here:" <+> ppr ty TcRnInvalidVisibleKindArgument arg ty -> mkSimpleDecorated $ ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -2261,7 +2261,7 @@ data TcRnMessage where typecheck/should_fail/T7210 rename/should_fail/T22478b -} - TcRnUnexpectedAnnotation :: !(HsType GhcRn) -> !HsBang -> TcRnMessage + TcRnUnexpectedAnnotation :: !(HsType GhcPs) -> !HsBang -> TcRnMessage {-| TcRnIllegalRecordSyntax is an error indicating an illegal use of record syntax. @@ -2272,7 +2272,7 @@ data TcRnMessage where rename/should_fail/T9077 rename/should_fail/T22478b -} - TcRnIllegalRecordSyntax :: Either (HsType GhcPs) (HsType GhcRn) -> TcRnMessage + TcRnIllegalRecordSyntax :: HsType GhcPs -> TcRnMessage {-| TcRnInvalidVisibleKindArgument is an error for a kind application on a target type that cannot accept it. ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -1098,15 +1098,6 @@ tcHsType :: TcTyMode -> HsType GhcRn -> ExpKind -> TcM TcType tcHsType mode (HsParTy _ ty) exp_kind = tcLHsType mode ty exp_kind tcHsType mode (HsDocTy _ ty _) exp_kind = tcLHsType mode ty exp_kind -tcHsType _ ty@(HsBangTy _ bang _) _ - -- While top-level bangs at this point are eliminated (eg !(Maybe Int)), - -- other kinds of bangs are not (eg ((!Maybe) Int)). These kinds of - -- bangs are invalid, so fail. (#7210, #14761) - = failWith $ TcRnUnexpectedAnnotation ty bang -tcHsType _ ty@(HsRecTy {}) _ - -- Record types (which only show up temporarily in constructor - -- signatures) should have been removed by now - = failWithTc $ TcRnIllegalRecordSyntax (Right ty) -- HsSpliced is an annotation produced by 'GHC.Rename.Splice.rnSpliceType'. -- Here we get rid of it and add the finalizers to the global environment ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -282,8 +282,6 @@ no_anon_wc_ty lty = go lty HsIParamTy _ _ ty -> go ty HsKindSig _ ty kind -> go ty && go kind HsDocTy _ ty _ -> go ty - HsBangTy _ _ ty -> go ty - HsRecTy _ flds -> gos $ concatMap (hsConFieldSpecToHsTypes . cd_fld_spec . unLoc) flds HsExplicitListTy _ _ tys -> gos tys HsExplicitTupleTy _ _ tys -> gos tys HsForAllTy { hst_tele = tele ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1802,7 +1802,7 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc kcConArgTys :: NewOrData -> TcKind -> [HsConFieldSpec on GhcRn] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext ty exp_kind tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -3927,7 +3927,7 @@ tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatype -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (CFS (_, src) unp str w bty) = do { traceTc "tcConArg 1" (ppr bty) - ; arg_ty <- tcCheckLHsTypeInContext (getBangType bty) exp_kind + ; arg_ty <- tcCheckLHsTypeInContext bty exp_kind ; w' <- tcDataConMult w ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, HsSrcBang src (HsBang unp str)) } ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -909,12 +909,6 @@ data HsType pass | HsDocTy (XDocTy pass) (LHsType pass) (LHsDoc pass) -- A documented type - | HsBangTy (XBangTy pass) -- Contains the SourceText in GHC passes. - HsBang (LHsType pass) -- Bang-style type annotations - - | HsRecTy (XRecTy pass) - [LConDeclField pass] -- Only in data type declarations - | HsExplicitListTy -- A promoted explicit list (XExplicitListTy pass) PromotionFlag -- whether explicitly promoted, for pretty printer ===================================== testsuite/tests/parser/should_fail/T3811c.stderr ===================================== @@ -1,7 +1,5 @@ - -T3811c.hs:6:10: error: [GHC-53946] - • Illegal head of an instance declaration: ‘!Show D’. - Instance heads must be of the form - C ty_1 ... ty_n - where ‘C’ is a class. +T3811c.hs:6:10: error: [GHC-18932] + • Unexpected strictness annotation: !Show + strictness annotation cannot appear nested inside a type • In an instance declaration + ===================================== testsuite/tests/parser/should_fail/unpack_inside_type.stderr ===================================== @@ -1,7 +1,5 @@ - unpack_inside_type.hs:3:25: error: [GHC-18932] • Unexpected UNPACK annotation: {-# UNPACK #-}Int UNPACK annotation cannot appear nested inside a type - • In the first argument of ‘Maybe’, namely ‘{-# UNPACK #-}Int’ - In the type ‘Maybe {-# UNPACK #-}Int’ - In the definition of data constructor ‘T’ + • In the definition of data constructor ‘T’ + ===================================== testsuite/tests/rename/should_fail/T22478b.stderr ===================================== @@ -5,7 +5,7 @@ T22478b.hs:16:14: error: [GHC-10498] • In an equation for ‘fOutOfOrder’ T22478b.hs:18:10: error: [GHC-18932] - • Unexpected strictness annotation: Int + • Unexpected strictness annotation: !Int strictness annotation cannot appear nested inside a type • In a type argument in a pattern ===================================== testsuite/tests/typecheck/should_fail/T7210.stderr ===================================== @@ -1,7 +1,5 @@ - T7210.hs:5:19: error: [GHC-18932] • Unexpected strictness annotation: !IntMap strictness annotation cannot appear nested inside a type - • In the type ‘!IntMap Int’ - In the definition of data constructor ‘C’ - In the data declaration for ‘T’ + • In the definition of data constructor ‘C’ + ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4041,7 +4041,7 @@ instance ExactPrint (HsType GhcPs) where exact (HsDocTy an ty doc) = do ty' <- markAnnotated ty return (HsDocTy an ty' doc) - exact (HsBangTy ((o,c,tk), mt) (HsBang up str) ty) = do + exact (XHsType (HsBangTy ((o,c,tk), mt) (HsBang up str) ty)) = do (o',c') <- case mt of NoSourceText -> return (o,c) @@ -4056,7 +4056,7 @@ instance ExactPrint (HsType GhcPs) where SrcStrict -> printStringAtAA tk "!" NoSrcStrict -> return tk ty' <- markAnnotated ty - return (HsBangTy ((o',c',tk'), mt) (HsBang up str) ty') + return (XHsType (HsBangTy ((o',c',tk'), mt) (HsBang up str) ty')) exact (HsExplicitListTy (sq,o,c) prom tys) = do sq' <- if (isPromoted prom) then markEpToken sq ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs ===================================== @@ -98,7 +98,6 @@ dropHsDocTy = drop_sig_ty drop_ty (HsForAllTy x a e) = HsForAllTy x a (drop_lty e) drop_ty (HsQualTy x a e) = HsQualTy x a (drop_lty e) - drop_ty (HsBangTy x a b) = HsBangTy x a (drop_lty b) drop_ty (HsAppTy x a b) = HsAppTy x (drop_lty a) (drop_lty b) drop_ty (HsAppKindTy x a b) = HsAppKindTy x (drop_lty a) (drop_lty b) drop_ty (HsFunTy x w a b) = HsFunTy x w (drop_lty a) (drop_lty b) ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -597,7 +597,7 @@ ppSubSigLike unicode typ argDocs subdocs leader = do_sig_args 0 leader typ , decltt (ppLContextNoArrow lctxt unicode) <+> nl ) : do_largs n (darrow unicode) ltype - do_args n leader (HsFunTy _ _w (L _ (HsRecTy _ fields)) r) = + do_args n leader (HsFunTy _ _w (L _ (XHsType (HsRecTy _ fields))) r) = [ (decltt ldr, latex <+> nl) | (L _ field, ldr) <- zip fields (leader <+> gadtOpen : repeat gadtComma) , let latex = ppSideBySideField subdocs unicode field @@ -1320,7 +1320,6 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u = HsLinearAnn _ -> lollipop u HsUnannotated _ _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u <+> arrow u -ppr_mono_ty (HsBangTy _ b ty) u = ppBang b <> ppLParendType u ty ppr_mono_ty (HsTyVar _ NotPromoted (L _ name)) _ = ppDocName name ppr_mono_ty (HsTyVar _ IsPromoted (L _ name)) _ = char '\'' <> ppDocName name ppr_mono_ty (HsTupleTy _ con tys) u = tupleParens con (map (ppLType u) tys) @@ -1329,8 +1328,9 @@ ppr_mono_ty (HsKindSig _ ty kind) u = parens (ppr_mono_lty ty u <+> dcolon u <+> ppr_mono_ty (HsListTy _ ty) u = brackets (ppr_mono_lty ty u) ppr_mono_ty (HsIParamTy _ (L _ n) ty) u = ppIPName n <+> dcolon u <+> ppr_mono_lty ty u ppr_mono_ty (HsSpliceTy v _) _ = dataConCantHappen v -ppr_mono_ty (HsRecTy{}) _ = text "{..}" -ppr_mono_ty (XHsType{}) _ = error "ppr_mono_ty HsCoreTy" +ppr_mono_ty (XHsType (HsBangTy _ b ty)) u = ppBang b <> ppLParendType u ty +ppr_mono_ty (XHsType HsRecTy{}) _ = text "{..}" +ppr_mono_ty (XHsType HsCoreTy{}) _ = error "ppr_mono_ty HsCoreTy" ppr_mono_ty (HsExplicitListTy _ IsPromoted tys) u = Pretty.quote $ brackets $ hsep $ punctuate comma $ map (ppLType u) tys ppr_mono_ty (HsExplicitListTy _ NotPromoted tys) u = brackets $ hsep $ punctuate comma $ map (ppLType u) tys ppr_mono_ty (HsExplicitTupleTy _ IsPromoted tys) u = Pretty.quote $ parenList $ map (ppLType u) tys ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -335,7 +335,7 @@ ppSubSigLike unicode qual typ argDocs subdocs sep emptyCtxts = do_sig_args 0 sep | otherwise = (leader <+> ppLContextNoArrow lctxt unicode qual emptyCtxts, Nothing, []) : do_largs n (darrow unicode) ltype - do_args n leader (HsFunTy _ _w (L _ (HsRecTy _ fields)) r) = + do_args n leader (HsFunTy _ _w (L _ (XHsType (HsRecTy _ fields))) r) = [ (ldr <+> html, mdoc, subs) | (L _ field, ldr) <- zip fields (leader <+> gadtOpen : repeat gadtComma) , let (html, mdoc, subs) = ppSideBySideField subdocs unicode qual field @@ -1808,8 +1808,6 @@ ppr_mono_ty (HsQualTy _ ctxt ty) unicode qual emptyCtxts = -- UnicodeSyntax alternatives ppr_mono_ty (HsTyVar _ _ (L _ name)) True _ _ | getOccString (getName name) == "(->)" = toHtml "(→)" -ppr_mono_ty (HsBangTy _ b ty) u q _ = - ppBang b +++ ppLParendType u q HideEmptyContexts ty ppr_mono_ty (HsTyVar _ prom (L _ name)) _ q _ | isPromoted prom = promoQuote (ppDocName q Prefix True name) | otherwise = ppDocName q Prefix True name @@ -1835,11 +1833,13 @@ ppr_mono_ty (HsListTy _ ty) u q _ = brackets (ppr_mono_lty ty u q HideEmptyConte ppr_mono_ty (HsIParamTy _ (L _ n) ty) u q _ = ppIPName n <+> dcolon u <+> ppr_mono_lty ty u q HideEmptyContexts ppr_mono_ty (HsSpliceTy v _) _ _ _ = dataConCantHappen v -ppr_mono_ty (HsRecTy{}) _ _ _ = toHtml "{..}" +ppr_mono_ty (XHsType (HsBangTy _ b ty)) u q _ = + ppBang b +++ ppLParendType u q HideEmptyContexts ty +ppr_mono_ty (XHsType (HsRecTy{})) _ _ _ = toHtml "{..}" -- Can now legally occur in ConDeclGADT, the output here is to provide a -- placeholder in the signature, which is followed by the field -- declarations. -ppr_mono_ty (XHsType{}) _ _ _ = error "ppr_mono_ty HsCoreTy" +ppr_mono_ty (XHsType HsCoreTy{}) _ _ _ = error "ppr_mono_ty HsCoreTy" ppr_mono_ty (HsExplicitListTy _ IsPromoted tys) u q _ = promoQuote $ brackets $ hsep $ punctuate comma $ map (ppLType u q HideEmptyContexts) tys ppr_mono_ty (HsExplicitListTy _ NotPromoted tys) u q _ = brackets $ hsep $ punctuate comma $ map (ppLType u q HideEmptyContexts) tys ppr_mono_ty (HsExplicitTupleTy _ IsPromoted tys) u q _ = promoQuote $ parenList $ map (ppLType u q HideEmptyContexts) tys ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -196,14 +196,14 @@ hsConFieldSpecToFunTy (hsConFieldSpecGeneralize -> cfs) tgt = noLocA (HsFunTy noAnn (cfs_multiplicity cfs) (hsConFieldSpecToHsTypeNoMult cfs) tgt) hsConFieldSpecToHsTypeNoMult - :: (XRec pass (HsType pass) ~ GenLocated e (HsType pass), HasAnnotation e, NoAnn (XBangTy pass)) + :: (XRec pass (HsType pass) ~ GenLocated e (HsType pass), HasAnnotation e, NoAnn (XBangTy pass), XXType pass ~ HsTypeGhcPsExt pass) => HsConFieldSpec on pass -> LHsType pass hsConFieldSpecToHsTypeNoMult (CFS _ unp str _ t) = case t of L l (HsDocTy x ty doc) -> L l (HsDocTy x (mkBang unp str ty) doc) _ -> mkBang unp str t where mkBang NoSrcUnpack NoSrcStrict ty = ty - mkBang u s ty = noLocA (HsBangTy noAnn (HsBang u s) ty) + mkBang u s ty = noLocA (XHsType (HsBangTy noAnn (HsBang u s) ty)) getGADTConType :: ConDecl DocNameI -> LHsSigType DocNameI -- The full type of a GADT data constructor We really only get this in @@ -234,7 +234,7 @@ getGADTConType -- tau_ty :: LHsType DocNameI tau_ty = case args of - RecConGADT _ flds -> mkFunTy (noLocA (HsRecTy noAnn (unLoc flds))) res_ty + RecConGADT _ flds -> mkFunTy (noLocA (XHsType (HsRecTy noAnn (unLoc flds)))) res_ty PrefixConGADT _ pos_args -> foldr hsConFieldSpecToFunTy res_ty pos_args mkFunTy :: LHsType DocNameI -> LHsType DocNameI -> LHsType DocNameI @@ -426,11 +426,9 @@ reparenTypePrec = go where -- Shorter name for 'reparenType' go :: Precedence -> HsType a -> HsType a - go _ (HsBangTy x b ty) = HsBangTy x b (reparenLType ty) go _ (HsTupleTy x con tys) = HsTupleTy x con (map reparenLType tys) go _ (HsSumTy x tys) = HsSumTy x (map reparenLType tys) go _ (HsListTy x ty) = HsListTy x (reparenLType ty) - go _ (HsRecTy x flds) = HsRecTy x (map (mapXRec @a reparenConDeclField) flds) go p (HsDocTy x ty d) = HsDocTy x (goL p ty) d go _ (HsExplicitListTy x p tys) = HsExplicitListTy x p (map reparenLType tys) go _ (HsExplicitTupleTy x p tys) = HsExplicitTupleTy x p (map reparenLType tys) ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Create.hs ===================================== @@ -962,12 +962,12 @@ extractPatternSyn nm t tvs cons = let args = case con of ConDeclH98{con_args = con_args'} -> case con_args' of - PrefixCon _ args' -> map hsConFieldSpecToHsTypeNoMult args' - RecCon (L _ fields) -> hsConFieldSpecToHsTypeNoMult . cd_fld_spec . unLoc <$> fields - InfixCon arg1 arg2 -> map hsConFieldSpecToHsTypeNoMult [arg1, arg2] + PrefixCon _ args' -> map cfs_type args' + RecCon (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields + InfixCon arg1 arg2 -> map cfs_type [arg1, arg2] ConDeclGADT{con_g_args = con_args'} -> case con_args' of - PrefixConGADT _ args' -> map hsConFieldSpecToHsTypeNoMult args' - RecConGADT _ (L _ fields) -> hsConFieldSpecToHsTypeNoMult . cd_fld_spec . unLoc <$> fields + PrefixConGADT _ args' -> map cfs_type args' + RecConGADT _ (L _ fields) -> cfs_type . cd_fld_spec . unLoc <$> fields typ = longArrow args (data_ty con) typ' = case con of ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -362,7 +362,6 @@ renameType t = case t of ltype' <- renameLType ltype return (HsQualTy{hst_xqual = noAnn, hst_ctxt = lcontext', hst_body = ltype'}) HsTyVar _ ip (L l n) -> return . HsTyVar noAnn ip . L l =<< renameName n - HsBangTy _ b ltype -> return . HsBangTy noAnn b =<< renameLType ltype HsStarTy _ isUni -> return (HsStarTy noAnn isUni) HsAppTy _ a b -> do a' <- renameLType a @@ -403,8 +402,7 @@ renameType t = case t of doc' <- renameLDocHsSyn doc return (HsDocTy noAnn ty' doc') HsTyLit _ x -> return (HsTyLit noAnn (renameTyLit x)) - HsRecTy _ a -> HsRecTy noAnn <$> mapM renameConDeclFieldField a - XHsType a -> pure (XHsType a) + XHsType a -> pure (XHsType (HsCoreTy a)) HsExplicitListTy _ a b -> HsExplicitListTy noAnn a <$> mapM renameLType b -- Special-case unary boxed tuples so that they are pretty-printed as -- `'MkSolo x`, not `'(x)` ===================================== utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs ===================================== @@ -111,8 +111,6 @@ renameType (HsIParamTy x ip lt) = HsIParamTy x ip <$> renameLType lt renameType (HsKindSig x lt lk) = HsKindSig x <$> renameLType lt <*> pure lk renameType t@(HsSpliceTy _ _) = pure t renameType (HsDocTy x lt doc) = HsDocTy x <$> renameLType lt <*> pure doc -renameType (HsBangTy x bang lt) = HsBangTy x bang <$> renameLType lt -renameType t@(HsRecTy _ _) = pure t renameType t@(XHsType _) = pure t renameType (HsExplicitListTy x ip ltys) = HsExplicitListTy x ip <$> renameLTypes ltys ===================================== utils/haddock/haddock-api/src/Haddock/Types.hs ===================================== @@ -866,7 +866,7 @@ type instance XExplicitListTy DocNameI = EpAnn NoEpAnns type instance XExplicitTupleTy DocNameI = EpAnn NoEpAnns type instance XTyLit DocNameI = EpAnn NoEpAnns type instance XWildCardTy DocNameI = EpAnn NoEpAnns -type instance XXType DocNameI = HsCoreTy +type instance XXType DocNameI = HsTypeGhcPsExt DocNameI type instance XNumTy DocNameI = NoExtField type instance XStrTy DocNameI = NoExtField View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9103745e24a3b7534a996b78b6a2ebf938c4b06d...0a19e6ac82619a9397ece4dcc809256a26363456 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9103745e24a3b7534a996b78b6a2ebf938c4b06d...0a19e6ac82619a9397ece4dcc809256a26363456 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 13:44:26 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 11 Jan 2025 08:44:26 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: user_guide: Note -pgmP/-optP are for /Haskell/-CPP Message-ID: <678275ba48417_5ab7f61e964388f5@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 15b243c0 by Mike Pilgrem at 2025-01-11T08:44:11-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - 669b8b42 by Patrick at 2025-01-11T08:44:12-05:00 Fix #25611. Enhances the kind inference for data family instances, by including the RHS's constraints when kind-checking LHS. Type checker changes: In `tcDataFamInstHeader`, `kcConDecls` the H98-style decls and newtype decls, even those in GADT syntax, but NOT for general GADT decls. Testsuite changes: 1. The test to ensure kind specialization remains correctly handled even if we include the RHS's constrains: * T25611d 2. Infer result kind from datacon. * H98 newtype case: T25611a * H98 data case: T25611b 3. Two tests with additional errors report: * UnliftedNewtypesFamilyKindFail2 * UnliftedNewtypesInstanceFail 4. Due to better kind inference, move should_fail test UnliftedNewtypesUnassociatedFamilyFail to should_compile test T25611c. 5. Additional test to we default the kind of the data instance correctly without UnliftedNewtypes or UnliftedDatatypes: * DataInstanceKindsDefaults Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 30 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - docs/users_guide/phases.rst - libraries/base/changelog.md - libraries/base/src/Data/List/NonEmpty.hs - libraries/base/src/Data/Semigroup.hs - libraries/base/src/GHC/Base.hs - libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/src/GHC/Internal/Base.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs - libraries/ghc-internal/src/GHC/Internal/Data/Data.hs - libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs - libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs - + libraries/ghc-internal/src/GHC/Internal/Data/NonEmpty.hs - libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs - libraries/ghc-internal/src/GHC/Internal/Generics.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs - libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs - libraries/ghc-internal/src/GHC/Internal/Text/ParserCombinators/ReadP.hs - + testsuite/tests/indexed-types/should_compile/dataInstanceKindsDefaults.hs - testsuite/tests/indexed-types/should_fail/all.T - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c80092a23f01279cca64e5907787e10137904a4...669b8b42c0d913d8a9b30570eb3169e79313c3f3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c80092a23f01279cca64e5907787e10137904a4...669b8b42c0d913d8a9b30570eb3169e79313c3f3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 13:57:21 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 11 Jan 2025 08:57:21 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax Message-ID: <678278c166a82_c13b2c054413827@gitlab.mail> Patrick pushed new branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 14:00:02 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 11 Jan 2025 09:00:02 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] allow-newtype-instance-in-gadt-syntax Message-ID: <678279629a563_c13b2c15481531c@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 47240934 by Patrick at 2025-01-11T21:59:53+08:00 allow-newtype-instance-in-gadt-syntax - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -4855,7 +4855,7 @@ checkNewDataCon con -- If the newtype is a GADT, the GADT error is enough; -- we don't need to *also* complain about existentials. ; if not (null eq_spec) - then addErrTc $ TcRnIllegalNewtype con show_linear_types IsGADT + then return () else unless (null ex_tvs) $ addErrTc $ TcRnIllegalNewtype con show_linear_types HasExistentialTyVar View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47240934b8f446e71ca7a1a08ecaa5cb3ca14104 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47240934b8f446e71ca7a1a08ecaa5cb3ca14104 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 14:01:52 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 11 Jan 2025 09:01:52 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Deleted 1 commit: allow-newtype-instance-in-gadt-syntax Message-ID: <678279d0aa06a_c13b238d6b41683c@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below. Deleted commits: 47240934 by Patrick at 2025-01-11T21:59:53+08:00 allow-newtype-instance-in-gadt-syntax - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -4855,7 +4855,7 @@ checkNewDataCon con -- If the newtype is a GADT, the GADT error is enough; -- we don't need to *also* complain about existentials. ; if not (null eq_spec) - then addErrTc $ TcRnIllegalNewtype con show_linear_types IsGADT + then return () else unless (null ex_tvs) $ addErrTc $ TcRnIllegalNewtype con show_linear_types HasExistentialTyVar View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47240934b8f446e71ca7a1a08ecaa5cb3ca14104 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47240934b8f446e71ca7a1a08ecaa5cb3ca14104 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 14:03:37 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 11 Jan 2025 09:03:37 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] allow newtype instance in gadt syntax Message-ID: <67827a398ad42_c13b238d27c1838a@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 171d280a by Patrick at 2025-01-11T22:03:25+08:00 allow newtype instance in gadt syntax - - - - - 2 changed files: - compiler/GHC/Tc/TyCl.hs - testsuite/tests/rep-poly/T25611d.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -4855,7 +4855,7 @@ checkNewDataCon con -- If the newtype is a GADT, the GADT error is enough; -- we don't need to *also* complain about existentials. ; if not (null eq_spec) - then addErrTc $ TcRnIllegalNewtype con show_linear_types IsGADT + then return () else unless (null ex_tvs) $ addErrTc $ TcRnIllegalNewtype con show_linear_types HasExistentialTyVar ===================================== testsuite/tests/rep-poly/T25611d.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE DataKinds #-} +{-# LANGUAGE UnliftedNewtypes #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MagicHash #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/171d280a71b52fde7df0be702dac13cda5bdcc03 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/171d280a71b52fde7df0be702dac13cda5bdcc03 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 11 20:15:26 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sat, 11 Jan 2025 15:15:26 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <6782d15e3c47c_264b4f4c38081634c@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: a0e1f3bd by Brandon Chinn at 2025-01-11T12:15:00-08:00 Require alex >= 3.5.2 (#25623) - - - - - 6 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in - hadrian/cabal.project Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: eb4d3389fd62e4f7321a0c8799014ec1f4da0708 + DOCKER_REV: f8b8b8910097a88185835e0c929b8bb03fadfe61 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/ci.sh ===================================== @@ -8,9 +8,9 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-04T21:29:42Z" MIN_HAPPY_VERSION="1.20" -MIN_ALEX_VERSION="3.2.6" +MIN_ALEX_VERSION="3.5.2.0" TOP="$(pwd)" if [ ! -d "$TOP/.gitlab" ]; then ===================================== .gitlab/darwin/nix/sources.json ===================================== @@ -17,10 +17,10 @@ "homepage": "", "owner": "nixos", "repo": "nixpkgs", - "rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60", - "sha256": "1anwxmjpm21msnnlrjdz19w31bxnbpn4kgf93sn3npihi7wf4a8h", + "rev": "91ef85e17108be826689fe42a207dfd24d354012", + "sha256": "0000000000000000000000000000000000000000000000000000", "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/2893f56de08021cffd9b6b6dfc70fd9ccd51eb60.tar.gz", + "url": "https://github.com/nixos/nixpkgs/archive/91ef85e17108be826689fe42a207dfd24d354012.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-04T21:29:42Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a0e1f3bd9a1e9db53043eaf6bc14430142a95784 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a0e1f3bd9a1e9db53043eaf6bc14430142a95784 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 12 00:29:30 2025 From: gitlab at gitlab.haskell.org (=?UTF-8?B?TWF0ZXVzeiBHb8WbbGlub3dza2kgKEBTd29yZGxhc2gp?=) Date: Sat, 11 Jan 2025 19:29:30 -0500 Subject: [Git][ghc/ghc][wip/swordlash/allow_multiline_strings_in_js_ffi] Add test for multiline imports Message-ID: <67830cea996cc_351cf9f8cdd482371@gitlab.mail> Mateusz Goślinowski pushed to branch wip/swordlash/allow_multiline_strings_in_js_ffi at Glasgow Haskell Compiler / GHC Commits: 148a1e5c by Mateusz Goślinowski at 2025-01-12T01:29:20+01:00 Add test for multiline imports - - - - - 4 changed files: - docs/users_guide/9.14.1-notes.rst - + testsuite/tests/javascript/T25633.hs - + testsuite/tests/javascript/T25633.stdout - testsuite/tests/javascript/all.T Changes: ===================================== docs/users_guide/9.14.1-notes.rst ===================================== @@ -38,6 +38,8 @@ Language That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`. +* Multiline strings are now accepted in foreign imports. (#25157) + Compiler ~~~~~~~~ ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -0,0 +1,41 @@ +{-# LANGUAGE MultilineStrings #-} +module Main where + +import GHC.Prim +import GHC.JS.Prim +import Foreign.C +import System.IO + +foreign import javascript + """ + ((x) => x) + """ + toJSDouble :: Double -> JSVal + +foreign import javascript + """ + (function (x) { console.log(x); }) + """ + multiLog :: JSVal -> IO () + +foreign import javascript + """ + ((x) => x + "") + """ + jsToString :: JSVal -> JSVal + +foreign import ccall + """ + cos + """ mycos :: CDouble -> CDouble + +main :: IO () +main = do + -- avoid C and Haskell prints to stdout to be intermingled due to buffering on the Haskell side + hSetBuffering stdout NoBuffering + + multiLog $ toJSInt 5 + multiLog $ toJSString "Hello" + putStrLn $ fromJSString $ jsToString $ toJSInt (- 5) + multiLog $ jsToString $ toJSDouble 3.0 + print $ mycos 0 == 1 \ No newline at end of file ===================================== testsuite/tests/javascript/T25633.stdout ===================================== @@ -0,0 +1,5 @@ +5 +Hello +-5 +3 +True \ No newline at end of file ===================================== testsuite/tests/javascript/all.T ===================================== @@ -25,3 +25,5 @@ test('T24495', normal, makefile_test, ['T24495']) test('T23479', normal, makefile_test, ['T23479']) test('T24744', normal, makefile_test, ['T24744']) + +test('T25633', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/148a1e5c9e0dc606ef682edd43a62c011e02cc7f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/148a1e5c9e0dc606ef682edd43a62c011e02cc7f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 12 00:30:26 2025 From: gitlab at gitlab.haskell.org (=?UTF-8?B?TWF0ZXVzeiBHb8WbbGlub3dza2kgKEBTd29yZGxhc2gp?=) Date: Sat, 11 Jan 2025 19:30:26 -0500 Subject: [Git][ghc/ghc][wip/swordlash/allow_multiline_strings_in_js_ffi] 11 commits: warnings: Find out if a qualified name is in the interactive scope directly Message-ID: <67830d226a11e_351cf9ee0958840ca@gitlab.mail> Mateusz Goślinowski pushed to branch wip/swordlash/allow_multiline_strings_in_js_ffi at Glasgow Haskell Compiler / GHC Commits: f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 9a5b87e4 by Mateusz Goślinowski at 2025-01-12T00:29:51+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 3594450e by Mateusz Goślinowski at 2025-01-12T00:29:51+00:00 Add test for multiline imports - - - - - 25 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/TyCl.hs - docs/users_guide/9.14.1-notes.rst - docs/users_guide/phases.rst - docs/users_guide/using-optimisation.rst - m4/ghc_toolchain.m4 - rts/Printer.c - rts/xxhash.h - + testsuite/tests/core-to-stg/T25284/A.hs - + testsuite/tests/core-to-stg/T25284/B.hs - + testsuite/tests/core-to-stg/T25284/Cls.hs - + testsuite/tests/core-to-stg/T25284/Main.hs - + testsuite/tests/core-to-stg/T25284/T25284.stdout - + testsuite/tests/core-to-stg/T25284/all.T - + testsuite/tests/javascript/T25633.hs - + testsuite/tests/javascript/T25633.stdout - testsuite/tests/javascript/all.T - utils/dump-decls/Main.hs Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2051,6 +2051,16 @@ conceptually. See also Note [Floats and FloatDecision] for how we maintain whole groups of floats and how far they go. +Note [Controlling Speculative Evaluation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Most of the time, speculative evaluation has a positive effect on performance, +but we have found a case where speculative evaluation of dictionary functions +leads to a performance regression #25284. + +Therefore we have some flags to control it. See the optimization section in +the User's Guide for the description of these flags and when to use them. + Note [Floats and FloatDecision] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We have a special datatype `Floats` for modelling a telescope of `FloatingBind` @@ -2275,7 +2285,15 @@ mkNonRecFloat env lev bndr rhs } is_hnf = exprIsHNF rhs - ok_for_spec = exprOkForSpecEval (not . is_rec_call) rhs + cfg = cpe_config env + + ok_for_spec = exprOkForSpecEval call_ok_for_spec rhs + -- See Note [Controlling Speculative Evaluation] + call_ok_for_spec x + | is_rec_call x = False + | not (cp_specEval cfg) = False + | not (cp_specEvalDFun cfg) && isDFunId x = False + | otherwise = True is_rec_call = (`elemUnVarSet` cpe_rec_ids env) -- See Note [Pin evaluatedness on floats] @@ -2517,6 +2535,11 @@ data CorePrepConfig = CorePrepConfig -- ^ Configuration for arity analysis ('exprEtaExpandArity'). -- See Note [Eta expansion of arguments in CorePrep] -- When 'Nothing' (e.g., -O0, -O1), use the cheaper 'exprArity' instead + , cp_specEval :: !Bool + -- ^ Whether to perform speculative evaluation + -- See Note [Controlling Speculative Evaluation] + , cp_specEvalDFun :: !Bool + -- ^ Whether to perform speculative evaluation on DFuns } data CorePrepEnv ===================================== compiler/GHC/Driver/Config/CoreToStg/Prep.hs ===================================== @@ -24,6 +24,8 @@ initCorePrepConfig hsc_env = do , cp_arityOpts = if gopt Opt_DoCleverArgEtaExpansion dflags then Just (initArityOpts dflags) else Nothing + , cp_specEval = gopt Opt_SpecEval dflags + , cp_specEvalDFun = gopt Opt_SpecEvalDictFun dflags } initCorePrepPgmConfig :: DynFlags -> [Var] -> CorePrepPgmConfig ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1287,6 +1287,8 @@ optLevelFlags -- see Note [Documenting optimisation flags] -- RegsGraph suffers performance regression. See #7679 -- , ([2], Opt_StaticArgumentTransformation) -- Static Argument Transformation needs investigation. See #9374 + , ([0,1,2], Opt_SpecEval) + , ([0,1,2], Opt_SpecEvalDictFun) ] ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -674,6 +674,9 @@ data GeneralFlag | Opt_NumConstantFolding | Opt_CoreConstantFolding | Opt_FastPAPCalls -- #6084 + | Opt_SpecEval + | Opt_SpecEvalDictFun -- See Note [Controlling Speculative Evaluation] + -- Inference flags | Opt_DoTagInferenceChecks @@ -912,6 +915,8 @@ optimisationFlags = EnumSet.fromList , Opt_WorkerWrapper , Opt_WorkerWrapperUnlift , Opt_SolveConstantDicts + , Opt_SpecEval + , Opt_SpecEvalDictFun ] -- | The set of flags which affect code generation and can change a program's ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -2544,6 +2544,8 @@ fFlagsDeps = [ flagSpec "num-constant-folding" Opt_NumConstantFolding, flagSpec "core-constant-folding" Opt_CoreConstantFolding, flagSpec "fast-pap-calls" Opt_FastPAPCalls, + flagSpec "spec-eval" Opt_SpecEval, + flagSpec "spec-eval-dictfun" Opt_SpecEvalDictFun, flagSpec "cmm-control-flow" Opt_CmmControlFlow, flagSpec "show-warning-groups" Opt_ShowWarnGroups, flagSpec "hide-source-paths" Opt_HideSourcePaths, ===================================== compiler/GHC/Parser.y ===================================== @@ -2148,6 +2148,9 @@ fspec :: { Located (TokDcolon : STRING var '::' sigtype { sLL $1 $> (epUniTok $3 ,(L (getLoc $1) (getStringLiteral $1), $2, $4)) } + | STRING_MULTI var '::' sigtype { sLL $1 $> (epUniTok $3 + ,(L (getLoc $1) + (getStringMultiLiteral $1), $2, $4)) } | var '::' sigtype { sLL $1 $> (epUniTok $2 ,(noLoc (StringLiteral NoSourceText nilFS Nothing), $1, $3)) } -- if the entity string is missing, it defaults to the empty string; @@ -4247,6 +4250,7 @@ getINCOHERENT_PRAGs (L _ (ITincoherent_prag src)) = src getCTYPEs (L _ (ITctype src)) = src getStringLiteral l = StringLiteral (getSTRINGs l) (getSTRING l) Nothing +getStringMultiLiteral l = StringLiteral (getSTRINGMULTIs l) (getSTRINGMULTI l) Nothing isUnicode :: Located Token -> Bool isUnicode (L _ (ITforall iu)) = iu == UnicodeSyntax ===================================== compiler/GHC/Rename/Unbound.hs ===================================== @@ -34,10 +34,11 @@ import GHC.Prelude import GHC.Driver.DynFlags import GHC.Driver.Ppr +import GHC.Driver.Env.Types import GHC.Tc.Errors.Types import GHC.Tc.Utils.Monad -import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique) +import GHC.Builtin.Names ( mkUnboundName, isUnboundName ) import GHC.Utils.Misc import GHC.Utils.Panic (panic) @@ -53,16 +54,16 @@ import GHC.Types.Hint import GHC.Types.SrcLoc as SrcLoc import GHC.Types.Name import GHC.Types.Name.Reader -import GHC.Types.Unique.DFM (udfmToList) import GHC.Unit.Module import GHC.Unit.Module.Imported -import GHC.Unit.Home.ModInfo +import GHC.Utils.Outputable +import GHC.Runtime.Context import GHC.Data.Bag -import GHC.Utils.Outputable (empty) +import Language.Haskell.Syntax.ImpExp -import Data.List (sortBy, partition, nub) +import Data.List (sortBy, partition) import Data.List.NonEmpty ( pattern (:|), NonEmpty ) import Data.Function ( on ) import qualified Data.Semigroup as S @@ -146,10 +147,10 @@ unboundNameOrTermInType if_term_in_type looking_for rdr_name hints ; global_env <- getGlobalRdrEnv ; impInfo <- getImports ; currmod <- getModule - ; hpt <- getHpt + ; ic <- hsc_IC <$> getTopEnv ; let (imp_errs, suggs) = unknownNameSuggestions_ looking_for - dflags hpt currmod global_env local_env impInfo + dflags ic currmod global_env local_env impInfo rdr_name ; addErr $ make_error imp_errs (hints ++ suggs) } @@ -179,17 +180,17 @@ notInScopeErr where_look rdr_name unknownNameSuggestions :: LocalRdrEnv -> WhatLooking -> RdrName -> RnM ([ImportError], [GhcHint]) unknownNameSuggestions lcl_env what_look tried_rdr_name = do { dflags <- getDynFlags - ; hpt <- getHpt ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports ; curr_mod <- getModule + ; interactive_context <- hsc_IC <$> getTopEnv ; return $ unknownNameSuggestions_ (LF what_look WL_Anywhere) - dflags hpt curr_mod rdr_env lcl_env imp_info tried_rdr_name } + dflags interactive_context curr_mod rdr_env lcl_env imp_info tried_rdr_name } -unknownNameSuggestions_ :: LookingFor -> DynFlags - -> HomePackageTable -> Module +unknownNameSuggestions_ :: LookingFor -> DynFlags -> InteractiveContext + -> Module -> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails -> RdrName -> ([ImportError], [GhcHint]) unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env @@ -201,7 +202,7 @@ unknownNameSuggestions_ looking_for dflags hpt curr_mod global_env local_env , map (ImportSuggestion $ rdrNameOcc tried_rdr_name) imp_suggs , extensionSuggestions tried_rdr_name , fieldSelectorSuggestions global_env tried_rdr_name ] - (imp_errs, imp_suggs) = importSuggestions looking_for global_env hpt curr_mod imports tried_rdr_name + (imp_errs, imp_suggs) = importSuggestions looking_for hpt curr_mod imports tried_rdr_name if_ne :: (NonEmpty a -> b) -> [a] -> [b] if_ne _ [] = [] @@ -308,15 +309,13 @@ similarNameSuggestions looking_for@(LF what_look where_look) dflags global_env -- | Generate errors and helpful suggestions if a qualified name Mod.foo is not in scope. importSuggestions :: LookingFor - -> GlobalRdrEnv - -> HomePackageTable -> Module + -> InteractiveContext -> Module -> ImportAvails -> RdrName -> ([ImportError], [ImportSuggestion]) -importSuggestions looking_for global_env hpt currMod imports rdr_name +importSuggestions looking_for ic currMod imports rdr_name | WL_LocalOnly <- lf_where looking_for = ([], []) | WL_LocalTop <- lf_where looking_for = ([], []) | not (isQual rdr_name || isUnqual rdr_name) = ([], []) - | null interesting_imports - , Just name <- mod_name + | Just name <- mod_name , show_not_imported_line name = ([MissingModule name], []) | is_qualified @@ -344,6 +343,17 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name , Just imp <- return $ pick (importedByUser mod_imports) ] + -- Choose the imports from the interactive context which might have provided + -- a module. + interactive_imports = + filter pick_interactive (ic_imports ic) + + pick_interactive :: InteractiveImport -> Bool + pick_interactive (IIDecl d) | mod_name == Just (unLoc (ideclName d)) = True + | mod_name == fmap unLoc (ideclAs d) = True + pick_interactive (IIModule m) | mod_name == Just m = True + pick_interactive _ = False + -- We want to keep only one for each original module; preferably one with an -- explicit import list (for no particularly good reason) pick :: [ImportedModsVal] -> Maybe ImportedModsVal @@ -369,17 +379,10 @@ importSuggestions looking_for global_env hpt currMod imports rdr_name -- See Note [When to show/hide the module-not-imported line] show_not_imported_line :: ModuleName -> Bool -- #15611 show_not_imported_line modnam - | modnam `elem` glob_mods = False -- #14225 -- 1 - | moduleName currMod == modnam = False -- 2.1 - | is_last_loaded_mod modnam hpt_uniques = False -- 2.2 + | not (null interactive_imports) = False -- 1 (interactive context) + | not (null interesting_imports) = False -- 1 (normal module import) + | moduleName currMod == modnam = False -- 2 | otherwise = True - where - hpt_uniques = map fst (udfmToList hpt) - is_last_loaded_mod modnam uniqs = lastMaybe uniqs == Just (getUnique modnam) - glob_mods = nub [ mod - | gre <- globalRdrEnvElts global_env - , (mod, _) <- qualsInScope gre - ] extensionSuggestions :: RdrName -> [GhcHint] extensionSuggestions rdrName @@ -478,13 +481,8 @@ For the error message: Module X does not export Y No module named ‘X’ is imported: there are 2 cases, where we hide the last "no module is imported" line: -1. If the module X has been imported. -2. If the module X is the current module. There are 2 subcases: - 2.1 If the unknown module name is in a input source file, - then we can use the getModule function to get the current module name. - (See test T15611a) - 2.2 If the unknown module name has been entered by the user in GHCi, - then the getModule function returns something like "interactive:Ghci1", - and we have to check the current module in the last added entry of - the HomePackageTable. (See test T15611b) +1. If the module X has been imported (normally or via interactive context). +2. It is the current module we are trying to compile + then we can use the getModule function to get the current module name. + (See test T15611a) -} ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -1432,7 +1432,7 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1 }) ; wanted <- TcS.zonkSimples simples1 -- Plugin requires zonked inputs ; traceTcS "Running plugins (" (vcat [ text "Given:" <+> ppr given - , text "Watned:" <+> ppr wanted ]) + , text "Wanted:" <+> ppr wanted ]) ; p <- runTcPluginSolvers solvers (given, bagToList wanted) ; let (_, solved_wanted) = pluginSolvedCts p (_, unsolved_wanted) = pluginInputCts p ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1759,7 +1759,9 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- - In this function, those TcTyVars are unified with other kind variables during -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) -kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) tycon +kcTyClDecl (DataDecl { tcdLName = (L _ _name) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no -- harm. For GADTs, each data con brings its own tyvars into scope, @@ -1767,7 +1769,7 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name), tcdDataDefn = HsDataDefn { dd_ -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (dataDefnConsNewOrData cons) (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1799,67 +1801,70 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: NewOrData -> TcKind -> [HsScaled GhcRn (LHsType GhcRn)] -> TcM () -kcConArgTys new_or_data res_kind arg_tys = do - { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(HsScaled mult ty) -> do _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind - tcMult mult) +kcConArgTys :: ConArgKind -- Expected kind of the argument(s) + -> [HsScaled GhcRn (LHsType GhcRn)] -- User-written argument types + -> TcM () +kcConArgTys exp_kind arg_tys + = forM_ arg_tys $ \(HsScaled mult ty) -> + do { _ <- tcCheckLHsTypeInContext (getBangType ty) exp_kind + ; tcMult mult } -- See Note [Implementation of UnliftedNewtypes], STEP 2 - } -- Kind-check the types of arguments to a Haskell98 data constructor. -kcConH98Args :: NewOrData -> TcKind -> HsConDeclH98Details GhcRn -> TcM () -kcConH98Args new_or_data res_kind con_args = case con_args of - PrefixCon _ tys -> kcConArgTys new_or_data res_kind tys - InfixCon ty1 ty2 -> kcConArgTys new_or_data res_kind [ty1, ty2] - RecCon (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConH98Args :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclH98Details GhcRn + -> TcM () +kcConH98Args exp_kind con_args = case con_args of + PrefixCon _ tys -> kcConArgTys exp_kind tys + InfixCon ty1 ty2 -> kcConArgTys exp_kind [ty1, ty2] + RecCon (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -- Kind-check the types of arguments to a GADT data constructor. -kcConGADTArgs :: NewOrData -> TcKind -> HsConDeclGADTDetails GhcRn -> TcM () -kcConGADTArgs new_or_data res_kind con_args = case con_args of - PrefixConGADT _ tys -> kcConArgTys new_or_data res_kind tys - RecConGADT _ (L _ flds) -> kcConArgTys new_or_data res_kind $ +kcConGADTArgs :: ConArgKind -- Expected kind of the argument(s) + -> HsConDeclGADTDetails GhcRn + -> TcM () +kcConGADTArgs exp_kind con_args = case con_args of + PrefixConGADT _ tys -> kcConArgTys exp_kind tys + RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -kcConDecls :: Foldable f - => NewOrData - -> TcKind -- The result kind signature - -- Used only in H98 case - -> f (LConDecl GhcRn) -- The data constructors - -> TcM () +kcConDecls :: TcKind -- Result kind of tycon + -- Used only in H98 case + -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls new_or_data tc_res_kind = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) +kcConDecls tc_res_kind cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons + where + new_or_data = dataDefnConsNewOrData cons -- Kind check a data constructor. In additional to the data constructor, -- we also need to know about whether or not its corresponding type was -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData - -> TcKind -- Result kind of the type constructor - -- Usually Type but can be TYPE UnliftedRep - -- or even TYPE r, in the case of unlifted newtype - -- Used only in H98 case - -> ConDecl GhcRn - -> TcM () -kcConDecl new_or_data tc_res_kind (ConDeclH98 - { con_name = name, con_ex_tvs = ex_tvs - , con_mb_cxt = ex_ctxt, con_args = args }) +kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data tc_res_kind + (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs + , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (dataConCtxt (NE.singleton name)) $ discardResult $ bindExplicitTKBndrs_Tv ex_tvs $ do { _ <- tcHsContext ex_ctxt - ; kcConH98Args new_or_data tc_res_kind args + ; let arg_exp_kind = getArgExpKind new_or_data tc_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same as the tc_res_kind. See (KCD1) + -- in Note [kcConDecls: kind-checking data type decls] + ; kcConH98Args arg_exp_kind args -- We don't need to check the telescope here, -- because that's done in tcConDecl } -kcConDecl new_or_data - _tc_res_kind -- Not used in GADT case (and doesn't make sense) - (ConDeclGADT - { con_names = names, con_bndrs = L _ outer_bndrs, con_mb_cxt = cxt - , con_g_args = args, con_res_ty = res_ty }) +kcConDecl new_or_data _tc_res_kind + -- NB: _tc_res_kind is unused. See (KCD3) in + -- Note [kcConDecls: kind-checking data type decls] + (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs + , con_mb_cxt = cxt, con_g_args = args, con_res_ty = res_ty }) = -- See Note [kcConDecls: kind-checking data type decls] addErrCtxt (dataConCtxt names) $ discardResult $ @@ -1870,45 +1875,80 @@ kcConDecl new_or_data ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) ; con_res_kind <- newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - ; kcConGADTArgs new_or_data con_res_kind args - ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr con_res_kind) + + ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind + -- getArgExpKind: for newtypes, check that the argument kind + -- is the same the kind of `res_ty`, the data con's return type + -- See (KCD2) in Note [kcConDecls: kind-checking data type decls] + ; kcConGADTArgs arg_exp_kind args + + ; traceTc "kcConDecl:GADT }" (ppr names $$ ppr arg_exp_kind) ; return () } {- Note [kcConDecls: kind-checking data type decls] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ kcConDecls is used when we are inferring the kind of the type -constructor in a data type declaration. E.g. - data T f a = MkT (f a) -we want to infer the kind of 'f' and 'a'. The basic plan is described -in Note [Inferring kinds for type declarations]; here we are doing Step 2. - -In the GADT case we may have this: - data T f a where - MkT :: forall g b. g b -> T g b - -Notice that the variables f,a, and g,b are quite distinct. -Nevertheless, the type signature for MkT must still influence the kind -T which is (remember Step 1) something like - T :: kappa1 -> kappa2 -> Type -Otherwise we'd infer the bogus kind - T :: forall k1 k2. k1 -> k2 -> Type. - -The type signature for MkT influences the kind of T simply by -kind-checking the result type (T g b), which will force 'f' and 'g' to -have the same kinds. This is the call to - tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) -Because this is the result type of an arrow, we know the kind must be -of form (TYPE rr), and we get better error messages if we enforce that -here (e.g. test gadt10). - -For unlifted newtypes only, we must ensure that the argument kind -and result kind are the same: -* In the H98 case, we need the result kind of the TyCon, to unify with - the argument kind. - -* In GADT syntax, this unification happens via the result kind passed - to kcConGADTArgs. The tycon's result kind is not used at all in the - GADT case. +constructor in a data type declaration. The basic plan is described in +Note [Inferring kinds for type declarations]; here we are doing Step 2. + +We are kind-checking the data constructors /only/ to compute the kind of +the type construtor. For example + data T f a = MkT (f a) +The (f a) in the data construtor constrains the kinds of `f` and `a`, and hence +of `T`. + +There are two cases to consider in `kcConDecl` + +* Haskell 98 data constructors, as above. We simply bring `f` and `a` + into scope and kind-check the data constructors. + +* GADT data type decls e.g. + data S f a where + MkS :: g b -> S g b + Here `f` and `a` don't scope over the data constructor signatures. + Instead, we just kind-check the entire signature (including the result `S g b`), + relying on the fact that `S` is in scope with its initial kind `k1 -> k2 -> Type`; + doing so will constrain `k1` and `k2` appropriately. + +The arguments of each data constructor are always of kind (TYPE r) for some +r :: RuntimeRep. But in the case of a newytype, the argument kind must be +the same as the tycon result kind. Since we are trying to figure out the +tycon kind, kcConDecls must account for this, which is surprisingly tricky. +Again there are two cases to consider in `kcConDecl`: + +* Haskell 98 data type decls, e.g. + data T f a = MkT (f a) + * In the header, all the tycon binders are specified (here `f` and `a`) + and there is no result kind signature. + * The binders from the header scope over the data construtors. + * In the case of unlifted newtypes, the argument kind affects the tycon kind + newtype N = MkN Int# + Here `getInitialKind` will give `N` the result kind `TYPE r`, where `r` is + a unification variable, and `kcConDecls` should unify that `r` with + `IntRep` becuase of the `Int#` + + Solution (KCD1): just check that the argumet type has the same kind as the result + kind of the tycon. + +* GADT data type decls e.g. + data S f :: Type -> Type where + MkS :: g a -> S g a + * In the header, not all the tycon binders are specified (here just `f`), + and there can be a kind signature + * The kind signature may describe some, all, or none of the tycon binders. + Regardless, in the TcTyCon constructed by `getInitialKind`, the tyConResKind + is the signature, not the "ultimate" result type of the tycon (which is + usually Type) + * In the case of unlifted newtypes, we again want the argument kind to be the + same as the result kind of the tycon; but it's not so clear what /is/ the + result kind of the tycon, because of the signature stuff in the previous bullet. + + Solution (KCD2): kind-check the result type of the data constructor (here + `S g a`) and, for newtypes, ensure that the arugment has that same kind. + + (KCD3) The tycon's result kind `tc_res_kind` is not used at all in the GADT + case; rather it is accessed via looking up S's kind in the type environment + when kind-checking the result type of the data constructor. Note [Using TyVarTvs for kind-checking GADTs] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -3866,13 +3906,21 @@ nothing wrong with it). We are implicitly requiring tha tcInferLHsTypeKind doesn't any gratuitous top-level casts. -} + +type ConArgKind = ContextKind + -- The expected kind of the argument(s) of a constructor + -- For data types this is always OpenKind + -- For newtypes it is (TheKind ki) + -- where `ki` is the result kind of the newtype + -- With NoUnliftedNewtype, ki=Type, but with UnliftedNewtypes it can be a variable + -- | Produce an "expected kind" for the arguments of a data/newtype. -- If the declaration is indeed for a newtype, -- then this expected kind will be the kind provided. Otherwise, -- it is OpenKind for datatypes and liftedTypeKind. -- Why do we not check for -XUnliftedNewtypes? See point -- in Note [Implementation of UnliftedNewtypes] -getArgExpKind :: NewOrData -> TcKind -> ContextKind +getArgExpKind :: NewOrData -> TcKind -> ConArgKind getArgExpKind NewType res_ki = TheKind res_ki getArgExpKind DataType _ = OpenKind @@ -3898,7 +3946,7 @@ tcConIsInfixGADT con details ; return (con `elemNameEnv` fix_env) } | otherwise -> return False -tcConH98Args :: ContextKind -- expected kind of arguments +tcConH98Args :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclH98Details GhcRn @@ -3912,7 +3960,7 @@ tcConH98Args exp_kind (InfixCon bty1 bty2) tcConH98Args exp_kind (RecCon fields) = tcRecConDeclFields exp_kind fields -tcConGADTArgs :: ContextKind -- expected kind of arguments +tcConGADTArgs :: ConArgKind -- expected kind of arguments -- always OpenKind for datatypes, but unlifted newtypes -- might have a specific kind -> HsConDeclGADTDetails GhcRn @@ -3922,7 +3970,7 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsScaled GhcRn (LHsType GhcRn) -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (HsScaled w bty) @@ -3932,7 +3980,7 @@ tcConArg exp_kind (HsScaled w bty) ; traceTc "tcConArg 2" (ppr bty) ; return (Scaled w' arg_ty, getBangStrictness bty) } -tcRecConDeclFields :: ContextKind +tcRecConDeclFields :: ConArgKind -> LocatedL [LConDeclField GhcRn] -> TcM [(Scaled TcType, HsSrcBang)] tcRecConDeclFields exp_kind fields ===================================== docs/users_guide/9.14.1-notes.rst ===================================== @@ -38,6 +38,8 @@ Language That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`. +* Multiline strings are now accepted in foreign imports. (#25157) + Compiler ~~~~~~~~ ===================================== docs/users_guide/phases.rst ===================================== @@ -25,11 +25,12 @@ given compilation phase: Use ⟨cmd⟩ as the literate pre-processor. .. ghc-flag:: -pgmP ⟨cmd⟩ - :shortdesc: Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only) + :shortdesc: Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only) :type: dynamic :category: phase-programs - Use ⟨cmd⟩ as the C pre-processor (with :ghc-flag:`-cpp` only). + Use ⟨cmd⟩ as the Haskell C pre-processor (with :ghc-flag:`-cpp` only). + Note that the Haskell C pre-processor only pre-processes Haskell files. .. ghc-flag:: -pgmJSP ⟨cmd⟩ :shortdesc: Use ⟨cmd⟩ as the JavaScript C pre-processor (only for javascript-backend) @@ -177,7 +178,11 @@ the following flags: :type: dynamic :category: phase-options - Pass ⟨option⟩ to CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Pass ⟨option⟩ to the Haskell CPP (makes sense only if :ghc-flag:`-cpp` is also on). + Note that the Haskell pre-processor options only apply to pre-processing + invocations on Haskell files, and, e.g., to use different options to + pre-process Javascript or Cmm, one should use ``-optJSP``, or + ``-optCmmP``, respectively). .. ghc-flag:: -optJSP ⟨option⟩ :shortdesc: pass ⟨option⟩ to JavaScript C pre-processor (only for javascript-backend) ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -405,6 +405,55 @@ as such you shouldn't need to set any of them explicitly. A flag intermediate language, where it is able to common up some subexpressions that differ in their types, but not their representation. +.. ghc-flag:: -fspec-eval + :shortdesc: Enables speculative evaluation. + :type: dynamic + :category: + :reverse: -fno-spec-eval + + :default: on + :since: 9.14.1 + + Enables speculative evaluation which usually results in fewer allocations. + Enabling speculative evaluation should not cause performance regressions. + If you encounter any, please open a ticket. + + Note that disabling this flag will switch off speculative evaluation + completely, causing :ghc-flag:`-fspec-eval-dictfun` to have + no effect. + +.. ghc-flag:: -fspec-eval-dictfun + :shortdesc: Enables speculative evaluation of dictionary functions. + :type: dynamic + :category: + :reverse: -fno-spec-eval-dictfun + + :default: on + :since: 9.14.1 + + Enables speculative (strict) evaluation of dictionary functions. + + This is best explained with an example :: + + instance C a => D a where ... + + g :: D a => a -> Int + g x = ... + + f :: C a => a -> Int + f x = g x + + Function `f` has to pass a `D a` dictionary to `g`, and uses a dictionary + function `C a => D a` to compute it. If speculative evaluation for + dictionary functions is enabled, this dictionary is computed + strictly. + + Speculative evalation of dictionary functions can lead to slightly better + performance, because a thunk is avoided. However, it results in unnecessary + computation and allocation if the dictionary goes unused. This causes + a significant increase in allocation if the dictionary is large. + See (:ghc-ticket:`25284`). + .. ghc-flag:: -fdicts-cheap :shortdesc: Make dictionary-valued expressions seem cheap to the optimiser. :type: dynamic ===================================== m4/ghc_toolchain.m4 ===================================== @@ -187,6 +187,7 @@ AC_DEFUN([VALIDATE_GHC_TOOLCHAIN],[ "$GHC_TOOLCHAIN_BIN" format --input="$1" --output="$o1" "$GHC_TOOLCHAIN_BIN" format --input="$2" --output="$o2" diff_output=`diff "$o1" "$o2" 2>&1` + rm -f "$o1" "$o2" if test -z "$diff_output"; then true else ===================================== rts/Printer.c ===================================== @@ -151,13 +151,20 @@ printClosure( const StgClosure *obj ) case FUN_1_0: case FUN_0_1: case FUN_1_1: case FUN_0_2: case FUN_2_0: case FUN_STATIC: - debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); - printPtr((StgPtr)obj->header.info); + { + debugBelch("FUN/%d(",(int)itbl_to_fun_itbl(info)->f.arity); + printPtr((StgPtr)obj->header.info); + + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #if defined(PROFILING) - debugBelch(", %s", obj->header.prof.ccs->cc->label); + debugBelch(", %s", obj->header.prof.ccs->cc->label); #endif - printStdObjPayload(obj); - break; + printStdObjPayload(obj); + break; + } case PRIM: debugBelch("PRIM("); @@ -175,13 +182,19 @@ printClosure( const StgClosure *obj ) case THUNK_1_0: case THUNK_0_1: case THUNK_1_1: case THUNK_0_2: case THUNK_2_0: case THUNK_STATIC: + { /* ToDo: will this work for THUNK_STATIC too? */ #if defined(PROFILING) printThunkObject((StgThunk *)obj,GET_PROF_DESC(info)); #else printThunkObject((StgThunk *)obj,"THUNK"); + InfoProvEnt ipe; + if (lookupIPE(obj->header.info, &ipe)) { + debugBelch(", %s", ipe.prov.table_name); + } #endif break; + } case THUNK_SELECTOR: printStdObjHdr(obj, "THUNK_SELECTOR"); ===================================== rts/xxhash.h ===================================== @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (C) 2012-2021 Yann Collet + * Copyright (C) 2012-2023 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * @@ -130,6 +130,7 @@ * } * @endcode * + * * @anchor streaming_example * **Streaming** * @@ -165,6 +166,77 @@ * } * @endcode * + * Streaming functions generate the xxHash value from an incremental input. + * This method is slower than single-call functions, due to state management. + * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. + * + * An XXH state must first be allocated using `XXH*_createState()`. + * + * Start a new hash by initializing the state with a seed using `XXH*_reset()`. + * + * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. + * + * The function returns an error code, with 0 meaning OK, and any other value + * meaning there is an error. + * + * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. + * This function returns the nn-bits hash as an int or long long. + * + * It's still possible to continue inserting input into the hash state after a + * digest, and generate new hash values later on by invoking `XXH*_digest()`. + * + * When done, release the state using `XXH*_freeState()`. + * + * + * @anchor canonical_representation_example + * **Canonical Representation** + * + * The default return values from XXH functions are unsigned 32, 64 and 128 bit + * integers. + * This the simplest and fastest format for further post-processing. + * + * However, this leaves open the question of what is the order on the byte level, + * since little and big endian conventions will store the same number differently. + * + * The canonical representation settles this issue by mandating big-endian + * convention, the same convention as human-readable numbers (large digits first). + * + * When writing hash values to storage, sending them over a network, or printing + * them, it's highly recommended to use the canonical representation to ensure + * portability across a wider range of systems, present and future. + * + * The following functions allow transformation of hash values to and from + * canonical format. + * + * XXH32_canonicalFromHash(), XXH32_hashFromCanonical(), + * XXH64_canonicalFromHash(), XXH64_hashFromCanonical(), + * XXH128_canonicalFromHash(), XXH128_hashFromCanonical(), + * + * @code{.c} + * #include + * #include "xxhash.h" + * + * // Example for a function which prints XXH32_hash_t in human readable format + * void printXxh32(XXH32_hash_t hash) + * { + * XXH32_canonical_t cano; + * XXH32_canonicalFromHash(&cano, hash); + * size_t i; + * for(i = 0; i < sizeof(cano.digest); ++i) { + * printf("%02x", cano.digest[i]); + * } + * printf("\n"); + * } + * + * // Example for a function which converts XXH32_canonical_t to XXH32_hash_t + * XXH32_hash_t convertCanonicalToXxh32(XXH32_canonical_t cano) + * { + * XXH32_hash_t hash = XXH32_hashFromCanonical(&cano); + * return hash; + * } + * @endcode + * + * * @file xxhash.h * xxHash prototypes and implementation */ @@ -261,7 +333,7 @@ extern "C" { /* make all functions private */ # undef XXH_PUBLIC_API # if defined(__GNUC__) -# define XXH_PUBLIC_API static __inline __attribute__((unused)) +# define XXH_PUBLIC_API static __inline __attribute__((__unused__)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # define XXH_PUBLIC_API static inline # elif defined(_MSC_VER) @@ -373,7 +445,7 @@ extern "C" { /*! @brief Marks a global symbol. */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -449,7 +521,7 @@ extern "C" { /* specific declaration modes for Windows */ #if !defined(XXH_INLINE_ALL) && !defined(XXH_PRIVATE_API) -# if defined(WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) +# if defined(_WIN32) && defined(_MSC_VER) && (defined(XXH_IMPORT) || defined(XXH_EXPORT)) # ifdef XXH_EXPORT # define XXH_PUBLIC_API __declspec(dllexport) # elif XXH_IMPORT @@ -461,9 +533,9 @@ extern "C" { #endif #if defined (__GNUC__) -# define XXH_CONSTF __attribute__((const)) -# define XXH_PUREF __attribute__((pure)) -# define XXH_MALLOCF __attribute__((malloc)) +# define XXH_CONSTF __attribute__((__const__)) +# define XXH_PUREF __attribute__((__pure__)) +# define XXH_MALLOCF __attribute__((__malloc__)) #else # define XXH_CONSTF /* disable */ # define XXH_PUREF @@ -475,7 +547,7 @@ extern "C" { ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 8 -#define XXH_VERSION_RELEASE 2 +#define XXH_VERSION_RELEASE 3 /*! @brief Version number, encoded as two digits each */ #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) @@ -517,7 +589,11 @@ typedef uint32_t XXH32_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint32_t XXH32_hash_t; #else @@ -551,10 +627,6 @@ typedef uint32_t XXH32_hash_t; /*! * @brief Calculates the 32-bit hash of @p input using xxHash32. * - * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark): 5.4 GB/s - * - * See @ref single_shot_example "Single Shot Example" for an example. - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 32-bit seed to alter the hash's output predictably. @@ -564,63 +636,44 @@ typedef uint32_t XXH32_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 32-bit hash value. + * @return The calculated 32-bit xxHash32 value. * - * @see - * XXH64(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH32_createState(), XXH32_update(), XXH32_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32 (const void* input, size_t length, XXH32_hash_t seed); #ifndef XXH_NO_STREAM -/*! - * Streaming functions generate the xxHash value from an incremental input. - * This method is slower than single-call functions, due to state management. - * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. - * - * An XXH state must first be allocated using `XXH*_createState()`. - * - * Start a new hash by initializing the state with a seed using `XXH*_reset()`. - * - * Then, feed the hash state by calling `XXH*_update()` as many times as necessary. - * - * The function returns an error code, with 0 meaning OK, and any other value - * meaning there is an error. - * - * Finally, a hash value can be produced anytime, by using `XXH*_digest()`. - * This function returns the nn-bits hash as an int or long long. - * - * It's still possible to continue inserting input into the hash state after a - * digest, and generate new hash values later on by invoking `XXH*_digest()`. - * - * When done, release the state using `XXH*_freeState()`. - * - * @see streaming_example at the top of @ref xxhash.h for an example. - */ - /*! * @typedef struct XXH32_state_s XXH32_state_t * @brief The opaque state struct for the XXH32 streaming API. * * @see XXH32_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH32_state_s XXH32_state_t; /*! * @brief Allocates an @ref XXH32_state_t. * - * Must be freed with XXH32_freeState(). - * @return An allocated XXH32_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH32_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH32_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH32_state_t* XXH32_createState(void); /*! * @brief Frees an @ref XXH32_state_t. * - * Must be allocated with XXH32_createState(). * @param statePtr A pointer to an @ref XXH32_state_t allocated with @ref XXH32_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH32_createState(). + * + * @see @ref streaming_example "Streaming Example" + * */ XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); /*! @@ -636,23 +689,24 @@ XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* dst_state, const XXH32_state_ /*! * @brief Resets an @ref XXH32_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH32_update(). - * * @param statePtr The state struct to reset. * @param seed The 32-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH32_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH32_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -664,48 +718,36 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, XXH32_hash_t * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH32_state_t. * - * @note - * Calling XXH32_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash32 value from that state. + * @return The calculated 32-bit xxHash32 value from that state. + * + * @note + * Calling XXH32_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr); #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/* - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * This the simplest and fastest format for further post-processing. - * - * However, this leaves open the question of what is the order on the byte level, - * since little and big endian conventions will store the same number differently. - * - * The canonical representation settles this issue by mandating big-endian - * convention, the same convention as human-readable numbers (large digits first). - * - * When writing hash values to storage, sending them over a network, or printing - * them, it's highly recommended to use the canonical representation to ensure - * portability across a wider range of systems, present and future. - * - * The following functions allow transformation of hash values to and from - * canonical format. - */ - /*! * @brief Canonical (big endian) representation of @ref XXH32_hash_t. */ @@ -716,11 +758,13 @@ typedef struct { /*! * @brief Converts an @ref XXH32_hash_t to a big endian @ref XXH32_canonical_t. * - * @param dst The @ref XXH32_canonical_t pointer to be stored to. + * @param dst The @ref XXH32_canonical_t pointer to be stored to. * @param hash The @ref XXH32_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash); @@ -733,6 +777,8 @@ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src); @@ -794,7 +840,7 @@ XXH_PUBLIC_API XXH_PUREF XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canoni * As of writing this, only supported by clang. */ #if XXH_HAS_ATTRIBUTE(noescape) -# define XXH_NOESCAPE __attribute__((noescape)) +# define XXH_NOESCAPE __attribute__((__noescape__)) #else # define XXH_NOESCAPE #endif @@ -821,7 +867,11 @@ typedef uint64_t XXH64_hash_t; #elif !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include +# ifdef _AIX +# include +# else +# include +# endif typedef uint64_t XXH64_hash_t; #else # include @@ -851,9 +901,6 @@ typedef uint64_t XXH64_hash_t; /*! * @brief Calculates the 64-bit hash of @p input using xxHash64. * - * This function usually runs faster on 64-bit systems, but slower on 32-bit - * systems (see benchmark). - * * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. * @param seed The 64-bit seed to alter the hash's output predictably. @@ -863,13 +910,9 @@ typedef uint64_t XXH64_hash_t; * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return The calculated 64-bit hash. + * @return The calculated 64-bit xxHash64 value. * - * @see - * XXH32(), XXH3_64bits_withSeed(), XXH3_128bits_withSeed(), XXH128(): - * Direct equivalents for the other variants of xxHash. - * @see - * XXH64_createState(), XXH64_update(), XXH64_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -879,23 +922,32 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64(XXH_NOESCAPE const void* input, size * @brief The opaque state struct for the XXH64 streaming API. * * @see XXH64_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ /*! * @brief Allocates an @ref XXH64_state_t. * - * Must be freed with XXH64_freeState(). - * @return An allocated XXH64_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH64_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH64_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_MALLOCF XXH64_state_t* XXH64_createState(void); /*! * @brief Frees an @ref XXH64_state_t. * - * Must be allocated with XXH64_createState(). * @param statePtr A pointer to an @ref XXH64_state_t allocated with @ref XXH64_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note @p statePtr must be allocated with XXH64_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); @@ -912,23 +964,24 @@ XXH_PUBLIC_API void XXH64_copyState(XXH_NOESCAPE XXH64_state_t* dst_state, const /*! * @brief Resets an @ref XXH64_state_t to begin a new hash. * - * This function resets and seeds a state. Call it before @ref XXH64_update(). - * * @param statePtr The state struct to reset. * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note This function resets and seeds a state. Call it before @ref XXH64_update(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed); /*! * @brief Consumes a block of @p input to an @ref XXH64_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -940,23 +993,30 @@ XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH_NOESCAPE XXH64_state_t* statePtr, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH_NOESCAPE XXH64_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated hash value from an @ref XXH64_state_t. * - * @note - * Calling XXH64_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * - * @return The calculated xxHash64 value from that state. + * @return The calculated 64-bit xxHash64 value from that state. + * + * @note + * Calling XXH64_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_digest (XXH_NOESCAPE const XXH64_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -975,6 +1035,8 @@ typedef struct { unsigned char digest[sizeof(XXH64_hash_t)]; } XXH64_canonical_t * * @pre * @p dst must not be `NULL`. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, XXH64_hash_t hash); @@ -987,6 +1049,8 @@ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH_NOESCAPE XXH64_canonical_t* dst, * @p src must not be `NULL`. * * @return The converted hash. + * + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_canonical_t* src); @@ -1046,40 +1110,74 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const * * The API supports one-shot hashing, streaming mode, and custom secrets. */ + +/*! + * @ingroup tuning + * @brief Possible values for @ref XXH_VECTOR. + * + * Unless set explicitly, determined automatically. + */ +# define XXH_SCALAR 0 /*!< Portable scalar version */ +# define XXH_SSE2 1 /*!< SSE2 for Pentium 4, Opteron, all x86_64. */ +# define XXH_AVX2 2 /*!< AVX2 for Haswell and Bulldozer */ +# define XXH_AVX512 3 /*!< AVX512 for Skylake and Icelake */ +# define XXH_NEON 4 /*!< NEON for most ARMv7-A, all AArch64, and WASM SIMD128 */ +# define XXH_VSX 5 /*!< VSX and ZVector for POWER8/z13 (64-bit) */ +# define XXH_SVE 6 /*!< SVE for some ARMv8-A and ARMv9-A */ +# define XXH_LSX 7 /*!< LSX (128-bit SIMD) for LoongArch64 */ + + /*-********************************************************************** * XXH3 64-bit variant ************************************************************************/ /*! - * @brief 64-bit unseeded variant of XXH3. + * @brief Calculates 64-bit unseeded variant of XXH3 hash of @p input. * - * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of 0, however - * it may have slightly better performance due to constant propagation of the - * defaults. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @note + * This is equivalent to @ref XXH3_64bits_withSeed() with a seed of `0`, however + * it may have slightly better performance due to constant propagation of the + * defaults. * - * @see - * XXH32(), XXH64(), XXH3_128bits(): equivalent for the other xxHash algorithms * @see * XXH3_64bits_withSeed(), XXH3_64bits_withSecret(): other seeding variants - * @see - * XXH3_64bits_reset(), XXH3_64bits_update(), XXH3_64bits_digest(): Streaming version. + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits(XXH_NOESCAPE const void* input, size_t length); /*! - * @brief 64-bit seeded variant of XXH3 + * @brief Calculates 64-bit seeded variant of XXH3 hash of @p input. * - * This variant generates a custom secret on the fly based on default secret - * altered using the `seed` value. + * @param input The block of data to be hashed, at least @p length bytes in size. + * @param length The length of @p input, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. * - * While this operation is decently fast, note that it's not completely free. + * @pre + * The memory between @p input and @p input + @p length must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p input may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 64-bit XXH3 hash value. * * @note * seed == 0 produces the same results as @ref XXH3_64bits(). * - * @param input The data to hash - * @param length The length - * @param seed The 64-bit seed to alter the state. + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const void* input, size_t length, XXH64_hash_t seed); @@ -1093,22 +1191,36 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSeed(XXH_NOESCAPE const vo #define XXH3_SECRET_SIZE_MIN 136 /*! - * @brief 64-bit variant of XXH3 with a custom "secret". + * @brief Calculates 64-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 64-bit XXH3 hash value. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p length is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. * * It's possible to provide any blob of bytes as a "secret" to generate the hash. * This makes it more difficult for an external actor to prepare an intentional collision. - * The main condition is that secretSize *must* be large enough (>= XXH3_SECRET_SIZE_MIN). + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). * However, the quality of the secret impacts the dispersion of the hash algorithm. * Therefore, the secret _must_ look like a bunch of random bytes. * Avoid "trivial" or structured data such as repeated sequences or a text document. * Whenever in doubt about the "randomness" of the blob of bytes, - * consider employing "XXH3_generateSecret()" instead (see below). + * consider employing @ref XXH3_generateSecret() instead (see below). * It will generate a proper high entropy secret derived from the blob of bytes. * Another advantage of using XXH3_generateSecret() is that * it guarantees that all bits within the initial blob of bytes * will impact every bit of the output. * This is not necessarily the case when using the blob of bytes directly * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); @@ -1123,9 +1235,10 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecret(XXH_NOESCAPE const */ /*! - * @brief The state struct for the XXH3 streaming API. + * @brief The opaque state struct for the XXH3 streaming API. * * @see XXH3_state_s for details. + * @see @ref streaming_example "Streaming Example" */ typedef struct XXH3_state_s XXH3_state_t; XXH_PUBLIC_API XXH_MALLOCF XXH3_state_t* XXH3_createState(void); @@ -1144,15 +1257,20 @@ XXH_PUBLIC_API void XXH3_copyState(XXH_NOESCAPE XXH3_state_t* dst_state, XXH_NOE /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); @@ -1160,36 +1278,54 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset(XXH_NOESCAPE XXH3_state_t* stateP /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_64bits_update(). - * Digest will be equivalent to `XXH3_64bits_withSeed()`. - * * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param seed The 64-bit seed to alter the hash result predictably. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call this function before @ref XXH3_64bits_update(). + * - Digest will be equivalent to `XXH3_64bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" * */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); /*! - * XXH3_64bits_reset_withSecret(): - * `secret` is referenced, it _must outlive_ the hash streaming session. - * Similar to one-shot API, `secretSize` must be >= `XXH3_SECRET_SIZE_MIN`, + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * `secret` is referenced, it _must outlive_ the hash streaming session. + * + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, * and the quality of produced hash values depends on secret's entropy * (secret's content should look like a bunch of random bytes). * When in doubt about the randomness of a candidate `secret`, * consider employing `XXH3_generateSecret()` instead (see below). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! * @brief Consumes a block of @p input to an @ref XXH3_state_t. * - * Call this to incrementally consume blocks of data. - * * @param statePtr The state struct to update. * @param input The block of data to be hashed, at least @p length bytes in size. * @param length The length of @p input, in bytes. @@ -1201,23 +1337,30 @@ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecret(XXH_NOESCAPE XXH3_stat * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note Call this to incrementally consume blocks of data. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 64-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 64-bit hash value from that state. + * + * @note + * Calling XXH3_64bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1242,26 +1385,71 @@ typedef struct { } XXH128_hash_t; /*! - * @brief Unseeded 128-bit variant of XXH3 + * @brief Calculates 128-bit unseeded variant of XXH3 of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. * * The 128-bit variant of XXH3 has more strength, but it has a bit of overhead * for shorter inputs. * - * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of 0, however + * This is equivalent to @ref XXH3_128bits_withSeed() with a seed of `0`, however * it may have slightly better performance due to constant propagation of the * defaults. * - * @see - * XXH32(), XXH64(), XXH3_64bits(): equivalent for the other xxHash algorithms - * @see - * XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants - * @see - * XXH3_128bits_reset(), XXH3_128bits_update(), XXH3_128bits_digest(): Streaming version. + * @see XXH3_128bits_withSeed(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits(XXH_NOESCAPE const void* data, size_t len); -/*! @brief Seeded 128-bit variant of XXH3. @see XXH3_64bits_withSeed(). */ +/*! @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p length bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * @note + * seed == 0 produces the same results as @ref XXH3_64bits(). + * + * This variant generates a custom secret on the fly based on default secret + * altered using the @p seed value. + * + * While this operation is decently fast, note that it's not completely free. + * + * @see XXH3_128bits(), XXH3_128bits_withSecret(): other seeding variants + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSeed(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH3_64bits_withSecret(). */ +/*! + * @brief Calculates 128-bit variant of XXH3 with a custom "secret". + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * + * @return The calculated 128-bit variant of XXH3 value. + * + * It's possible to provide any blob of bytes as a "secret" to generate the hash. + * This makes it more difficult for an external actor to prepare an intentional collision. + * The main condition is that @p secretSize *must* be large enough (>= @ref XXH3_SECRET_SIZE_MIN). + * However, the quality of the secret impacts the dispersion of the hash algorithm. + * Therefore, the secret _must_ look like a bunch of random bytes. + * Avoid "trivial" or structured data such as repeated sequences or a text document. + * Whenever in doubt about the "randomness" of the blob of bytes, + * consider employing @ref XXH3_generateSecret() instead (see below). + * It will generate a proper high entropy secret derived from the blob of bytes. + * Another advantage of using XXH3_generateSecret() is that + * it guarantees that all bits within the initial blob of bytes + * will impact every bit of the output. + * This is not necessarily the case when using the blob of bytes directly + * because, when hashing _small_ inputs, only a portion of the secret is employed. + * + * @see @ref single_shot_example "Single Shot Example" for an example. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize); /******* Streaming *******/ @@ -1281,36 +1469,65 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecret(XXH_NOESCAPE cons /*! * @brief Resets an @ref XXH3_state_t to begin a new hash. * - * This function resets `statePtr` and generate a secret with default parameters. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits()`. - * * @param statePtr The state struct to reset. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret with default parameters. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits()`. * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset(XXH_NOESCAPE XXH3_state_t* statePtr); /*! * @brief Resets an @ref XXH3_state_t with 64-bit seed to begin a new hash. * - * This function resets `statePtr` and generate a secret from `seed`. Call it before @ref XXH3_128bits_update(). - * Digest will be equivalent to `XXH3_128bits_withSeed()`. + * @param statePtr The state struct to reset. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * @pre + * @p statePtr must not be `NULL`. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note + * - This function resets `statePtr` and generate a secret from `seed`. + * - Call it before @ref XXH3_128bits_update(). + * - Digest will be equivalent to `XXH3_128bits_withSeed()`. + * + * @see @ref streaming_example "Streaming Example" + */ +XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. * - * @param statePtr The state struct to reset. - * @param seed The 64-bit seed to alter the state. + * @param statePtr The state struct to reset. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. * * @pre * @p statePtr must not be `NULL`. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * `secret` is referenced, it _must outlive_ the hash streaming session. + * Similar to one-shot API, `secretSize` must be >= @ref XXH3_SECRET_SIZE_MIN, + * and the quality of produced hash values depends on secret's entropy + * (secret's content should look like a bunch of random bytes). + * When in doubt about the randomness of a candidate `secret`, + * consider employing `XXH3_generateSecret()` instead (see below). * + * @see @ref streaming_example "Streaming Example" */ -XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH64_hash_t seed); -/*! @brief Custom secret 128-bit variant of XXH3. @see XXH_64bits_reset_withSecret(). */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize); /*! @@ -1324,28 +1541,32 @@ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecret(XXH_NOESCAPE XXH3_sta * * @pre * @p statePtr must not be `NULL`. - * @pre + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @note * The memory between @p input and @p input + @p length must be valid, * readable, contiguous memory. However, if @p length is `0`, @p input may be * `NULL`. In C++, this also must be *TriviallyCopyable*. * - * @return @ref XXH_OK on success, @ref XXH_ERROR on failure. */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_update (XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* input, size_t length); /*! * @brief Returns the calculated XXH3 128-bit hash value from an @ref XXH3_state_t. * - * @note - * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, - * digest, and update again. - * * @param statePtr The state struct to calculate the hash from. * * @pre * @p statePtr must not be `NULL`. * * @return The calculated XXH3 128-bit hash value from that state. + * + * @note + * Calling XXH3_128bits_digest() will not affect @p statePtr, so you can update, + * digest, and update again. + * */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_t* statePtr); #endif /* !XXH_NO_STREAM */ @@ -1355,18 +1576,27 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const X * Note: For better performance, these functions can be inlined using XXH_INLINE_ALL */ /*! - * XXH128_isEqual(): - * Return: 1 if `h1` and `h2` are equal, 0 if they are not. + * @brief Check equality of two XXH128_hash_t values + * + * @param h1 The 128-bit hash value. + * @param h2 Another 128-bit hash value. + * + * @return `1` if `h1` and `h2` are equal. + * @return `0` if they are not. */ XXH_PUBLIC_API XXH_PUREF int XXH128_isEqual(XXH128_hash_t h1, XXH128_hash_t h2); /*! * @brief Compares two @ref XXH128_hash_t + * * This comparator is compatible with stdlib's `qsort()`/`bsearch()`. * - * @return: >0 if *h128_1 > *h128_2 - * =0 if *h128_1 == *h128_2 - * <0 if *h128_1 < *h128_2 + * @param h128_1 Left-hand side value + * @param h128_2 Right-hand side value + * + * @return >0 if @p h128_1 > @p h128_2 + * @return =0 if @p h128_1 == @p h128_2 + * @return <0 if @p h128_1 < @p h128_2 */ XXH_PUBLIC_API XXH_PUREF int XXH128_cmp(XXH_NOESCAPE const void* h128_1, XXH_NOESCAPE const void* h128_2); @@ -1378,11 +1608,12 @@ typedef struct { unsigned char digest[sizeof(XXH128_hash_t)]; } XXH128_canonical /*! * @brief Converts an @ref XXH128_hash_t to a big endian @ref XXH128_canonical_t. * - * @param dst The @ref XXH128_canonical_t pointer to be stored to. + * @param dst The @ref XXH128_canonical_t pointer to be stored to. * @param hash The @ref XXH128_hash_t to be converted. * * @pre * @p dst must not be `NULL`. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* dst, XXH128_hash_t hash); @@ -1395,6 +1626,7 @@ XXH_PUBLIC_API void XXH128_canonicalFromHash(XXH_NOESCAPE XXH128_canonical_t* ds * @p src must not be `NULL`. * * @return The converted hash. + * @see @ref canonical_representation_example "Canonical Representation Example" */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE const XXH128_canonical_t* src); @@ -1440,9 +1672,9 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128_hashFromCanonical(XXH_NOESCAPE con struct XXH32_state_s { XXH32_hash_t total_len_32; /*!< Total length hashed, modulo 2^32 */ XXH32_hash_t large_len; /*!< Whether the hash is >= 16 (handles @ref total_len_32 overflow) */ - XXH32_hash_t v[4]; /*!< Accumulator lanes */ - XXH32_hash_t mem32[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[16]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem32 */ + XXH32_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[16]; /*!< Internal buffer for partial reads. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved; /*!< Reserved field. Do not read nor write to it. */ }; /* typedef'd to XXH32_state_t */ @@ -1463,9 +1695,9 @@ struct XXH32_state_s { */ struct XXH64_state_s { XXH64_hash_t total_len; /*!< Total length hashed. This is always 64-bit. */ - XXH64_hash_t v[4]; /*!< Accumulator lanes */ - XXH64_hash_t mem64[4]; /*!< Internal buffer for partial reads. Treated as unsigned char[32]. */ - XXH32_hash_t memsize; /*!< Amount of data in @ref mem64 */ + XXH64_hash_t acc[4]; /*!< Accumulator lanes */ + unsigned char buffer[32]; /*!< Internal buffer for partial reads.. */ + XXH32_hash_t bufferedSize; /*!< Amount of data in @ref buffer */ XXH32_hash_t reserved32; /*!< Reserved field, needed for padding anyways*/ XXH64_hash_t reserved64; /*!< Reserved field. Do not read or write to it. */ }; /* typedef'd to XXH64_state_t */ @@ -1473,8 +1705,7 @@ struct XXH64_state_s { #ifndef XXH_NO_XXH3 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) /* >= C11 */ -# include -# define XXH_ALIGN(n) alignas(n) +# define XXH_ALIGN(n) _Alignas(n) #elif defined(__cplusplus) && (__cplusplus >= 201103L) /* >= C++11 */ /* In C++ alignas() is a keyword */ # define XXH_ALIGN(n) alignas(n) @@ -1587,7 +1818,20 @@ struct XXH3_state_s { /*! - * simple alias to pre-selected XXH3_128bits variant + * @brief Calculates the 128-bit hash of @p data using XXH3. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param seed The 64-bit seed to alter the hash's output predictably. + * + * @pre + * The memory between @p data and @p data + @p len must be valid, + * readable, contiguous memory. However, if @p len is `0`, @p data may be + * `NULL`. In C++, this also must be *TriviallyCopyable*. + * + * @return The calculated 128-bit XXH3 value. + * + * @see @ref single_shot_example "Single Shot Example" for an example. */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, size_t len, XXH64_hash_t seed); @@ -1596,9 +1840,16 @@ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH128(XXH_NOESCAPE const void* data, siz /* Symbols defined below must be considered tied to a specific library version. */ /*! - * XXH3_generateSecret(): + * @brief Derive a high-entropy secret from any user-defined content, named customSeed. + * + * @param secretBuffer A writable buffer for derived high-entropy secret data. + * @param secretSize Size of secretBuffer, in bytes. Must be >= XXH3_SECRET_SIZE_MIN. + * @param customSeed A user-defined content. + * @param customSeedSize Size of customSeed, in bytes. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. * - * Derive a high-entropy secret from any user-defined content, named customSeed. * The generated secret can be used in combination with `*_withSecret()` functions. * The `_withSecret()` variants are useful to provide a higher level of protection * than 64-bit seed, as it becomes much more difficult for an external actor to @@ -1651,6 +1902,9 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer /*! * @brief Generate the same secret as the _withSeed() variants. * + * @param secretBuffer A writable buffer of @ref XXH3_SECRET_DEFAULT_SIZE bytes + * @param seed The 64-bit seed to alter the hash result predictably. + * * The generated secret can be used in combination with *`*_withSecret()` and `_withSecretandSeed()` variants. * @@ -1670,7 +1924,7 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * }; * // Fast, caches the seeded secret for future uses. * class HashFast { - * unsigned char secret[XXH3_SECRET_SIZE_MIN]; + * unsigned char secret[XXH3_SECRET_DEFAULT_SIZE]; * public: * HashFast(XXH64_hash_t s) { * XXH3_generateSecret_fromSeed(secret, seed); @@ -1682,15 +1936,26 @@ XXH_PUBLIC_API XXH_errorcode XXH3_generateSecret(XXH_NOESCAPE void* secretBuffer * } * }; * @endcode - * @param secretBuffer A writable buffer of @ref XXH3_SECRET_SIZE_MIN bytes - * @param seed The seed to seed the state. */ XXH_PUBLIC_API void XXH3_generateSecret_fromSeed(XXH_NOESCAPE void* secretBuffer, XXH64_hash_t seed); /*! - * These variants generate hash values using either - * @p seed for "short" keys (< XXH3_MIDSIZE_MAX = 240 bytes) - * or @p secret for "large" keys (>= XXH3_MIDSIZE_MAX). + * @brief Maximum size of "short" key in bytes. + */ +#define XXH3_MIDSIZE_MAX 240 + +/*! + * @brief Calculates 64/128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The block of data to be hashed, at least @p len bytes in size. + * @param len The length of @p data, in bytes. + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed The 64-bit seed to alter the hash result predictably. + * + * These variants generate hash values using either: + * - @p seed for "short" keys (< @ref XXH3_MIDSIZE_MAX = 240 bytes) + * - @p secret for "large" keys (>= @ref XXH3_MIDSIZE_MAX). * * This generally benefits speed, compared to `_withSeed()` or `_withSecret()`. * `_withSeed()` has to generate the secret on the fly for "large" keys. @@ -1717,22 +1982,71 @@ XXH_PUBLIC_API XXH_PUREF XXH64_hash_t XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* data, size_t len, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Calculates 128-bit seeded variant of XXH3 hash of @p data. + * + * @param data The memory segment to be hashed, at least @p len bytes in size. + * @param length The length of @p data, in bytes. + * @param secret The secret used to alter hash result predictably. + * @param secretSize The length of @p secret, in bytes (must be >= XXH3_SECRET_SIZE_MIN) + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(): contract is the same. + */ XXH_PUBLIC_API XXH_PUREF XXH128_hash_t XXH3_128bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #ifndef XXH_NO_STREAM -/*! @copydoc XXH3_64bits_withSecretandSeed() */ +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + */ XXH_PUBLIC_API XXH_errorcode XXH3_64bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); -/*! @copydoc XXH3_64bits_withSecretandSeed() */ + +/*! + * @brief Resets an @ref XXH3_state_t with secret data to begin a new hash. + * + * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). + * @param secret The secret data. + * @param secretSize The length of @p secret, in bytes. + * @param seed64 The 64-bit seed to alter the hash result predictably. + * + * @return @ref XXH_OK on success. + * @return @ref XXH_ERROR on failure. + * + * @see XXH3_64bits_withSecretandSeed(). Contract is identical. + * + * Note: there was a bug in an earlier version of this function (<= v0.8.2) + * that would make it generate an incorrect hash value + * when @p seed == 0 and @p length < XXH3_MIDSIZE_MAX + * and @p secret is different from XXH3_generateSecret_fromSeed(). + * As stated in the contract, the correct hash result must be + * the same as XXH3_128bits_withSeed() when @p length <= XXH3_MIDSIZE_MAX. + * Results generated by this older version are wrong, hence not comparable. + */ XXH_PUBLIC_API XXH_errorcode XXH3_128bits_reset_withSecretandSeed(XXH_NOESCAPE XXH3_state_t* statePtr, XXH_NOESCAPE const void* secret, size_t secretSize, XXH64_hash_t seed64); + #endif /* !XXH_NO_STREAM */ #endif /* !XXH_NO_XXH3 */ @@ -2100,15 +2414,15 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if XXH_NO_INLINE_HINTS /* disable inlining hints */ # if defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __attribute__((unused)) +# define XXH_FORCE_INLINE static __attribute__((__unused__)) # else # define XXH_FORCE_INLINE static # endif # define XXH_NO_INLINE static /* enable inlining hints */ #elif defined(__GNUC__) || defined(__clang__) -# define XXH_FORCE_INLINE static __inline__ __attribute__((always_inline, unused)) -# define XXH_NO_INLINE static __attribute__((noinline)) +# define XXH_FORCE_INLINE static __inline__ __attribute__((__always_inline__, __unused__)) +# define XXH_NO_INLINE static __attribute__((__noinline__)) #elif defined(_MSC_VER) /* Visual Studio */ # define XXH_FORCE_INLINE static __forceinline # define XXH_NO_INLINE static __declspec(noinline) @@ -2121,12 +2435,34 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) # define XXH_NO_INLINE static #endif +#if defined(XXH_INLINE_ALL) +# define XXH_STATIC XXH_FORCE_INLINE +#else +# define XXH_STATIC static +#endif + #if XXH3_INLINE_SECRET # define XXH3_WITH_SECRET_INLINE XXH_FORCE_INLINE #else # define XXH3_WITH_SECRET_INLINE XXH_NO_INLINE #endif +#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ +# define XXH_RESTRICT /* disable */ +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ +# define XXH_RESTRICT restrict +#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ + || (defined (__clang__)) \ + || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ + || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) +/* + * There are a LOT more compilers that recognize __restrict but this + * covers the major ones. + */ +# define XXH_RESTRICT __restrict +#else +# define XXH_RESTRICT /* disable */ +#endif /* ************************************* * Debug @@ -2206,10 +2542,14 @@ static void* XXH_memcpy(void* dest, const void* src, size_t size) #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) -# include - typedef uint8_t xxh_u8; +# ifdef _AIX +# include +# else +# include +# endif + typedef uint8_t xxh_u8; #else - typedef unsigned char xxh_u8; + typedef unsigned char xxh_u8; #endif typedef XXH32_hash_t xxh_u32; @@ -2295,11 +2635,11 @@ static xxh_u32 XXH_read32(const void* memPtr) { return *(const xxh_u32*) memPtr; * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; } __attribute__((packed)) unalign; +typedef union { xxh_u32 u32; } __attribute__((__packed__)) unalign; #endif static xxh_u32 XXH_read32(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u32 xxh_unalign32; + typedef __attribute__((__aligned__(1))) xxh_u32 xxh_unalign32; return *((const xxh_unalign32*)ptr); } @@ -2445,6 +2785,9 @@ static int XXH_isLittleEndian(void) && XXH_HAS_BUILTIN(__builtin_rotateleft64) # define XXH_rotl32 __builtin_rotateleft32 # define XXH_rotl64 __builtin_rotateleft64 +#elif XXH_HAS_BUILTIN(__builtin_stdc_rotate_left) +# define XXH_rotl32 __builtin_stdc_rotate_left +# define XXH_rotl64 __builtin_stdc_rotate_left /* Note: although _rotl exists for minGW (GCC under windows), performance seems poor */ #elif defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) @@ -2590,7 +2933,7 @@ static xxh_u32 XXH32_round(xxh_u32 acc, xxh_u32 input) #if (defined(__SSE4_1__) || defined(__aarch64__) || defined(__wasm_simd128__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) /* * UGLY HACK: - * A compiler fence is the only thing that prevents GCC and Clang from + * A compiler fence is used to prevent GCC and Clang from * autovectorizing the XXH32 loop (pragmas and attributes don't work for some * reason) without globally disabling SSE4.1. * @@ -2651,6 +2994,61 @@ static xxh_u32 XXH32_avalanche(xxh_u32 hash) #define XXH_get32bits(p) XXH_readLE32_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH32(). + */ +XXH_FORCE_INLINE void +XXH32_initAccs(xxh_u32 *acc, xxh_u32 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; + acc[1] = seed + XXH_PRIME32_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME32_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH32(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH32_consumeLong( + xxh_u32 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 15; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 16); + do { + acc[0] = XXH32_round(acc[0], XXH_get32bits(input)); input += 4; + acc[1] = XXH32_round(acc[1], XXH_get32bits(input)); input += 4; + acc[2] = XXH32_round(acc[2], XXH_get32bits(input)); input += 4; + acc[3] = XXH32_round(acc[3], XXH_get32bits(input)); input += 4; + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH32() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u32 +XXH32_mergeAccs(const xxh_u32 *acc) +{ + XXH_ASSERT(acc != NULL); + return XXH_rotl32(acc[0], 1) + XXH_rotl32(acc[1], 7) + + XXH_rotl32(acc[2], 12) + XXH_rotl32(acc[3], 18); +} + /*! * @internal * @brief Processes the last 0-15 bytes of @p ptr. @@ -2763,22 +3161,12 @@ XXH32_endian_align(const xxh_u8* input, size_t len, xxh_u32 seed, XXH_alignment if (input==NULL) XXH_ASSERT(len == 0); if (len>=16) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 15; - xxh_u32 v1 = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - xxh_u32 v2 = seed + XXH_PRIME32_2; - xxh_u32 v3 = seed + 0; - xxh_u32 v4 = seed - XXH_PRIME32_1; + xxh_u32 acc[4]; + XXH32_initAccs(acc, seed); - do { - v1 = XXH32_round(v1, XXH_get32bits(input)); input += 4; - v2 = XXH32_round(v2, XXH_get32bits(input)); input += 4; - v3 = XXH32_round(v3, XXH_get32bits(input)); input += 4; - v4 = XXH32_round(v4, XXH_get32bits(input)); input += 4; - } while (input < limit); - - h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) - + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); + input = XXH32_consumeLong(acc, input, len, align); + + h32 = XXH32_mergeAccs(acc); } else { h32 = seed + XXH_PRIME32_5; } @@ -2834,10 +3222,7 @@ XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, XXH32_hash_t s { XXH_ASSERT(statePtr != NULL); memset(statePtr, 0, sizeof(*statePtr)); - statePtr->v[0] = seed + XXH_PRIME32_1 + XXH_PRIME32_2; - statePtr->v[1] = seed + XXH_PRIME32_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME32_1; + XXH32_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -2851,45 +3236,37 @@ XXH32_update(XXH32_state_t* state, const void* input, size_t len) return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len_32 += (XXH32_hash_t)len; + state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); - state->total_len_32 += (XXH32_hash_t)len; - state->large_len |= (XXH32_hash_t)((len>=16) | (state->total_len_32>=16)); + XXH_ASSERT(state->bufferedSize < sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 16) { /* fill in tmp buffer */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, len); - state->memsize += (XXH32_hash_t)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* some data left from previous update */ - XXH_memcpy((xxh_u8*)(state->mem32) + state->memsize, input, 16-state->memsize); - { const xxh_u32* p32 = state->mem32; - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p32)); p32++; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p32)); p32++; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p32)); p32++; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p32)); - } - p += 16-state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer: complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* then process one round */ + (void)XXH32_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p <= bEnd-16) { - const xxh_u8* const limit = bEnd - 16; - - do { - state->v[0] = XXH32_round(state->v[0], XXH_readLE32(p)); p+=4; - state->v[1] = XXH32_round(state->v[1], XXH_readLE32(p)); p+=4; - state->v[2] = XXH32_round(state->v[2], XXH_readLE32(p)); p+=4; - state->v[3] = XXH32_round(state->v[3], XXH_readLE32(p)); p+=4; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH32_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem32, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -2903,36 +3280,20 @@ XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t* state) xxh_u32 h32; if (state->large_len) { - h32 = XXH_rotl32(state->v[0], 1) - + XXH_rotl32(state->v[1], 7) - + XXH_rotl32(state->v[2], 12) - + XXH_rotl32(state->v[3], 18); + h32 = XXH32_mergeAccs(state->acc); } else { - h32 = state->v[2] /* == seed */ + XXH_PRIME32_5; + h32 = state->acc[2] /* == seed */ + XXH_PRIME32_5; } h32 += state->total_len_32; - return XXH32_finalize(h32, (const xxh_u8*)state->mem32, state->memsize, XXH_aligned); + return XXH32_finalize(h32, state->buffer, state->bufferedSize, XXH_aligned); } #endif /* !XXH_NO_STREAM */ /******* Canonical representation *******/ -/*! - * @ingroup XXH32_family - * The default return values from XXH functions are unsigned 32 and 64 bit - * integers. - * - * The canonical representation uses big endian convention, the same convention - * as human-readable numbers (large digits first). - * - * This way, hash values can be written into a file or buffer, remaining - * comparable across different systems. - * - * The following functions allow transformation of hash values to and from their - * canonical format. - */ +/*! @ingroup XXH32_family */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); @@ -2987,11 +3348,11 @@ static xxh_u64 XXH_read64(const void* memPtr) * https://gcc.godbolt.org/z/xYez1j67Y. */ #ifdef XXH_OLD_NAMES -typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((packed)) unalign64; +typedef union { xxh_u32 u32; xxh_u64 u64; } __attribute__((__packed__)) unalign64; #endif static xxh_u64 XXH_read64(const void* ptr) { - typedef __attribute__((aligned(1))) xxh_u64 xxh_unalign64; + typedef __attribute__((__aligned__(1))) xxh_u64 xxh_unalign64; return *((const xxh_unalign64*)ptr); } @@ -3110,6 +3471,23 @@ static xxh_u64 XXH64_round(xxh_u64 acc, xxh_u64 input) acc += input * XXH_PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= XXH_PRIME64_1; +#if (defined(__AVX512F__)) && !defined(XXH_ENABLE_AUTOVECTORIZE) + /* + * DISABLE AUTOVECTORIZATION: + * A compiler fence is used to prevent GCC and Clang from + * autovectorizing the XXH64 loop (pragmas and attributes don't work for some + * reason) without globally disabling AVX512. + * + * Autovectorization of XXH64 tends to be detrimental, + * though the exact outcome may change depending on exact cpu and compiler version. + * For information, it has been reported as detrimental for Skylake-X, + * but possibly beneficial for Zen4. + * + * The default is to disable auto-vectorization, + * but you can select to enable it instead using `XXH_ENABLE_AUTOVECTORIZE` build variable. + */ + XXH_COMPILER_GUARD(acc); +#endif return acc; } @@ -3135,6 +3513,85 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) #define XXH_get64bits(p) XXH_readLE64_align(p, align) +/*! + * @internal + * @brief Sets up the initial accumulator state for XXH64(). + */ +XXH_FORCE_INLINE void +XXH64_initAccs(xxh_u64 *acc, xxh_u64 seed) +{ + XXH_ASSERT(acc != NULL); + acc[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; + acc[1] = seed + XXH_PRIME64_2; + acc[2] = seed + 0; + acc[3] = seed - XXH_PRIME64_1; +} + +/*! + * @internal + * @brief Consumes a block of data for XXH64(). + * + * @return the end input pointer. + */ +XXH_FORCE_INLINE const xxh_u8 * +XXH64_consumeLong( + xxh_u64 *XXH_RESTRICT acc, + xxh_u8 const *XXH_RESTRICT input, + size_t len, + XXH_alignment align +) +{ + const xxh_u8* const bEnd = input + len; + const xxh_u8* const limit = bEnd - 31; + XXH_ASSERT(acc != NULL); + XXH_ASSERT(input != NULL); + XXH_ASSERT(len >= 32); + do { + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + acc[i] = XXH64_round(acc[i], XXH_get64bits(input)); + input += 8; + } + } else { + acc[0] = XXH64_round(acc[0], XXH_get64bits(input)); input += 8; + acc[1] = XXH64_round(acc[1], XXH_get64bits(input)); input += 8; + acc[2] = XXH64_round(acc[2], XXH_get64bits(input)); input += 8; + acc[3] = XXH64_round(acc[3], XXH_get64bits(input)); input += 8; + } + } while (input < limit); + + return input; +} + +/*! + * @internal + * @brief Merges the accumulator lanes together for XXH64() + */ +XXH_FORCE_INLINE XXH_PUREF xxh_u64 +XXH64_mergeAccs(const xxh_u64 *acc) +{ + XXH_ASSERT(acc != NULL); + { + xxh_u64 h64 = XXH_rotl64(acc[0], 1) + XXH_rotl64(acc[1], 7) + + XXH_rotl64(acc[2], 12) + XXH_rotl64(acc[3], 18); + /* reroll on 32-bit */ + if (sizeof(void *) < sizeof(xxh_u64)) { + size_t i; + for (i = 0; i < 4; i++) { + h64 = XXH64_mergeRound(h64, acc[i]); + } + } else { + h64 = XXH64_mergeRound(h64, acc[0]); + h64 = XXH64_mergeRound(h64, acc[1]); + h64 = XXH64_mergeRound(h64, acc[2]); + h64 = XXH64_mergeRound(h64, acc[3]); + } + return h64; + } +} + /*! * @internal * @brief Processes the last 0-31 bytes of @p ptr. @@ -3150,7 +3607,7 @@ static xxh_u64 XXH64_avalanche(xxh_u64 hash) * @return The finalized hash * @see XXH32_finalize(). */ -static XXH_PUREF xxh_u64 +XXH_STATIC XXH_PUREF xxh_u64 XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len, XXH_alignment align) { if (ptr==NULL) XXH_ASSERT(len == 0); @@ -3200,27 +3657,13 @@ XXH64_endian_align(const xxh_u8* input, size_t len, xxh_u64 seed, XXH_alignment xxh_u64 h64; if (input==NULL) XXH_ASSERT(len == 0); - if (len>=32) { - const xxh_u8* const bEnd = input + len; - const xxh_u8* const limit = bEnd - 31; - xxh_u64 v1 = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - xxh_u64 v2 = seed + XXH_PRIME64_2; - xxh_u64 v3 = seed + 0; - xxh_u64 v4 = seed - XXH_PRIME64_1; + if (len>=32) { /* Process a large block of data */ + xxh_u64 acc[4]; + XXH64_initAccs(acc, seed); - do { - v1 = XXH64_round(v1, XXH_get64bits(input)); input+=8; - v2 = XXH64_round(v2, XXH_get64bits(input)); input+=8; - v3 = XXH64_round(v3, XXH_get64bits(input)); input+=8; - v4 = XXH64_round(v4, XXH_get64bits(input)); input+=8; - } while (inputv[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2; - statePtr->v[1] = seed + XXH_PRIME64_2; - statePtr->v[2] = seed + 0; - statePtr->v[3] = seed - XXH_PRIME64_1; + XXH64_initAccs(statePtr->acc, seed); return XXH_OK; } @@ -3292,42 +3732,36 @@ XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, return XXH_OK; } - { const xxh_u8* p = (const xxh_u8*)input; - const xxh_u8* const bEnd = p + len; + state->total_len += len; - state->total_len += len; + XXH_ASSERT(state->bufferedSize <= sizeof(state->buffer)); + if (len < sizeof(state->buffer) - state->bufferedSize) { /* fill in tmp buffer */ + XXH_memcpy(state->buffer + state->bufferedSize, input, len); + state->bufferedSize += (XXH32_hash_t)len; + return XXH_OK; + } - if (state->memsize + len < 32) { /* fill in tmp buffer */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, len); - state->memsize += (xxh_u32)len; - return XXH_OK; - } + { const xxh_u8* xinput = (const xxh_u8*)input; + const xxh_u8* const bEnd = xinput + len; - if (state->memsize) { /* tmp buffer is full */ - XXH_memcpy(((xxh_u8*)state->mem64) + state->memsize, input, 32-state->memsize); - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(state->mem64+0)); - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(state->mem64+1)); - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(state->mem64+2)); - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(state->mem64+3)); - p += 32 - state->memsize; - state->memsize = 0; + if (state->bufferedSize) { /* non-empty buffer => complete first */ + XXH_memcpy(state->buffer + state->bufferedSize, xinput, sizeof(state->buffer) - state->bufferedSize); + xinput += sizeof(state->buffer) - state->bufferedSize; + /* and process one round */ + (void)XXH64_consumeLong(state->acc, state->buffer, sizeof(state->buffer), XXH_aligned); + state->bufferedSize = 0; } - if (p+32 <= bEnd) { - const xxh_u8* const limit = bEnd - 32; - - do { - state->v[0] = XXH64_round(state->v[0], XXH_readLE64(p)); p+=8; - state->v[1] = XXH64_round(state->v[1], XXH_readLE64(p)); p+=8; - state->v[2] = XXH64_round(state->v[2], XXH_readLE64(p)); p+=8; - state->v[3] = XXH64_round(state->v[3], XXH_readLE64(p)); p+=8; - } while (p<=limit); - + XXH_ASSERT(xinput <= bEnd); + if ((size_t)(bEnd - xinput) >= sizeof(state->buffer)) { + /* Process the remaining data */ + xinput = XXH64_consumeLong(state->acc, xinput, (size_t)(bEnd - xinput), XXH_unaligned); } - if (p < bEnd) { - XXH_memcpy(state->mem64, p, (size_t)(bEnd-p)); - state->memsize = (unsigned)(bEnd-p); + if (xinput < bEnd) { + /* Copy the leftover to the tmp buffer */ + XXH_memcpy(state->buffer, xinput, (size_t)(bEnd-xinput)); + state->bufferedSize = (unsigned)(bEnd-xinput); } } @@ -3341,18 +3775,14 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_digest(XXH_NOESCAPE const XXH64_state_t* state xxh_u64 h64; if (state->total_len >= 32) { - h64 = XXH_rotl64(state->v[0], 1) + XXH_rotl64(state->v[1], 7) + XXH_rotl64(state->v[2], 12) + XXH_rotl64(state->v[3], 18); - h64 = XXH64_mergeRound(h64, state->v[0]); - h64 = XXH64_mergeRound(h64, state->v[1]); - h64 = XXH64_mergeRound(h64, state->v[2]); - h64 = XXH64_mergeRound(h64, state->v[3]); + h64 = XXH64_mergeAccs(state->acc); } else { - h64 = state->v[2] /*seed*/ + XXH_PRIME64_5; + h64 = state->acc[2] /*seed*/ + XXH_PRIME64_5; } h64 += (xxh_u64) state->total_len; - return XXH64_finalize(h64, (const xxh_u8*)state->mem64, (size_t)state->total_len, XXH_aligned); + return XXH64_finalize(h64, state->buffer, (size_t)state->total_len, XXH_aligned); } #endif /* !XXH_NO_STREAM */ @@ -3387,22 +3817,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can /* === Compiler specifics === */ -#if ((defined(sun) || defined(__sun)) && __cplusplus) /* Solaris includes __STDC_VERSION__ with C++. Tested with GCC 5.5 */ -# define XXH_RESTRICT /* disable */ -#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* >= C99 */ -# define XXH_RESTRICT restrict -#elif (defined (__GNUC__) && ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) \ - || (defined (__clang__)) \ - || (defined (_MSC_VER) && (_MSC_VER >= 1400)) \ - || (defined (__INTEL_COMPILER) && (__INTEL_COMPILER >= 1300)) -/* - * There are a LOT more compilers that recognize __restrict but this - * covers the major ones. - */ -# define XXH_RESTRICT __restrict -#else -# define XXH_RESTRICT /* disable */ -#endif #if (defined(__GNUC__) && (__GNUC__ >= 3)) \ || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) \ @@ -3416,7 +3830,11 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can #ifndef XXH_HAS_INCLUDE # ifdef __has_include -# define XXH_HAS_INCLUDE(x) __has_include(x) +/* + * Not defined as XXH_HAS_INCLUDE(x) (function-like) because + * this causes segfaults in Apple Clang 4.2 (on Mac OS X 10.7 Lion) + */ +# define XXH_HAS_INCLUDE __has_include # else # define XXH_HAS_INCLUDE(x) 0 # endif @@ -3437,6 +3855,8 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can # include # elif defined(__SSE2__) # include +# elif defined(__loongarch_sx) +# include # endif #endif @@ -3533,33 +3953,6 @@ XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(XXH_NOESCAPE const XXH64_can * implementation. */ # define XXH_VECTOR XXH_SCALAR -/*! - * @ingroup tuning - * @brief Possible values for @ref XXH_VECTOR. - * - * Note that these are actually implemented as macros. - * - * If this is not defined, it is detected automatically. - * internal macro XXH_X86DISPATCH overrides this. - */ -enum XXH_VECTOR_TYPE /* fake enum */ { - XXH_SCALAR = 0, /*!< Portable scalar version */ - XXH_SSE2 = 1, /*!< - * SSE2 for Pentium 4, Opteron, all x86_64. - * - * @note SSE2 is also guaranteed on Windows 10, macOS, and - * Android x86. - */ - XXH_AVX2 = 2, /*!< AVX2 for Haswell and Bulldozer */ - XXH_AVX512 = 3, /*!< AVX512 for Skylake and Icelake */ - XXH_NEON = 4, /*!< - * NEON for most ARMv7-A, all AArch64, and WASM SIMD128 - * via the SIMDeverywhere polyfill provided with the - * Emscripten SDK. - */ - XXH_VSX = 5, /*!< VSX and ZVector for POWER8/z13 (64-bit) */ - XXH_SVE = 6, /*!< SVE for some ARMv8-A and ARMv9-A */ -}; /*! * @ingroup tuning * @brief Selects the minimum alignment for XXH3's accumulators. @@ -3574,13 +3967,6 @@ enum XXH_VECTOR_TYPE /* fake enum */ { /* Actual definition */ #ifndef XXH_DOXYGEN -# define XXH_SCALAR 0 -# define XXH_SSE2 1 -# define XXH_AVX2 2 -# define XXH_AVX512 3 -# define XXH_NEON 4 -# define XXH_VSX 5 -# define XXH_SVE 6 #endif #ifndef XXH_VECTOR /* can be defined on command line */ @@ -3605,6 +3991,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { || (defined(__s390x__) && defined(__VEC__)) \ && defined(__GNUC__) /* TODO: IBM XL */ # define XXH_VECTOR XXH_VSX +# elif defined(__loongarch_sx) +# define XXH_VECTOR XXH_LSX # else # define XXH_VECTOR XXH_SCALAR # endif @@ -3642,6 +4030,8 @@ enum XXH_VECTOR_TYPE /* fake enum */ { # define XXH_ACC_ALIGN 64 # elif XXH_VECTOR == XXH_SVE /* sve */ # define XXH_ACC_ALIGN 64 +# elif XXH_VECTOR == XXH_LSX /* lsx */ +# define XXH_ACC_ALIGN 64 # endif #endif @@ -3655,7 +4045,7 @@ enum XXH_VECTOR_TYPE /* fake enum */ { #endif #if defined(__GNUC__) || defined(__clang__) -# define XXH_ALIASING __attribute__((may_alias)) +# define XXH_ALIASING __attribute__((__may_alias__)) #else # define XXH_ALIASING /* nothing */ #endif @@ -4408,8 +4798,6 @@ XXH3_len_17to128_64b(const xxh_u8* XXH_RESTRICT input, size_t len, } } -#define XXH3_MIDSIZE_MAX 240 - XXH_NO_INLINE XXH_PUREF XXH64_hash_t XXH3_len_129to240_64b(const xxh_u8* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -5281,6 +5669,71 @@ XXH3_accumulate_sve(xxh_u64* XXH_RESTRICT acc, #endif +#if (XXH_VECTOR == XXH_LSX) +#define _LSX_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) + +XXH_FORCE_INLINE void +XXH3_accumulate_512_lsx( void* XXH_RESTRICT acc, + const void* XXH_RESTRICT input, + const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i *) acc; + const __m128i* const xinput = (const __m128i *) input; + const __m128i* const xsecret = (const __m128i *) secret; + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* data_vec = xinput[i]; */ + __m128i const data_vec = __lsx_vld(xinput + i, 0); + /* key_vec = xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + /* data_key = data_vec ^ key_vec; */ + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + /* data_key_lo = data_key >> 32; */ + __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + // __m128i const data_key_lo = __lsx_vsrli_d(data_key, 32); + /* product = (data_key & 0xffffffff) * (data_key_lo & 0xffffffff); */ + __m128i const product = __lsx_vmulwev_d_wu(data_key, data_key_lo); + /* xacc[i] += swap(data_vec); */ + __m128i const data_swap = __lsx_vshuf4i_w(data_vec, _LSX_SHUFFLE(1, 0, 3, 2)); + __m128i const sum = __lsx_vadd_d(xacc[i], data_swap); + /* xacc[i] += product; */ + xacc[i] = __lsx_vadd_d(product, sum); + } + } +} +XXH_FORCE_INLINE XXH3_ACCUMULATE_TEMPLATE(lsx) + +XXH_FORCE_INLINE void +XXH3_scrambleAcc_lsx(void* XXH_RESTRICT acc, const void* XXH_RESTRICT secret) +{ + XXH_ASSERT((((size_t)acc) & 15) == 0); + { + __m128i* const xacc = (__m128i*) acc; + const __m128i* const xsecret = (const __m128i *) secret; + const __m128i prime32 = __lsx_vreplgr2vr_w((int)XXH_PRIME32_1); + + for (size_t i = 0; i < XXH_STRIPE_LEN / sizeof(__m128i); i++) { + /* xacc[i] ^= (xacc[i] >> 47) */ + __m128i const acc_vec = xacc[i]; + __m128i const shifted = __lsx_vsrli_d(acc_vec, 47); + __m128i const data_vec = __lsx_vxor_v(acc_vec, shifted); + /* xacc[i] ^= xsecret[i]; */ + __m128i const key_vec = __lsx_vld(xsecret + i, 0); + __m128i const data_key = __lsx_vxor_v(data_vec, key_vec); + + /* xacc[i] *= XXH_PRIME32_1; */ + __m128i const data_key_hi = __lsx_vsrli_d(data_key, 32); + __m128i const prod_lo = __lsx_vmulwev_d_wu(data_key, prime32); + __m128i const prod_hi = __lsx_vmulwev_d_wu(data_key_hi, prime32); + xacc[i] = __lsx_vadd_d(prod_lo, __lsx_vslli_d(prod_hi, 32)); + } + } +} + +#endif + /* scalar variants - universal */ #if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) @@ -5511,6 +5964,12 @@ typedef void (*XXH3_f_initCustomSecret)(void* XXH_RESTRICT, xxh_u64); #define XXH3_scrambleAcc XXH3_scrambleAcc_scalar #define XXH3_initCustomSecret XXH3_initCustomSecret_scalar +#elif (XXH_VECTOR == XXH_LSX) +#define XXH3_accumulate_512 XXH3_accumulate_512_lsx +#define XXH3_accumulate XXH3_accumulate_lsx +#define XXH3_scrambleAcc XXH3_scrambleAcc_lsx +#define XXH3_initCustomSecret XXH3_initCustomSecret_scalar + #else /* scalar */ #define XXH3_accumulate_512 XXH3_accumulate_512_scalar @@ -5566,7 +6025,7 @@ XXH3_mix2Accs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret acc[1] ^ XXH_readLE64(secret+8) ); } -static XXH64_hash_t +static XXH_PUREF XXH64_hash_t XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 start) { xxh_u64 result64 = start; @@ -5593,6 +6052,15 @@ XXH3_mergeAccs(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secre return XXH3_avalanche(result64); } +/* do not align on 8, so that the secret is different from the accumulator */ +#define XXH_SECRET_MERGEACCS_START 11 + +static XXH_PUREF XXH64_hash_t +XXH3_finalizeLong_64b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, xxh_u64 len) +{ + return XXH3_mergeAccs(acc, secret + XXH_SECRET_MERGEACCS_START, len * XXH_PRIME64_1); +} + #define XXH3_INIT_ACC { XXH_PRIME32_3, XXH_PRIME64_1, XXH_PRIME64_2, XXH_PRIME64_3, \ XXH_PRIME64_4, XXH_PRIME32_2, XXH_PRIME64_5, XXH_PRIME32_1 } @@ -5608,10 +6076,8 @@ XXH3_hashLong_64b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); - /* do not align on 8, so that the secret is different from the accumulator */ -#define XXH_SECRET_MERGEACCS_START 11 XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - return XXH3_mergeAccs(acc, (const xxh_u8*)secret + XXH_SECRET_MERGEACCS_START, (xxh_u64)len * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, (const xxh_u8*)secret, (xxh_u64)len); } /* @@ -5747,7 +6213,7 @@ XXH3_64bits_withSecretandSeed(XXH_NOESCAPE const void* input, size_t length, XXH /* === XXH3 streaming === */ #ifndef XXH_NO_STREAM /* - * Malloc's a pointer that is always aligned to align. + * Malloc's a pointer that is always aligned to @align. * * This must be freed with `XXH_alignedFree()`. * @@ -5815,8 +6281,12 @@ static void XXH_alignedFree(void* p) /*! * @brief Allocate an @ref XXH3_state_t. * - * Must be freed with XXH3_freeState(). - * @return An allocated XXH3_state_t on success, `NULL` on failure. + * @return An allocated pointer of @ref XXH3_state_t on success. + * @return `NULL` on failure. + * + * @note Must be freed with XXH3_freeState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) { @@ -5830,9 +6300,13 @@ XXH_PUBLIC_API XXH3_state_t* XXH3_createState(void) /*! * @brief Frees an @ref XXH3_state_t. * - * Must be allocated with XXH3_createState(). * @param statePtr A pointer to an @ref XXH3_state_t allocated with @ref XXH3_createState(). - * @return XXH_OK. + * + * @return @ref XXH_OK. + * + * @note Must be allocated with XXH3_createState(). + * + * @see @ref streaming_example "Streaming Example" */ XXH_PUBLIC_API XXH_errorcode XXH3_freeState(XXH3_state_t* statePtr) { @@ -6111,9 +6585,7 @@ XXH_PUBLIC_API XXH64_hash_t XXH3_64bits_digest (XXH_NOESCAPE const XXH3_state_t* if (state->totalLen > XXH3_MIDSIZE_MAX) { XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); - return XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); + return XXH3_finalizeLong_64b(acc, secret, (xxh_u64)state->totalLen); } /* totalLen <= XXH3_MIDSIZE_MAX: digesting a short input */ if (state->useSeed) @@ -6405,6 +6877,17 @@ XXH3_len_129to240_128b(const xxh_u8* XXH_RESTRICT input, size_t len, } } +static XXH_PUREF XXH128_hash_t +XXH3_finalizeLong_128b(const xxh_u64* XXH_RESTRICT acc, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, xxh_u64 len) +{ + XXH128_hash_t h128; + h128.low64 = XXH3_finalizeLong_64b(acc, secret, len); + h128.high64 = XXH3_mergeAccs(acc, secret + secretSize + - XXH_STRIPE_LEN - XXH_SECRET_MERGEACCS_START, + ~(len * XXH_PRIME64_2)); + return h128; +} + XXH_FORCE_INLINE XXH128_hash_t XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, const xxh_u8* XXH_RESTRICT secret, size_t secretSize, @@ -6418,16 +6901,7 @@ XXH3_hashLong_128b_internal(const void* XXH_RESTRICT input, size_t len, /* converge into final hash */ XXH_STATIC_ASSERT(sizeof(acc) == 64); XXH_ASSERT(secretSize >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)len * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + secretSize - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)len * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, secretSize, (xxh_u64)len); } /* @@ -6610,19 +7084,10 @@ XXH_PUBLIC_API XXH128_hash_t XXH3_128bits_digest (XXH_NOESCAPE const XXH3_state_ XXH_ALIGN(XXH_ACC_ALIGN) XXH64_hash_t acc[XXH_ACC_NB]; XXH3_digest_long(acc, state, secret); XXH_ASSERT(state->secretLimit + XXH_STRIPE_LEN >= sizeof(acc) + XXH_SECRET_MERGEACCS_START); - { XXH128_hash_t h128; - h128.low64 = XXH3_mergeAccs(acc, - secret + XXH_SECRET_MERGEACCS_START, - (xxh_u64)state->totalLen * XXH_PRIME64_1); - h128.high64 = XXH3_mergeAccs(acc, - secret + state->secretLimit + XXH_STRIPE_LEN - - sizeof(acc) - XXH_SECRET_MERGEACCS_START, - ~((xxh_u64)state->totalLen * XXH_PRIME64_2)); - return h128; - } + return XXH3_finalizeLong_128b(acc, secret, state->secretLimit + XXH_STRIPE_LEN, (xxh_u64)state->totalLen); } /* len <= XXH3_MIDSIZE_MAX : short code */ - if (state->seed) + if (state->useSeed) return XXH3_128bits_withSeed(state->buffer, (size_t)state->totalLen, state->seed); return XXH3_128bits_withSecret(state->buffer, (size_t)(state->totalLen), secret, state->secretLimit + XXH_STRIPE_LEN); ===================================== testsuite/tests/core-to-stg/T25284/A.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fspec-eval-dictfun #-} +module A (testX) where + +import qualified Cls + +-- this creates the big dictionary strictly because of speculative evaluation +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/B.hs ===================================== @@ -0,0 +1,8 @@ +{-# OPTIONS_GHC -fno-spec-eval-dictfun #-} +module B (testX) where + +import qualified Cls + +-- this creates the big dictionary lazily +testX :: (Show a, Cls.HasConst a) => a -> Int -> IO () +testX a b = Cls.printConst a b ===================================== testsuite/tests/core-to-stg/T25284/Cls.hs ===================================== @@ -0,0 +1,40 @@ +{-# LANGUAGE UndecidableInstances #-} + +module Cls where + +class HasConst a where constVal :: a + +instance Cls.HasConst Word where constVal = 123 + +instance Cls.HasConst Int where constVal = 456 + +-- this class has a big dictionary +class HasConst10 a where + constA :: a + constInt1 :: a -> Int + constInt1 _ = 1 + constInt2 :: a -> Int + constInt2 _ = 2 + constInt3 :: a -> Int + constInt3 _ = 3 + constInt4 :: a -> Int + constInt4 _ = 4 + constInt5 :: a -> Int + constInt5 _ = 5 + constInt6 :: a -> Int + constInt6 _ = 6 + constInt7 :: a -> Int + constInt7 _ = 7 + constInt8 :: a -> Int + constInt8 _ = 8 + constInt9 :: a -> Int + constInt9 _ = 9 + +instance HasConst a => HasConst10 a where + constA = constVal + +-- this doesn't use the big dictionary most of the time +printConst :: forall a. (Show a, HasConst10 a) + => a -> Int -> IO () +printConst x 5000 = print @a constA >> print (constInt8 x) +printConst _ _ = pure () ===================================== testsuite/tests/core-to-stg/T25284/Main.hs ===================================== @@ -0,0 +1,57 @@ +{- + + This tests that speculative evaluation for dictionary functions works as + expected, with a large dictionary that goes unused. + + - Module A: dictfun speculative evaluation enabled + - Module B: dictfun speculative evaluation disabled + + Speculative evaluation causes the unused large dictionary to be allocated + strictly in module A, so we expect more allocations than in module B. + + -} +module Main where + +import qualified A +import qualified B +import qualified Cls + +import Data.Word +import System.Mem (performGC) +import GHC.Stats +import Control.Monad + +{-# NOINLINE getAllocated #-} +getAllocated :: IO Word64 +getAllocated = do + performGC + allocated_bytes <$> getRTSStats + +main :: IO () +main = do + -- warm up (just in case) + _ <- testMain A.testX + _ <- testMain B.testX + + -- for real + a_alloc <- testMain A.testX + b_alloc <- testMain B.testX + + -- expect B to allocate less than A + let alloc_ratio :: Double + alloc_ratio = fromIntegral b_alloc / fromIntegral a_alloc + putStrLn ("expected alloc: " ++ show (alloc_ratio < 0.7)) + +iter :: (Int -> IO ()) -> Int -> Int -> IO () +iter m !i !j + | i < j = m i >> iter m (i+1) j + | otherwise = pure () + +{-# NOINLINE testMain #-} +testMain :: (forall b. (Show b, Cls.HasConst b) => b -> Int -> IO ()) + -> IO Word64 +testMain f = do + alloc0 <- getAllocated + iter (\i -> f (0::Int) i >> f (0::Word) i) 1 100000 + alloc1 <- getAllocated + pure (alloc1 - alloc0) ===================================== testsuite/tests/core-to-stg/T25284/T25284.stdout ===================================== @@ -0,0 +1,17 @@ +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +456 +8 +123 +8 +expected alloc: True ===================================== testsuite/tests/core-to-stg/T25284/all.T ===================================== @@ -0,0 +1,6 @@ +test('T25284', + [js_skip, # allocation counters aren't available on the JS backend + extra_files(['Main.hs', 'A.hs', 'B.hs', 'Cls.hs']), + extra_run_opts('+RTS -T -RTS')], + multimod_compile_and_run, + ['Main', '']) ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -0,0 +1,41 @@ +{-# LANGUAGE MultilineStrings #-} +module Main where + +import GHC.Prim +import GHC.JS.Prim +import Foreign.C +import System.IO + +foreign import javascript + """ + ((x) => x) + """ + toJSDouble :: Double -> JSVal + +foreign import javascript + """ + (function (x) { console.log(x); }) + """ + multiLog :: JSVal -> IO () + +foreign import javascript + """ + ((x) => x + "") + """ + jsToString :: JSVal -> JSVal + +foreign import ccall + """ + cos + """ mycos :: CDouble -> CDouble + +main :: IO () +main = do + -- avoid C and Haskell prints to stdout to be intermingled due to buffering on the Haskell side + hSetBuffering stdout NoBuffering + + multiLog $ toJSInt 5 + multiLog $ toJSString "Hello" + putStrLn $ fromJSString $ jsToString $ toJSInt (- 5) + multiLog $ jsToString $ toJSDouble 3.0 + print $ mycos 0 == 1 \ No newline at end of file ===================================== testsuite/tests/javascript/T25633.stdout ===================================== @@ -0,0 +1,5 @@ +5 +Hello +-5 +3 +True \ No newline at end of file ===================================== testsuite/tests/javascript/all.T ===================================== @@ -25,3 +25,5 @@ test('T24495', normal, makefile_test, ['T24495']) test('T23479', normal, makefile_test, ['T23479']) test('T24744', normal, makefile_test, ['T24744']) + +test('T25633', normal, compile_and_run, ['']) ===================================== utils/dump-decls/Main.hs ===================================== @@ -38,6 +38,7 @@ run root pkg_nm = runGhc (Just root) $ do , "-dppr-cols=1000" , "-fprint-explicit-runtime-reps" , "-fprint-explicit-foralls" + , "-fsuppress-unit-ids" ] dflags <- do dflags <- getSessionDynFlags View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/148a1e5c9e0dc606ef682edd43a62c011e02cc7f...3594450e67af26fae9268b385a565819df7f4a60 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/148a1e5c9e0dc606ef682edd43a62c011e02cc7f...3594450e67af26fae9268b385a565819df7f4a60 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 12 00:34:39 2025 From: gitlab at gitlab.haskell.org (=?UTF-8?B?TWF0ZXVzeiBHb8WbbGlub3dza2kgKEBTd29yZGxhc2gp?=) Date: Sat, 11 Jan 2025 19:34:39 -0500 Subject: [Git][ghc/ghc][wip/swordlash/allow_multiline_strings_in_js_ffi] Make tests actually multiline Message-ID: <67830e1f357b0_351cf9eb55c885467@gitlab.mail> Mateusz Goślinowski pushed to branch wip/swordlash/allow_multiline_strings_in_js_ffi at Glasgow Haskell Compiler / GHC Commits: 97887965 by Mateusz Goślinowski at 2025-01-12T01:34:30+01:00 Make tests actually multiline - - - - - 1 changed file: - testsuite/tests/javascript/T25633.hs Changes: ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -14,13 +14,17 @@ foreign import javascript foreign import javascript """ - (function (x) { console.log(x); }) + (function (x) { + console.log(x); + }) """ multiLog :: JSVal -> IO () foreign import javascript """ - ((x) => x + "") + ((x) => + x + "" + ) """ jsToString :: JSVal -> JSVal @@ -31,7 +35,6 @@ foreign import ccall main :: IO () main = do - -- avoid C and Haskell prints to stdout to be intermingled due to buffering on the Haskell side hSetBuffering stdout NoBuffering multiLog $ toJSInt 5 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9788796542928716fc3c0186190080dbf5aa6bf9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9788796542928716fc3c0186190080dbf5aa6bf9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 12 11:38:41 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sun, 12 Jan 2025 06:38:41 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] update T23308 Message-ID: <6783a9c170b61_2a4c001e878c32889@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: f4c6c17c by Patrick at 2025-01-12T19:38:25+08:00 update T23308 - - - - - 1 changed file: - testsuite/tests/typecheck/should_fail/T23308.stderr Changes: ===================================== testsuite/tests/typecheck/should_fail/T23308.stderr ===================================== @@ -24,24 +24,12 @@ T23308.hs:28:20: error: [GHC-45219] • In the definition of data constructor ‘B3’ In the newtype declaration for ‘B3’ -T23308.hs:33:22: error: [GHC-89498] - • A newtype must not be a GADT - B4 :: C4 -> B4 Int - • In the definition of data constructor ‘B4’ - In the newtype declaration for ‘B4’ - T23308.hs:38:22: error: [GHC-17440] • A newtype constructor must not have a context in its type B5 :: forall a. Num a => B5 (a, a) • In the definition of data constructor ‘B5’ In the newtype declaration for ‘B5’ -T23308.hs:38:22: error: [GHC-89498] - • A newtype must not be a GADT - B5 :: forall a. Num a => B5 (a, a) - • In the definition of data constructor ‘B5’ - In the newtype declaration for ‘B5’ - T23308.hs:38:22: error: [GHC-23517] • A newtype constructor must have exactly one field but ‘B5’ has none View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f4c6c17cdbb5621d301b08d1eaf1efa4927e499c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f4c6c17cdbb5621d301b08d1eaf1efa4927e499c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 12 14:14:24 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sun, 12 Jan 2025 09:14:24 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] move T18891a from should_fail to should_compile Message-ID: <6783ce4084196_2f97916a8bc838077@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 7cf6d7a0 by Patrick at 2025-01-12T22:13:44+08:00 move T18891a from should_fail to should_compile - - - - - 4 changed files: - testsuite/tests/typecheck/should_fail/T18891a.hs → testsuite/tests/typecheck/should_compile/T18891a.hs - testsuite/tests/typecheck/should_compile/all.T - − testsuite/tests/typecheck/should_fail/T18891a.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== testsuite/tests/typecheck/should_fail/T18891a.hs → testsuite/tests/typecheck/should_compile/T18891a.hs ===================================== ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -931,4 +931,5 @@ test('T23501b', normal, compile, ['']) test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) -test('T25597', normal, compile, ['']) \ No newline at end of file +test('T25597', normal, compile, ['']) +test('T18891a', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/T18891a.stderr deleted ===================================== @@ -1,12 +0,0 @@ - -T18891a.hs:8:4: error: [GHC-89498] - • A newtype must not be a GADT - MkN1 :: N1 @GHC.Types.LiftedRep -> N1 @GHC.Types.LiftedRep - • In the definition of data constructor ‘MkN1’ - In the newtype declaration for ‘N1’ - -T18891a.hs:12:3: error: [GHC-89498] - • A newtype must not be a GADT - MkN2 :: N2 @GHC.Types.LiftedRep -> N2 @GHC.Types.LiftedRep - • In the definition of data constructor ‘MkN2’ - In the newtype declaration for ‘N2’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -604,7 +604,6 @@ test('T18640c', normal, compile_fail, ['']) test('T10709', normal, compile_fail, ['']) test('T10709b', normal, compile_fail, ['']) test('GivenForallLoop', normal, compile_fail, ['']) -test('T18891a', normal, compile_fail, ['']) test('T19109', normal, compile_fail, ['']) test('T17139', [extra_files(['T17139a.hs'])], multimod_compile_fail, ['T17139', '-v0']) test('TyAppPat_ExistentialEscape', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7cf6d7a0f8c1006db005d374ec2981ced36bc494 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7cf6d7a0f8c1006db005d374ec2981ced36bc494 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 12 14:18:02 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sun, 12 Jan 2025 09:18:02 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] Move T21447 from should_fail to should_compile Message-ID: <6783cf1a787e7_2f9791653dbc38324@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 98985731 by Patrick at 2025-01-12T22:17:54+08:00 Move T21447 from should_fail to should_compile - - - - - 4 changed files: - testsuite/tests/typecheck/should_fail/T21447.hs → testsuite/tests/typecheck/should_compile/T21447.hs - testsuite/tests/typecheck/should_compile/all.T - − testsuite/tests/typecheck/should_fail/T21447.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== testsuite/tests/typecheck/should_fail/T21447.hs → testsuite/tests/typecheck/should_compile/T21447.hs ===================================== ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -932,4 +932,5 @@ test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) test('T25597', normal, compile, ['']) -test('T18891a', normal, compile, ['']) \ No newline at end of file +test('T18891a', normal, compile, ['']) +test('T21447', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/T21447.stderr deleted ===================================== @@ -1,6 +0,0 @@ - -T21447.hs:8:3: error: [GHC-89498] - • A newtype must not be a GADT - H :: forall a. a -> H @GHC.Types.LiftedRep a - • In the definition of data constructor ‘H’ - In the newtype declaration for ‘H’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -661,7 +661,6 @@ test('T21338', normal, compile_fail, ['']) test('T21158', normal, compile_fail, ['']) test('DataToTagFails', normal, compile_fail, ['']) test('MissingDefaultMethodBinding', normal, compile_fail, ['']) -test('T21447', normal, compile_fail, ['']) test('T21530a', normal, compile_fail, ['']) test('T21530b', normal, compile_fail, ['']) test('Or4', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9898573198562d1a50697ea77520629fc4d15a8f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9898573198562d1a50697ea77520629fc4d15a8f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 12 15:16:51 2025 From: gitlab at gitlab.haskell.org (Serge S. Gulin (@gulin.serge)) Date: Sun, 12 Jan 2025 10:16:51 -0500 Subject: [Git][ghc/ghc][wip/llvm-debug-info] 9 commits: Fix store comma Message-ID: <6783dce3bef61_323d5e5dbd083914a@gitlab.mail> Serge S. Gulin pushed to branch wip/llvm-debug-info at Glasgow Haskell Compiler / GHC Commits: 7bb41685 by Serge S. Gulin at 2025-01-11T01:24:58+03:00 Fix store comma - - - - - ee3c2d5f by Serge S. Gulin at 2025-01-11T01:28:13+03:00 Subprograms is not a field of `DICompileUnit` in modern LLVM IR - - - - - e28ef657 by Serge S. Gulin at 2025-01-11T01:30:58+03:00 Passing location file metaId down - - - - - 8d03b614 by Serge S. Gulin at 2025-01-11T01:33:18+03:00 Remove empty meta of subprograms `!XX = !{}` - - - - - d097d41e by Serge S. Gulin at 2025-01-11T01:35:39+03:00 Use root level fileMetaId instead of generation each record for subprograms - - - - - 2b157e7d by Serge S. Gulin at 2025-01-11T01:42:48+03:00 Render debug header and pass location-based file metaId to subprograms - - - - - 7034532c by Serge S. Gulin at 2025-01-11T02:04:13+03:00 Use compilation unit metaId to connect subprograms - - - - - 5c94f143 by Serge S. Gulin at 2025-01-11T02:15:20+03:00 Add MetaDISubprogram unit to ppr - - - - - 07c249c3 by Serge S. Gulin at 2025-01-12T18:03:17+03:00 Limit LLVM `Opt` optimization level to `0` when debug metadata is required - - - - - 6 changed files: - compiler/GHC/CmmToLlvm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/CmmToLlvm/Ppr.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Llvm/MetaData.hs - compiler/GHC/Llvm/Ppr.hs Changes: ===================================== compiler/GHC/CmmToLlvm.hs ===================================== @@ -105,8 +105,11 @@ llvmCodeGen' dflags location cfg cmm_stream ghcInternalFunctions cmmMetaLlvmPrelude + -- Debug metadata header + metaCUId <- debugInfoGen dflags location + -- Procedures - a <- Stream.consume cmm_stream (GHC.CmmToLlvm.Base.liftUDSMT) (llvmGroupLlvmGens dflags location) + a <- Stream.consume cmm_stream (GHC.CmmToLlvm.Base.liftUDSMT) (llvmGroupLlvmGens dflags location metaCUId) -- Declare aliases for forward references decls <- generateExternDecls @@ -116,22 +119,19 @@ llvmCodeGen' dflags location cfg cmm_stream -- Postamble cmmUsedLlvmGens - -- Debug metadata - debugInfoGen dflags location + -- Debug metadata for subprograms + cfg <- getConfig + metaSubs <- getMetaDecls + renderLlvm (ppLlvmMetas cfg metaSubs) (ppLlvmMetas cfg metaSubs) return a -debugInfoGen :: DynFlags -> ModLocation -> LlvmM () +debugInfoGen :: DynFlags -> ModLocation -> LlvmM MetaId debugInfoGen dflags location = do fileMeta <- getMetaUniqueId - subprogramsMeta <- getMetaUniqueId cuMeta <- getMetaUniqueId dwarfVersionMeta <- getMetaUniqueId debugInfoVersionMeta <- getMetaUniqueId - cfg <- getConfig - metaSubs <- getMetaDecls - renderLlvm (ppLlvmMetas cfg metaSubs) (ppLlvmMetas cfg metaSubs) - subprograms <- getSubprograms let metaHeader = [ MetaUnnamed fileMeta NotDistinct $ MetaDIFile { difFilename = fsLit $ fromMaybe "TODO" (ml_hs_file location) @@ -142,10 +142,8 @@ debugInfoGen dflags location , dicuFile = fileMeta , dicuProducer = fsLit "ghc" , dicuIsOptimized = llvmOptLevel dflags > 0 - , dicuSubprograms = MetaStruct $ map MetaNode subprograms } , MetaNamed (fsLit "llvm.dbg.cu") NotDistinct [ cuMeta ] - , MetaUnnamed subprogramsMeta NotDistinct $ MetaStruct [] , MetaNamed (fsLit "llvm.module.flags") NotDistinct [ dwarfVersionMeta , debugInfoVersionMeta @@ -161,8 +159,12 @@ debugInfoGen dflags location , MetaVar $ LMLitVar $ LMIntLit 3 i32 ] ] + + cfg <- getConfig renderLlvm (ppLlvmMetas cfg metaHeader) (ppLlvmMetas cfg metaHeader) + pure cuMeta + llvmHeader :: IsDoc doc => LlvmCgConfig -> doc llvmHeader cfg = let target = llvmCgLlvmTarget cfg @@ -182,8 +184,8 @@ llvmHeader cfg = {-# SPECIALIZE llvmHeader :: LlvmCgConfig -> SDoc #-} {-# SPECIALIZE llvmHeader :: LlvmCgConfig -> HDoc #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable -llvmGroupLlvmGens :: DynFlags -> ModLocation -> RawCmmGroup -> LlvmM () -llvmGroupLlvmGens dflags location cmm = do +llvmGroupLlvmGens :: DynFlags -> ModLocation -> MetaId -> RawCmmGroup -> LlvmM () +llvmGroupLlvmGens dflags location metaCUId cmm = do let debug_map :: LabelMap DebugBlock debug_map | (debugLevel dflags) >= 1 = debugToMap $ cmmDebugGen location cmm @@ -204,7 +206,7 @@ llvmGroupLlvmGens dflags location cmm = do {-# SCC "llvm_datas_gen" #-} cmmDataLlvmGens cdata {-# SCC "llvm_procs_gen" #-} - mapM_ (cmmLlvmGen debug_map) cmm + mapM_ (cmmLlvmGen debug_map metaCUId) cmm -- ----------------------------------------------------------------------------- -- | Do LLVM code generation on all these Cmms data sections. @@ -227,8 +229,8 @@ cmmDataLlvmGens statics (pprLlvmData cfg (concat gss', concat tss)) -- | Complete LLVM code generation phase for a single top-level chunk of Cmm. -cmmLlvmGen :: LabelMap DebugBlock -> RawCmmDecl -> LlvmM () -cmmLlvmGen debug_map cmm at CmmProc{} = do +cmmLlvmGen :: LabelMap DebugBlock -> MetaId -> RawCmmDecl -> LlvmM () +cmmLlvmGen debug_map metaCUId cmm at CmmProc{} = do -- rewrite assignments to global regs platform <- getPlatform @@ -243,11 +245,11 @@ cmmLlvmGen debug_map cmm at CmmProc{} = do -- pretty print - print as we go, since we produce HDocs, we know -- no nesting state needs to be maintained for the SDocs. forM_ llvmBC (\decl -> do - (hdoc, sdoc) <- pprLlvmCmmDecl debug_map decl + (hdoc, sdoc) <- pprLlvmCmmDecl debug_map decl metaCUId renderLlvm (hdoc $$ empty) (sdoc $$ empty) ) -cmmLlvmGen _ _ = return () +cmmLlvmGen _ _ _ = return () -- ----------------------------------------------------------------------------- -- | Generate meta data nodes ===================================== compiler/GHC/CmmToLlvm/Base.hs ===================================== @@ -20,7 +20,7 @@ module GHC.CmmToLlvm.Base ( markStackReg, checkStackReg, funLookup, funInsert, getLlvmVer, dumpIfSetLlvm, renderLlvm, markUsedVar, getUsedVars, - addMetaDecl, getMetaDecls, addSubprogram, getSubprograms, + addMetaDecl, getMetaDecls, ghcInternalFunctions, getPlatform, getConfig, getMetaUniqueId, @@ -290,8 +290,6 @@ data LlvmEnv = LlvmEnv , envAliases :: UniqSet LMString -- ^ Globals that we had to alias, see [Llvm Forward References] , envUsedVars :: [LlvmVar] -- ^ Pointers to be added to llvm.used (see @cmmUsedLlvmGens@) , envMetaDecls :: [MetaDecl] -- ^ Metadata declarations to be included in final output - , envSubprograms :: [MetaId] -- ^ 'MetaId's of the @DISubprogram@ metadata - -- nodes defined in this @DICompileUnit at . -- the following get cleared for every function (see @withClearVars@) , envVarMap :: LlvmEnvMap -- ^ Local variables so far, with type @@ -345,7 +343,6 @@ runLlvm logger cfg ver out us m = do , envStackRegs = [] , envUsedVars = [] , envMetaDecls = [] - , envSubprograms = [] , envAliases = emptyUniqSet , envVersion = ver , envConfig = cfg @@ -437,15 +434,6 @@ setUniqMeta f m = modifyEnv $ \env -> env { envUniqMeta = addToUFM (envUniqMeta getUniqMeta :: Unique -> LlvmM (Maybe MetaId) getUniqMeta s = getEnv (flip lookupUFM s . envUniqMeta) --- | Add a @DISubprogram@ metadata declaration to the current compilation unit. -addSubprogram :: MetaId -> MetaExpr -> LlvmM () -addSubprogram metaId metaExpr = do - modifyEnv $ \env -> env { envSubprograms = metaId : envSubprograms env } - addMetaDecl (MetaUnnamed metaId Distinct metaExpr) - -getSubprograms :: LlvmM [MetaId] -getSubprograms = LlvmM $ \env -> return (envSubprograms env, env { envSubprograms = [] }) - -- | Add a metadata declaration to the output. addMetaDecl :: MetaDecl -> LlvmM () addMetaDecl x = modifyEnv $ \env -> env { envMetaDecls = x : envMetaDecls env } ===================================== compiler/GHC/CmmToLlvm/Ppr.hs ===================================== @@ -49,13 +49,13 @@ pprLlvmData cfg (globals, types) = -- The HDoc we return is used to produce the final LLVM file, with the -- SDoc being returned alongside for use when @Opt_D_dump_llvm@ is set -- as we can't (currently) dump HDocs. -pprLlvmCmmDecl :: LabelMap DebugBlock -> LlvmCmmDecl -> LlvmM (HDoc, SDoc) -pprLlvmCmmDecl _ (CmmData _ lmdata) = do +pprLlvmCmmDecl :: LabelMap DebugBlock -> LlvmCmmDecl -> MetaId -> LlvmM (HDoc, SDoc) +pprLlvmCmmDecl _ (CmmData _ lmdata) _ = do opts <- getConfig return ( vcat $ map (pprLlvmData opts) lmdata , vcat $ map (pprLlvmData opts) lmdata) -pprLlvmCmmDecl debug_map (CmmProc (label, mb_info) entry_lbl live (ListGraph blks)) +pprLlvmCmmDecl debug_map (CmmProc (label, mb_info) entry_lbl live (ListGraph blks)) metaCUId = do let lbl = case mb_info of Nothing -> entry_lbl Just (CmmStaticsRaw info_lbl _) -> info_lbl @@ -104,18 +104,16 @@ pprLlvmCmmDecl debug_map (CmmProc (label, mb_info) entry_lbl live (ListGraph blk , disLine = srcSpanStartLine span , disType = typeMeta , disIsDefinition = True + , disUnit = metaCUId } addMetaDecl fileDef addMetaDecl typeMetaDef - addSubprogram subprogMeta subprog + addMetaDecl (MetaUnnamed subprogMeta Distinct subprog) return $ Just $ MetaAnnot (fsLit "dbg") (MetaNode subprogMeta) _ -> return Nothing - let funcMetas = maybeToList subprogAnnot - - let fun = LlvmFunction funDec funArgs llvmStdFunAttrs funSect - prefix funcMetas lmblocks + prefix (maybeToList subprogAnnot) lmblocks name = decName $ funcDecl fun defName = llvmDefLabel name funcDecl' = (funcDecl fun) { decName = defName } ===================================== compiler/GHC/Driver/Pipeline/Execute.hs ===================================== @@ -256,9 +256,39 @@ runLlvmOptPhase pipe_env hsc_env input_fn = do let dflags = hsc_dflags hsc_env logger = hsc_logger hsc_env llvm_config <- readLlvmConfigCache (hsc_llvm_config hsc_env) - let -- we always (unless -optlo specified) run Opt since we rely on it to + let -- LLVM debug metadata generation does not support inliner passes currently. + -- We have to disable it if debug information is required for the build. + -- Fortunately it is already done for `O0` of `opt`, so, we will override to the lowest + -- it when debug info is enabled. + -- Otherwise LLVM ERROR will be shown for `rts/Apply.cmm` and others. + -- The error is very common to rts cmm code. + -- inlinable function call in a function with debug info must have a !dbg location + -- tail call ghccc void @"cy_info$def"(i64* noalias nocapture nonnull %Base_Arg, i64* noalias nocapture nonnull %ln2l, i64* noalias nocapture %Hp_Arg, i64 %R1_Arg, i64 undef, i64 undef, i64 undef, i64 undef, i64 undef, i64 %SpLim_Arg) #0 + -- LLVM ERROR: Broken module found, compilation aborted! + -- PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace. + -- Stack dump: + -- 0. Program arguments: /nix/store/22qzc2gsw44j2w5vkny5m2zlmk42vk9w-llvm-13.0.1/bin/opt -passes=default -relocation-model=pic /tmp/ghc21926_tmp_0/ghc_tmp_3.ll -o /tmp/ghc21926_tmp_0/ghc_tmp_5.bc + -- Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it): + -- 0 libLLVM.dylib 0x0000000106d2f3a8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 72 + -- 1 libLLVM.dylib 0x0000000106d2e124 llvm::sys::RunSignalHandlers() + 112 + -- 2 libLLVM.dylib 0x0000000106d2fae8 SignalHandler(int) + 416 + -- 3 libsystem_platform.dylib 0x0000000196faa584 _sigtramp + 56 + -- 4 libsystem_pthread.dylib 0x0000000196f79c20 pthread_kill + 288 + -- 5 libsystem_c.dylib 0x0000000196e86a30 abort + 180 + -- 6 libLLVM.dylib 0x0000000106c6ddc4 llvm::report_fatal_error(std::__1::basic_string, std::__1::allocator > const&, bool) + 0 + -- 7 libLLVM.dylib 0x0000000106c6dc10 llvm::report_fatal_error(llvm::Twine const&, bool) + 0 + -- 8 libLLVM.dylib 0x0000000106efa5e0 llvm::VerifierPass::run(llvm::Function&, llvm::AnalysisManager&) + 0 + -- 9 libLLVM.dylib 0x0000000106ecbac4 llvm::PassManager >::run(llvm::Module&, llvm::AnalysisManager&) + 424 + -- 10 opt 0x0000000100c97bec llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool) + 14312 + -- 11 opt 0x0000000100ca8a28 main + 9588 + -- 12 dyld 0x0000000196bef154 start + 2476 + -- `opt' failed in phase `LLVM Optimiser'. (Exit code: -6) + maxOptIdxAvailable :: Int = if (debugLevel dflags) >= 1 then 0 else 2 + + -- we always (unless -optlo specified) run Opt since we rely on it to -- fix up some pretty big deficiencies in the code we generate - optIdx = max 0 $ min 2 $ llvmOptLevel dflags -- ensure we're in [0,2] + optIdx = max 0 $ min maxOptIdxAvailable $ llvmOptLevel dflags -- ensure we're in [0,2] + llvmOpts = case lookup optIdx $ llvmPasses llvm_config of Just passes -> passes Nothing -> panic ("runPhase LlvmOpt: llvm-passes file " ===================================== compiler/GHC/Llvm/MetaData.hs ===================================== @@ -96,7 +96,6 @@ data MetaExpr = MetaStr !LMString , dicuFile :: !MetaId , dicuProducer :: !LMString , dicuIsOptimized :: !Bool - , dicuSubprograms :: !MetaExpr } | MetaDISubprogram { disName :: !LMString , disLinkageName :: !LMString @@ -105,6 +104,7 @@ data MetaExpr = MetaStr !LMString , disLine :: !Int , disType :: !MetaId , disIsDefinition :: !Bool + , disUnit :: !MetaId } deriving (Eq) ===================================== compiler/GHC/Llvm/Ppr.hs ===================================== @@ -323,7 +323,6 @@ ppMetaExpr opts = \case , ("isOptimized", if dicuIsOptimized then text "true" else text "false") - , ("subprograms", ppMetaExpr opts $ dicuSubprograms) ] MetaDISubprogram {..} -> specialMetadata "DISubprogram" @@ -336,6 +335,7 @@ ppMetaExpr opts = \case , ("isDefinition", if disIsDefinition then text "true" else text "false") + , ("unit" , ppMetaId disUnit) ] where specialMetadata :: IsLine doc => String -> [(String, doc)] -> doc @@ -499,8 +499,12 @@ ppALoad opts ord st var = ppStore :: IsLine doc => LlvmCgConfig -> LlvmVar -> LlvmVar -> LMAlign -> [MetaAnnot] -> doc ppStore opts val dst alignment metas = - text "store" <+> ppVar opts val <> comma <+> ppVar opts dst <> align <+> ppMetaAnnots opts metas + text "store" <+> ppVar opts val <> comma <+> ppVar opts dst <> align <> metaComma where + metaComma = + case metas of + [] -> empty + _ -> comma <+> ppMetaAnnots opts metas align = case alignment of Just n -> text ", align" <+> int n View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62eab54ba3dfedac4e3f7e76d1fc3d8d6d84d25b...07c249c3a4e838ce3c99d0da6cb538301dd9b592 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/62eab54ba3dfedac4e3f7e76d1fc3d8d6d84d25b...07c249c3a4e838ce3c99d0da6cb538301dd9b592 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 12 20:51:01 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sun, 12 Jan 2025 15:51:01 -0500 Subject: [Git][ghc/ghc][wip/T25623] Require alex >= 3.5.2 (#25623) Message-ID: <67842b35ae9bd_6c12d86234c76fd@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 493772d5 by Brandon Chinn at 2025-01-12T12:50:52-08:00 Require alex >= 3.5.2 (#25623) - - - - - 6 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/darwin/nix/sources.json - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in - hadrian/cabal.project Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: eb4d3389fd62e4f7321a0c8799014ec1f4da0708 + DOCKER_REV: f8b8b8910097a88185835e0c929b8bb03fadfe61 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. ===================================== .gitlab/ci.sh ===================================== @@ -8,9 +8,9 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-04T21:29:42Z" MIN_HAPPY_VERSION="1.20" -MIN_ALEX_VERSION="3.2.6" +MIN_ALEX_VERSION="3.5.2.0" TOP="$(pwd)" if [ ! -d "$TOP/.gitlab" ]; then ===================================== .gitlab/darwin/nix/sources.json ===================================== @@ -17,10 +17,10 @@ "homepage": "", "owner": "nixos", "repo": "nixpkgs", - "rev": "2893f56de08021cffd9b6b6dfc70fd9ccd51eb60", - "sha256": "1anwxmjpm21msnnlrjdz19w31bxnbpn4kgf93sn3npihi7wf4a8h", + "rev": "91ef85e17108be826689fe42a207dfd24d354012", + "sha256": "1q0w1z7mljcch4bgm56jq7lird0iwd7i01255nps5fbbx8sbmij2", "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/2893f56de08021cffd9b6b6dfc70fd9ccd51eb60.tar.gz", + "url": "https://github.com/nixos/nixpkgs/archive/91ef85e17108be826689fe42a207dfd24d354012.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -3467,11 +3467,6 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b --- If the generated alexScan/alexScanUser functions are called multiple times --- in this file, alexScanUser gets broken out into a separate function and --- increases memory usage. Make sure GHC inlines this function and optimizes it. -{-# INLINE alexScanUser #-} - lexToken :: P (PsLocated Token) lexToken = do inp@(AI loc1 buf) <- getInput ===================================== compiler/ghc.cabal.in ===================================== @@ -102,7 +102,7 @@ Library FunTypes.h if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: alex:alex >= 3.5.2, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-04T21:29:42Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/493772d53b69b2e9b0cc1eece0d2fa69bc296e25 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/493772d53b69b2e9b0cc1eece0d2fa69bc296e25 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 02:20:28 2025 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Sun, 12 Jan 2025 21:20:28 -0500 Subject: [Git][ghc/ghc][wip/spj-apporv-Oct24] 90 commits: Add missing @since documentation for (!?) function Message-ID: <6784786c6587b_1b130a141f88874562@gitlab.mail> Apoorv Ingle pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC Commits: a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - f44ed71c by Apoorv Ingle at 2025-01-12T13:11:06-06:00 Make ApplicativeDo work with HsExpansions testcase added: T24406 Issues Fixed: #24406, #16135 Code Changes: - Remove `XStmtLR GhcTc` as `XStmtLR GhcRn` is now compiled to `HsExpr GhcTc` - The expanded statements are guided by `GHC.Hs.Expr.TcFunInfo` which is used to decide if the `XExpr GhcRn` is to be typechecked using `tcApp` or `tcExpr` Note [Expanding HsDo with XXExprGhcRn] explains the change in more detail - - - - - d959067a by Apoorv Ingle at 2025-01-12T13:32:43-06:00 simplify data structures. remove doTcApp and applicative stmt fail blocks do not refer stmts - - - - - 8035a59c by Simon Peyton Jones at 2025-01-12T13:32:43-06:00 Remove special cases ... to see what breaks - - - - - 44a2ea60 by Simon Peyton Jones at 2025-01-12T13:32:43-06:00 Don't use a user SrcSpan on a Stmt expansoin - - - - - 8094e6b6 by Apoorv Ingle at 2025-01-12T13:32:43-06:00 make caller wrap the pop err ctxt - - - - - 0722302a by Apoorv Ingle at 2025-01-12T13:32:43-06:00 wrap expansion statements with the statement location instead of genSpan - - - - - 2a378536 by Apoorv Ingle at 2025-01-12T13:32:44-06:00 fix bugs, let stmt pop in the right place - - - - - abcb6f14 by Apoorv Ingle at 2025-01-12T13:32:44-06:00 addThingCtxt in tcXExpr - - - - - 1bf41aa1 by Apoorv Ingle at 2025-01-12T13:32:44-06:00 some more progress in error messages - - - - - 4d74146d by Apoorv Ingle at 2025-01-12T13:32:44-06:00 addExprCtxt ignores Expanded Statements - - - - - 3472eae8 by Apoorv Ingle at 2025-01-12T13:32:44-06:00 remove adhoc addthingCtxt and remove location from PopErrCtxt HsExprs - - - - - 9607162b by Apoorv Ingle at 2025-01-12T13:32:45-06:00 push unLocs further in - - - - - 27 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .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 - .gitlab/rel_eng/upload.sh - .gitmodules - compiler/GHC/Builtin/Names.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Rep.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/594cdef4ed6dc4a95bc8cdeb71454ff7837231a4...9607162b597a05669250152f12181b312f9686f7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/594cdef4ed6dc4a95bc8cdeb71454ff7837231a4...9607162b597a05669250152f12181b312f9686f7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 04:14:17 2025 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Sun, 12 Jan 2025 23:14:17 -0500 Subject: [Git][ghc/ghc][wip/spj-apporv-Oct24] testing pushing VAExpansion into tcApp Message-ID: <6784931934143_2cd8f48e49f066299@gitlab.mail> Apoorv Ingle pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC Commits: 69f342dc by Apoorv Ingle at 2025-01-12T22:13:33-06:00 testing pushing VAExpansion into tcApp - - - - - 3 changed files: - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Head.hs Changes: ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -177,7 +177,7 @@ tcInferSigma :: Bool -> LHsExpr GhcRn -> TcM TcSigmaType tcInferSigma inst (L loc rn_expr) = addExprCtxt rn_expr $ setSrcSpanA loc $ - do { (fun@(rn_fun,fun_ctxt), rn_args) <- splitHsApps rn_expr + do { (fun@(rn_fun,fun_ctxt), rn_args) <- splitHsApps Nothing rn_expr ; do_ql <- wantQuickLook rn_fun ; (tc_fun, fun_sigma) <- tcInferAppHead fun ; (inst_args, app_res_sigma) <- tcInstFun do_ql inst (tc_fun, fun_ctxt) fun_sigma rn_args @@ -386,13 +386,14 @@ Unify result type /before/ typechecking the args The latter is much better. That is why we call checkResultType before tcValArgs. -} -tcApp :: HsExpr GhcRn +tcApp :: Maybe HsThingRn -- Just x <=> Expr is a compiler generated expression + -> HsExpr GhcRn -> ExpRhoType -- When checking, -XDeepSubsumption <=> deeply skolemised -> TcM (HsExpr GhcTc) -- See Note [tcApp: typechecking applications] -tcApp rn_expr exp_res_ty +tcApp mb_oexpr rn_expr exp_res_ty = do { -- Step 1: Split the application chain - (fun@(rn_fun, fun_ctxt), rn_args) <- splitHsApps rn_expr + (fun@(rn_fun, fun_ctxt), rn_args) <- splitHsApps mb_oexpr rn_expr ; traceTc "tcApp {" $ vcat [ text "rn_expr:" <+> ppr rn_expr , text "rn_fun:" <+> ppr rn_fun @@ -1727,7 +1728,7 @@ quickLookArg1 :: AppCtxt -> LHsExpr GhcRn quickLookArg1 ctxt larg@(L _ arg) sc_arg_ty@(Scaled _ orig_arg_rho) = addArgCtxt ctxt larg $ -- Context needed for constraints -- generated by calls in arg - do { ((rn_fun, fun_ctxt), rn_args) <- splitHsApps arg + do { ((rn_fun, fun_ctxt), rn_args) <- splitHsApps Nothing arg -- Step 1: get the type of the head of the argument ; (fun_ue, mb_fun_ty) <- tcCollectingUsage $ tcInferAppHead_maybe rn_fun ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -288,11 +288,11 @@ tcExpr :: HsExpr GhcRn -- - ones taken apart by GHC.Tc.Gen.Head.splitHsApps -- - ones understood by GHC.Tc.Gen.Head.tcInferAppHead_maybe -- See Note [Application chains and heads] in GHC.Tc.Gen.App -tcExpr e@(HsVar {}) res_ty = tcApp e res_ty -tcExpr e@(HsApp {}) res_ty = tcApp e res_ty -tcExpr e@(OpApp {}) res_ty = tcApp e res_ty -tcExpr e@(HsAppType {}) res_ty = tcApp e res_ty -tcExpr e@(ExprWithTySig {}) res_ty = tcApp e res_ty +tcExpr e@(HsVar {}) res_ty = tcApp Nothing e res_ty +tcExpr e@(HsApp {}) res_ty = tcApp Nothing e res_ty +tcExpr e@(OpApp {}) res_ty = tcApp Nothing e res_ty +tcExpr e@(HsAppType {}) res_ty = tcApp Nothing e res_ty +tcExpr e@(ExprWithTySig {}) res_ty = tcApp Nothing e res_ty tcExpr (XExpr e) res_ty = tcXExpr e res_ty @@ -360,7 +360,7 @@ tcExpr e@(HsOverLit _ lit) res_ty -- See Note [Short cut for overloaded literals] in GHC.Tc.Utils.TcMType ; case mb_res of Just lit' -> return (HsOverLit noExtField lit') - Nothing -> tcApp e res_ty } + Nothing -> tcApp Nothing e res_ty } -- Why go via tcApp? See Note [Typechecking overloaded literals] {- Note [Typechecking overloaded literals] @@ -749,10 +749,10 @@ tcXExpr (PopErrCtxt e) res_ty tcXExpr (ExpandedThingRn o@(OrigStmt stmt flav) e) res_ty = addThingCtxt o $ mkExpandedStmtTc stmt flav <$> - tcExpr e res_ty + tcApp (Just o) e res_ty -- For record selection -tcXExpr xe res_ty = tcApp (XExpr xe) res_ty +tcXExpr xe res_ty = tcApp Nothing (XExpr xe) res_ty {- ===================================== compiler/GHC/Tc/Gen/Head.hs ===================================== @@ -283,7 +283,8 @@ addArgWrap wrap args | isIdHsWrapper wrap = args | otherwise = EWrap (EHsWrap wrap) : args -splitHsApps :: HsExpr GhcRn +splitHsApps :: Maybe HsThingRn + -> HsExpr GhcRn -> TcM ( (HsExpr GhcRn, AppCtxt) -- Head , [HsExprArg 'TcpRn]) -- Args -- See Note [splitHsApps]. @@ -291,7 +292,10 @@ splitHsApps :: HsExpr GhcRn -- This uses the TcM monad solely because we must run modFinalizers when looking -- through HsUntypedSplices -- (see Note [Looking through Template Haskell splices in splitHsApps]). -splitHsApps e = go e (top_ctxt 0 e) [] +splitHsApps mb_oexpr e = case mb_oexpr of + Just x@(OrigStmt (L l _) _) -> go e (VAExpansion x (locA l) generatedSrcSpan) [] + Just x -> go e (VAExpansion x generatedSrcSpan generatedSrcSpan) [] + Nothing -> go e (top_ctxt 0 e) [] where top_ctxt :: Int -> HsExpr GhcRn -> AppCtxt -- Always returns VACall fun n_val_args noSrcSpan View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/69f342dc6695854ae60fc5f9630d21f5bcc63e96 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/69f342dc6695854ae60fc5f9630d21f5bcc63e96 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 08:37:18 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 13 Jan 2025 03:37:18 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] Remove `IsGADT` case Message-ID: <6784d0bec2f5c_2ff32105b80459ab@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 3bf19b5c by Patrick at 2025-01-13T16:37:01+08:00 Remove `IsGADT` case - - - - - 3 changed files: - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Types/Error/Codes.hs Changes: ===================================== compiler/GHC/Tc/Errors/Ppr.hs ===================================== @@ -1231,10 +1231,6 @@ instance Diagnostic TcRnMessage where IsNonLinear -> (text "A newtype constructor must be linear", ppr con <+> dcolon <+> ppr (dataConDisplayType True con)) - IsGADT -> - (text "A newtype must not be a GADT", - ppr con <+> dcolon <+> pprWithInvisibleBitsWhen sneaky_eq_spec - (ppr $ dataConDisplayType show_linear_types con)) HasConstructorContext -> (text "A newtype constructor must not have a context in its type", ppr con <+> dcolon <+> ppr (dataConDisplayType show_linear_types con)) ===================================== compiler/GHC/Tc/Errors/Types.hs ===================================== @@ -4502,7 +4502,6 @@ pprFixedRuntimeRepProvenance FixedRuntimeRepPatSynSigRes = text "pattern synonym data IllegalNewtypeReason = DoesNotHaveSingleField !Int | IsNonLinear - | IsGADT | HasConstructorContext | HasExistentialTyVar | HasStrictnessAnnotation ===================================== compiler/GHC/Types/Error/Codes.hs ===================================== @@ -661,7 +661,6 @@ type family GhcDiagnosticCode c = n | n -> c where -- IllegalNewtypeReason GhcDiagnosticCode "DoesNotHaveSingleField" = 23517 GhcDiagnosticCode "IsNonLinear" = 38291 - GhcDiagnosticCode "IsGADT" = 89498 GhcDiagnosticCode "HasConstructorContext" = 17440 GhcDiagnosticCode "HasExistentialTyVar" = 07525 GhcDiagnosticCode "HasStrictnessAnnotation" = 04049 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3bf19b5c64cea02639a21a25e38bcc0f3c085fdb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3bf19b5c64cea02639a21a25e38bcc0f3c085fdb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 10:07:36 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 13 Jan 2025 05:07:36 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Re CLC #300 - Specify fmap for NonEmpty as map Message-ID: <6784e5e8b3713_7a9dc51066c658a0@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6d2f5f33 by Mike Pilgrem at 2025-01-13T05:07:13-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - 32d38f60 by amesgen at 2025-01-13T05:07:21-05:00 wasm: prevent bundlers from resolving import("node:timers") - - - - - 96a4d0e2 by Luite Stegeman at 2025-01-13T05:07:29-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 30 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - docs/users_guide/using-optimisation.rst - libraries/base/changelog.md - libraries/base/src/Data/List/NonEmpty.hs - libraries/base/src/Data/Semigroup.hs - libraries/base/src/GHC/Base.hs - libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/src/GHC/Internal/Base.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs - libraries/ghc-internal/src/GHC/Internal/Data/Data.hs - libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs - libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs - + libraries/ghc-internal/src/GHC/Internal/Data/NonEmpty.hs - libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs - libraries/ghc-internal/src/GHC/Internal/Generics.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs - libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs - libraries/ghc-internal/src/GHC/Internal/Text/ParserCombinators/ReadP.hs - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - testsuite/tests/plugins/plugins09.stdout - testsuite/tests/plugins/plugins10.stdout - testsuite/tests/plugins/plugins11.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/669b8b42c0d913d8a9b30570eb3169e79313c3f3...96a4d0e2fef83fcf7a05a167041d42c5a23b574b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/669b8b42c0d913d8a9b30570eb3169e79313c3f3...96a4d0e2fef83fcf7a05a167041d42c5a23b574b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 12:06:02 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 13 Jan 2025 07:06:02 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Enhance kind inference for data family instances Message-ID: <678501aad1de2_1211f145d42c5796e@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 157d6328 by Patrick at 2025-01-13T19:59:04+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 19 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs - + testsuite/tests/indexed-types/should_compile/T25611a.hs - + testsuite/tests/indexed-types/should_compile/T25611b.hs - + testsuite/tests/indexed-types/should_compile/T25611c.hs - + testsuite/tests/indexed-types/should_compile/T25611d.hs - testsuite/tests/indexed-types/should_compile/all.T - testsuite/tests/indexed-types/should_fail/all.T - + testsuite/tests/rep-poly/T25611a.hs - + testsuite/tests/rep-poly/T25611b.hs - + testsuite/tests/rep-poly/T25611c.hs - + testsuite/tests/rep-poly/T25611d.hs - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_compile/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/indexed-types/should_compile/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/indexed-types/should_compile/T25611c.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module T25611c where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/indexed-types/should_compile/T25611d.hs ===================================== @@ -0,0 +1,38 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,8 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/rep-poly/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/rep-poly/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/rep-poly/T25611c.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module T25611c where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/rep-poly/T25611d.hs ===================================== @@ -0,0 +1,38 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -931,4 +931,4 @@ test('T23501b', normal, compile, ['']) test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) -test('T25597', normal, compile, ['']) +test('T25597', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/157d6328437cfbdac7bc9214f040b62746e2e74e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/157d6328437cfbdac7bc9214f040b62746e2e74e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 12:09:23 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 13 Jan 2025 07:09:23 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Enhance kind inference for data family instances Message-ID: <678502732c597_1211f13fc3d465183@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 1afaf853 by Patrick at 2025-01-13T20:08:31+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 15 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs - + testsuite/tests/indexed-types/should_compile/T25611a.hs - + testsuite/tests/indexed-types/should_compile/T25611b.hs - + testsuite/tests/indexed-types/should_compile/T25611c.hs - + testsuite/tests/indexed-types/should_compile/T25611d.hs - testsuite/tests/indexed-types/should_compile/all.T - testsuite/tests/indexed-types/should_fail/all.T - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2467,7 +2468,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3920,14 +3921,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1135,7 +1135,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1252,7 +1252,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2123,7 +2123,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2218,14 +2218,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -714,10 +715,9 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; skol_info <- mkSkolemInfo FamInstSkol - ; let new_or_data = dataDefnConsNewOrData hs_cons ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -742,8 +742,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -917,8 +916,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -926,7 +924,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -942,16 +940,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1003,9 +1002,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1031,6 +1037,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1185,31 +1206,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_compile/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/indexed-types/should_compile/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/indexed-types/should_compile/T25611c.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE GADTs #-} + +module T25611c where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) + +data family DF :: TYPE (r :: RuntimeRep) + +-- it used to be failed: see #18891 and !4419 +-- See Note [Kind inference for data family instances] +-- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 +newtype instance DF = MkDF1a Int# +newtype instance DF = MkDF2a Word# +newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/indexed-types/should_compile/T25611d.hs ===================================== @@ -0,0 +1,38 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,8 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ===================================== testsuite/tests/indexed-types/should_fail/all.T ===================================== @@ -171,4 +171,4 @@ test('T20521', normal, compile_fail, ['']) test('T21896', normal, compile_fail, ['']) test('HsBootFam', [extra_files(['HsBootFam_aux.hs','HsBootFam_aux.hs-boot'])], multimod_compile_fail, ['HsBootFam', '']) test('BadFamInstDecl', [extra_files(['BadFamInstDecl_aux.hs'])], multimod_compile_fail, ['BadFamInstDecl', '']) -test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) +test('T19773', [], multimod_compile_fail, ['T19773', '-Wall']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -931,4 +931,4 @@ test('T23501b', normal, compile, ['']) test('T25266', normal, compile, ['']) test('T25266a', normal, compile_fail, ['']) test('T25266b', normal, compile, ['']) -test('T25597', normal, compile, ['']) +test('T25597', normal, compile, ['']) \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,9 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • Expected a WordRep type, but ‘Bar Bool’ is an IntRep type • In the newtype instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ + +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the newtype instance declaration for ‘Bar’ \ No newline at end of file ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ - -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype instance declaration for ‘DF’ ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1afaf853f59c7d4bd80a79639d375be15380faf5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1afaf853f59c7d4bd80a79639d375be15380faf5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 13:08:27 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 13 Jan 2025 08:08:27 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Remove SDocs from ErrCtxt & ErrInfo Message-ID: <6785104bbdeef_1968241dfbf026711@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 4a10762f by Mike Pilgrem at 2025-01-13T08:08:04-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - 810bb351 by Luite Stegeman at 2025-01-13T08:08:09-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 30 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Errors/Types/PromotionErr.hs - compiler/GHC/Tc/Gen/Annotation.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96a4d0e2fef83fcf7a05a167041d42c5a23b574b...810bb35119a7ae69007e7f0e83810180541f0ce8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/96a4d0e2fef83fcf7a05a167041d42c5a23b574b...810bb35119a7ae69007e7f0e83810180541f0ce8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 13:13:52 2025 From: gitlab at gitlab.haskell.org (Jens Petersen (@juhp)) Date: Mon, 13 Jan 2025 08:13:52 -0500 Subject: [Git][ghc/ghc] Pushed new branch juhp-ghc-9.6-patch-42139 Message-ID: <67851190a6027_1968241fc37c3079d@gitlab.mail> Jens Petersen pushed new branch juhp-ghc-9.6-patch-42139 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/juhp-ghc-9.6-patch-42139 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 16:42:55 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 13 Jan 2025 11:42:55 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] 4 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <6785428f74976_20bfcb9715a8509a@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: ba97aa2d by Alex Mason at 2025-01-13T15:01:42+01:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 (cherry picked from commit dbdf1995956a7457c34b6895c67ef48f6c8384f2) - - - - - 52812e1c by Matthew Pickering at 2025-01-13T15:04:41+01:00 Bump os-string submodule to 2.0.2.2 Closes #24786 (cherry picked from commit 0528509028ef6c4d80d47aad9fd80de6c662c8a2) - - - - - a085f505 by Alex Mason at 2025-01-13T15:05:55+01:00 Add AArch64 CLZ, CTZ, RBIT primop implementations. Adds support for emitting the clz and rbit instructions, which are used by GHC.Prim.clz*#, GHC.Prim.ctz*# and GHC.Prim.bitReverse*#. (cherry picked from commit 71010381f4270966de334193ab2bfc67f8524212) - - - - - 6faa8336 by Andreas Klebinger at 2025-01-13T15:06:40+01:00 GHCi interpreter: Tag constructor closures when possible. When evaluating PUSH_G try to tag the reference we are pushing if it's a constructor. This is potentially helpful for performance and required to fix #24870. (cherry picked from commit 1bfa91115b8320ed99a5e946147528e21ca4f3e1) - - - - - 18 changed files: - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Prim.hs - libraries/os-string - rts/Interpreter.c - + testsuite/tests/codeGen/should_run/CtzClz0.hs - testsuite/tests/codeGen/should_run/all.T - testsuite/tests/numeric/should_run/all.T - + testsuite/tests/numeric/should_run/mul2int.hs - + testsuite/tests/numeric/should_run/mul2int.stdout - + testsuite/tests/numeric/should_run/mul2int.stdout-ws-32 - + testsuite/tests/th/should_compile/T24870/Def.hs - + testsuite/tests/th/should_compile/T24870/Use.hs - + testsuite/tests/th/should_compile/T24870/all.T Changes: ===================================== compiler/GHC/ByteCode/Instr.hs ===================================== @@ -83,7 +83,7 @@ data BCInstr | PUSH16_W !ByteOff | PUSH32_W !ByteOff - -- Push a ptr (these all map to PUSH_G really) + -- Push a (heap) ptr (these all map to PUSH_G really) | PUSH_G Name | PUSH_PRIMOP PrimOp | PUSH_BCO (ProtoBCO Name) ===================================== compiler/GHC/CmmToAsm/AArch64/CodeGen.hs ===================================== @@ -1556,7 +1556,7 @@ genCCall target dest_regs arg_regs bid = do -- pprTraceM "genCCall target" (ppr target) -- pprTraceM "genCCall formal" (ppr dest_regs) -- pprTraceM "genCCall actual" (ppr arg_regs) - + platform <- getPlatform case target of -- The target :: ForeignTarget call can either -- be a foreign procedure with an address expr @@ -1584,7 +1584,6 @@ genCCall target dest_regs arg_regs bid = do let (_res_hints, arg_hints) = foreignTargetHints target arg_regs'' = zipWith (\(r, f, c) h -> (r,f,h,c)) arg_regs' arg_hints - platform <- getPlatform let packStack = platformOS platform == OSDarwin (stackSpace', passRegs, passArgumentsCode) <- passArguments packStack allGpArgRegs allFpArgRegs arg_regs'' 0 [] nilOL @@ -1625,6 +1624,270 @@ genCCall target dest_regs arg_regs bid = do | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs -> unaryFloatOp W64 (\d x -> unitOL $ FABS d x) arg_reg dest_reg + PrimTarget (MO_S_Mul2 w) + -- Life is easier when we're working with word sized operands, + -- we can use SMULH to compute the high 64 bits, and dst_needed + -- checks if the high half's bits are all the same as the low half's + -- top bit. + | w == W64 + , [src_a, src_b] <- arg_regs + -- dst_needed = did the result fit into just the low half + , [dst_needed, dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + nd = getRegisterReg platform (CmmLocal dst_needed) + return ( + code_x `appOL` + code_y `snocOL` + MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + SMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + -- Are all high bits equal to the sign bit of the low word? + -- nd = (hi == ASR(lo,width-1)) ? 1 : 0 + CMP (OpReg W64 hi) (OpRegShift W64 lo SASR (widthInBits w - 1)) `snocOL` + CSET (OpReg W64 nd) NE + , Nothing) + -- For sizes < platform width, we can just perform a multiply and shift + -- using the normal 64 bit multiply. Calculating the dst_needed value is + -- complicated a little by the need to be careful when truncation happens. + -- Currently this case can't be generated since + -- timesInt2# :: Int# -> Int# -> (# Int#, Int#, Int# #) + -- TODO: Should this be removed or would other primops be useful? + | w < W64 + , [src_a, src_b] <- arg_regs + , [dst_needed, dst_hi, dst_lo] <- dest_regs + -> do + (reg_a', _format_x, code_a) <- getSomeReg src_a + (reg_b', _format_y, code_b) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + nd = getRegisterReg platform (CmmLocal dst_needed) + -- Do everything in a full 64 bit registers + w' = platformWordWidth platform + + (reg_a, code_a') <- signExtendReg w w' reg_a' + (reg_b, code_b') <- signExtendReg w w' reg_b' + + return ( + code_a `appOL` + code_b `appOL` + code_a' `appOL` + code_b' `snocOL` + -- the low 2w' of lo contains the full multiplication; + -- eg: int8 * int8 -> int16 result + -- so lo is in the last w of the register, and hi is in the second w. + SMULL (OpReg w' lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL` + -- Make sure we hold onto the sign bits for dst_needed + ASR (OpReg w' hi) (OpReg w' lo) (OpImm (ImmInt $ widthInBits w)) `appOL` + -- lo can now be truncated so we can get at it's top bit easily. + truncateReg w' w lo `snocOL` + -- Note the use of CMN (compare negative), not CMP: we want to + -- test if the top half is negative one and the top + -- bit of the bottom half is positive one. eg: + -- hi = 0b1111_1111 (actually 64 bits) + -- lo = 0b1010_1111 (-81, so the result didn't need the top half) + -- lo' = ASR(lo,7) (second reg of SMN) + -- = 0b0000_0001 (theeshift gives us 1 for negative, + -- and 0 for positive) + -- hi == -lo'? + -- 0b1111_1111 == 0b1111_1111 (yes, top half is just overflow) + -- Another way to think of this is if hi + lo' == 0, which is what + -- CMN really is under the hood. + CMN (OpReg w' hi) (OpRegShift w' lo SLSR (widthInBits w - 1)) `snocOL` + -- Set dst_needed to 1 if hi and lo' were (negatively) equal + CSET (OpReg w' nd) EQ `appOL` + -- Finally truncate hi to drop any extraneous sign bits. + truncateReg w' w hi + , Nothing) + -- Can't handle > 64 bit operands + | otherwise -> unsupported (MO_S_Mul2 w) + PrimTarget (MO_U_Mul2 w) + -- The unsigned case is much simpler than the signed, all we need to + -- do is the multiplication straight into the destination registers. + | w == W64 + , [src_a, src_b] <- arg_regs + , [dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + return ( + code_x `appOL` + code_y `snocOL` + MUL (OpReg W64 lo) (OpReg W64 reg_a) (OpReg W64 reg_b) `snocOL` + UMULH (OpReg W64 hi) (OpReg W64 reg_a) (OpReg W64 reg_b) + , Nothing) + -- For sizes < platform width, we can just perform a multiply and shift + -- Need to be careful to truncate the low half, but the upper half should be + -- be ok if the invariant in [Signed arithmetic on AArch64] is maintained. + -- Currently this case can't be produced by the compiler since + -- timesWord2# :: Word# -> Word# -> (# Word#, Word# #) + -- TODO: Remove? Or would the extra primop be useful for avoiding the extra + -- steps needed to do this in userland? + | w < W64 + , [src_a, src_b] <- arg_regs + , [dst_hi, dst_lo] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src_a + (reg_b, _format_y, code_y) <- getSomeReg src_b + + let lo = getRegisterReg platform (CmmLocal dst_lo) + hi = getRegisterReg platform (CmmLocal dst_hi) + w' = opRegWidth w + return ( + code_x `appOL` + code_y `snocOL` + -- UMULL: Xd = Wa * Wb with 64 bit result + -- W64 inputs should have been caught by case above + UMULL (OpReg W64 lo) (OpReg w' reg_a) (OpReg w' reg_b) `snocOL` + -- Extract and truncate high result + -- hi[w:0] = lo[2w:w] + UBFX (OpReg W64 hi) (OpReg W64 lo) + (OpImm (ImmInt $ widthInBits w)) -- lsb + (OpImm (ImmInt $ widthInBits w)) -- width to extract + `appOL` + truncateReg W64 w lo + , Nothing) + | otherwise -> unsupported (MO_U_Mul2 w) + PrimTarget (MO_Clz w) + | w == W64 || w == W32 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst_reg = getRegisterReg platform (CmmLocal dst) + return ( + code_x `snocOL` + CLZ (OpReg w dst_reg) (OpReg w reg_a) + , Nothing) + | w == W16 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst' = getRegisterReg platform (CmmLocal dst) + r n = OpReg W32 n + imm n = OpImm (ImmInt n) + {- dst = clz(x << 16 | 0x0000_8000) -} + return ( + code_x `appOL` toOL + [ LSL (r dst') (r reg_a) (imm 16) + , ORR (r dst') (r dst') (imm 0x00008000) + , CLZ (r dst') (r dst') + ] + , Nothing) + | w == W8 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst' = getRegisterReg platform (CmmLocal dst) + r n = OpReg W32 n + imm n = OpImm (ImmInt n) + {- dst = clz(x << 24 | 0x0080_0000) -} + return ( + code_x `appOL` toOL + [ LSL (r dst') (r reg_a) (imm 24) + , ORR (r dst') (r dst') (imm 0x00800000) + , CLZ (r dst') (r dst') + ] + , Nothing) + | otherwise -> unsupported (MO_Clz w) + PrimTarget (MO_Ctz w) + | w == W64 || w == W32 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst_reg = getRegisterReg platform (CmmLocal dst) + return ( + code_x `snocOL` + RBIT (OpReg w dst_reg) (OpReg w reg_a) `snocOL` + CLZ (OpReg w dst_reg) (OpReg w dst_reg) + , Nothing) + | w == W16 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst' = getRegisterReg platform (CmmLocal dst) + r n = OpReg W32 n + imm n = OpImm (ImmInt n) + {- dst = clz(reverseBits(x) | 0x0000_8000) -} + return ( + code_x `appOL` toOL + [ RBIT (r dst') (r reg_a) + , ORR (r dst') (r dst') (imm 0x00008000) + , CLZ (r dst') (r dst') + ] + , Nothing) + | w == W8 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst' = getRegisterReg platform (CmmLocal dst) + r n = OpReg W32 n + imm n = OpImm (ImmInt n) + {- dst = clz(reverseBits(x) | 0x0080_0000) -} + return ( + code_x `appOL` toOL + [ RBIT (r dst') (r reg_a) + , ORR (r dst') (r dst') (imm 0x00800000) + , CLZ (r dst') (r dst') + ] + , Nothing) + | otherwise -> unsupported (MO_Ctz w) + PrimTarget (MO_BRev w) + | w == W64 || w == W32 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst_reg = getRegisterReg platform (CmmLocal dst) + return ( + code_x `snocOL` + RBIT (OpReg w dst_reg) (OpReg w reg_a) + , Nothing) + | w == W16 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst' = getRegisterReg platform (CmmLocal dst) + r n = OpReg W32 n + imm n = OpImm (ImmInt n) + {- dst = reverseBits32(x << 16) -} + return ( + code_x `appOL` toOL + [ LSL (r dst') (r reg_a) (imm 16) + , RBIT (r dst') (r dst') + ] + , Nothing) + | w == W8 + , [src] <- arg_regs + , [dst] <- dest_regs + -> do + (reg_a, _format_x, code_x) <- getSomeReg src + let dst' = getRegisterReg platform (CmmLocal dst) + r n = OpReg W32 n + imm n = OpImm (ImmInt n) + {- dst = reverseBits32(x << 24) -} + return ( + code_x `appOL` toOL + [ LSL (r dst') (r reg_a) (imm 24) + , RBIT (r dst') (r dst') + ] + , Nothing) + | otherwise -> unsupported (MO_BRev w) + + -- or a possibly side-effecting machine operation -- mop :: CallishMachOp (see GHC.Cmm.MachOp) PrimTarget mop -> do @@ -1714,7 +1977,6 @@ genCCall target dest_regs arg_regs bid = do -- Arithmatic -- These are not supported on X86, so I doubt they are used much. - MO_S_Mul2 _w -> unsupported mop MO_S_QuotRem _w -> unsupported mop MO_U_QuotRem _w -> unsupported mop MO_U_QuotRem2 _w -> unsupported mop @@ -1723,7 +1985,6 @@ genCCall target dest_regs arg_regs bid = do MO_SubWordC _w -> unsupported mop MO_AddIntC _w -> unsupported mop MO_SubIntC _w -> unsupported mop - MO_U_Mul2 _w -> unsupported mop -- Memory Ordering MO_AcquireFence -> return (unitOL DMBISH, Nothing) @@ -1751,10 +2012,7 @@ genCCall target dest_regs arg_regs bid = do MO_PopCnt w -> mkCCall (popCntLabel w) MO_Pdep w -> mkCCall (pdepLabel w) MO_Pext w -> mkCCall (pextLabel w) - MO_Clz w -> mkCCall (clzLabel w) - MO_Ctz w -> mkCCall (ctzLabel w) MO_BSwap w -> mkCCall (bSwapLabel w) - MO_BRev w -> mkCCall (bRevLabel w) -- -- Atomic read-modify-write. MO_AtomicRead w ord ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -79,11 +79,14 @@ regUsageOfInstr platform instr = case instr of -- 1. Arithmetic Instructions ------------------------------------------------ ADD dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) CMP l r -> usage (regOp l ++ regOp r, []) + CMN l r -> usage (regOp l ++ regOp r, []) MSUB dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst) MUL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) NEG dst src -> usage (regOp src, regOp dst) SMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SMULL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + UMULH dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + UMULL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SDIV dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) SUB dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) UDIV dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) @@ -97,6 +100,8 @@ regUsageOfInstr platform instr = case instr of UXTB dst src -> usage (regOp src, regOp dst) SXTH dst src -> usage (regOp src, regOp dst) UXTH dst src -> usage (regOp src, regOp dst) + CLZ dst src -> usage (regOp src, regOp dst) + RBIT dst src -> usage (regOp src, regOp dst) -- 3. Logical and Move Instructions ------------------------------------------ AND dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) ASR dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) @@ -136,7 +141,8 @@ regUsageOfInstr platform instr = case instr of FMA _ dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst) - _ -> panic $ "regUsageOfInstr: " ++ instrCon instr + LOCATION{} -> panic $ "regUsageOfInstr: " ++ instrCon instr + NEWBLOCK{} -> panic $ "regUsageOfInstr: " ++ instrCon instr where -- filtering the usage is necessary, otherwise the register @@ -209,11 +215,14 @@ patchRegsOfInstr instr env = case instr of -- 1. Arithmetic Instructions ---------------------------------------------- ADD o1 o2 o3 -> ADD (patchOp o1) (patchOp o2) (patchOp o3) CMP o1 o2 -> CMP (patchOp o1) (patchOp o2) + CMN o1 o2 -> CMN (patchOp o1) (patchOp o2) MSUB o1 o2 o3 o4 -> MSUB (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) MUL o1 o2 o3 -> MUL (patchOp o1) (patchOp o2) (patchOp o3) NEG o1 o2 -> NEG (patchOp o1) (patchOp o2) SMULH o1 o2 o3 -> SMULH (patchOp o1) (patchOp o2) (patchOp o3) SMULL o1 o2 o3 -> SMULL (patchOp o1) (patchOp o2) (patchOp o3) + UMULH o1 o2 o3 -> UMULH (patchOp o1) (patchOp o2) (patchOp o3) + UMULL o1 o2 o3 -> UMULL (patchOp o1) (patchOp o2) (patchOp o3) SDIV o1 o2 o3 -> SDIV (patchOp o1) (patchOp o2) (patchOp o3) SUB o1 o2 o3 -> SUB (patchOp o1) (patchOp o2) (patchOp o3) UDIV o1 o2 o3 -> UDIV (patchOp o1) (patchOp o2) (patchOp o3) @@ -227,6 +236,8 @@ patchRegsOfInstr instr env = case instr of UXTB o1 o2 -> UXTB (patchOp o1) (patchOp o2) SXTH o1 o2 -> SXTH (patchOp o1) (patchOp o2) UXTH o1 o2 -> UXTH (patchOp o1) (patchOp o2) + CLZ o1 o2 -> CLZ (patchOp o1) (patchOp o2) + RBIT o1 o2 -> RBIT (patchOp o1) (patchOp o2) -- 3. Logical and Move Instructions ---------------------------------------- AND o1 o2 o3 -> AND (patchOp o1) (patchOp o2) (patchOp o3) @@ -268,7 +279,8 @@ patchRegsOfInstr instr env = case instr of FMA s o1 o2 o3 o4 -> FMA s (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) - _ -> panic $ "patchRegsOfInstr: " ++ instrCon instr + NEWBLOCK{} -> panic $ "patchRegsOfInstr: " ++ instrCon instr + LOCATION{} -> panic $ "patchRegsOfInstr: " ++ instrCon instr where patchOp :: Operand -> Operand patchOp (OpReg w r) = OpReg w (env r) @@ -546,6 +558,7 @@ data Instr -- | ADR ... -- | ADRP ... | CMP Operand Operand -- rd - op2 + | CMN Operand Operand -- rd + op2 -- | MADD ... -- | MNEG ... | MSUB Operand Operand Operand Operand -- rd = ra - rn × rm @@ -568,8 +581,8 @@ data Instr -- | UMADDL ... -- Xd = Xa + Wn × Wm -- | UMNEGL ... -- Xd = - Wn × Wm -- | UMSUBL ... -- Xd = Xa - Wn × Wm - -- | UMULH ... -- Xd = (Xn × Xm)_127:64 - -- | UMULL ... -- Xd = Wn × Wm + | UMULH Operand Operand Operand -- Xd = (Xn × Xm)_127:64 + | UMULL Operand Operand Operand -- Xd = Wn × Wm -- 2. Bit Manipulation Instructions ---------------------------------------- | SBFM Operand Operand Operand Operand -- rd = rn[i,j] @@ -582,6 +595,8 @@ data Instr -- Signed/Unsigned bitfield extract | SBFX Operand Operand Operand Operand -- rd = rn[i,j] | UBFX Operand Operand Operand Operand -- rd = rn[i,j] + | CLZ Operand Operand -- rd = countLeadingZeros(rn) + | RBIT Operand Operand -- rd = reverseBits(rn) -- 3. Logical and Move Instructions ---------------------------------------- | AND Operand Operand Operand -- rd = rn & op2 @@ -650,18 +665,23 @@ instrCon i = POP_STACK_FRAME{} -> "POP_STACK_FRAME" ADD{} -> "ADD" CMP{} -> "CMP" + CMN{} -> "CMN" MSUB{} -> "MSUB" MUL{} -> "MUL" NEG{} -> "NEG" SDIV{} -> "SDIV" SMULH{} -> "SMULH" SMULL{} -> "SMULL" + UMULH{} -> "UMULH" + UMULL{} -> "UMULL" SUB{} -> "SUB" UDIV{} -> "UDIV" SBFM{} -> "SBFM" UBFM{} -> "UBFM" SBFX{} -> "SBFX" UBFX{} -> "UBFX" + CLZ{} -> "CLZ" + RBIT{} -> "RBIT" AND{} -> "AND" ASR{} -> "ASR" EOR{} -> "EOR" ===================================== compiler/GHC/CmmToAsm/AArch64/Ppr.hs ===================================== @@ -372,12 +372,15 @@ pprInstr platform instr = case instr of CMP o1 o2 | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfcmp") o1 o2 | otherwise -> op2 (text "\tcmp") o1 o2 + CMN o1 o2 -> op2 (text "\tcmn") o1 o2 MSUB o1 o2 o3 o4 -> op4 (text "\tmsub") o1 o2 o3 o4 MUL o1 o2 o3 | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 -> op3 (text "\tfmul") o1 o2 o3 | otherwise -> op3 (text "\tmul") o1 o2 o3 SMULH o1 o2 o3 -> op3 (text "\tsmulh") o1 o2 o3 SMULL o1 o2 o3 -> op3 (text "\tsmull") o1 o2 o3 + UMULH o1 o2 o3 -> op3 (text "\tumulh") o1 o2 o3 + UMULL o1 o2 o3 -> op3 (text "\tumull") o1 o2 o3 NEG o1 o2 | isFloatOp o1 && isFloatOp o2 -> op2 (text "\tfneg") o1 o2 | otherwise -> op2 (text "\tneg") o1 o2 @@ -393,6 +396,8 @@ pprInstr platform instr = case instr of -- 2. Bit Manipulation Instructions ------------------------------------------ SBFM o1 o2 o3 o4 -> op4 (text "\tsbfm") o1 o2 o3 o4 UBFM o1 o2 o3 o4 -> op4 (text "\tubfm") o1 o2 o3 o4 + CLZ o1 o2 -> op2 (text "\tclz") o1 o2 + RBIT o1 o2 -> op2 (text "\trbit") o1 o2 -- signed and unsigned bitfield extract SBFX o1 o2 o3 o4 -> op4 (text "\tsbfx") o1 o2 o3 o4 UBFX o1 o2 o3 o4 -> op4 (text "\tubfx") o1 o2 o3 o4 ===================================== compiler/GHC/Driver/Config/StgToCmm.hs ===================================== @@ -76,7 +76,8 @@ initStgToCmmConfig dflags mod = StgToCmmConfig | otherwise -> const True - , stgToCmmAllowIntMul2Instr = (ncg && x86ish) || llvm + , stgToCmmAllowIntMul2Instr = (ncg && (x86ish || aarch64)) || llvm + , stgToCmmAllowWordMul2Instr = (ncg && (x86ish || ppc || aarch64)) || llvm -- SIMD flags , stgToCmmVecInstrsErr = vec_err , stgToCmmAvx = isAvxEnabled dflags @@ -92,6 +93,9 @@ initStgToCmmConfig dflags mod = StgToCmmConfig JSPrimitives -> (False, False) NcgPrimitives -> (True, False) LlvmPrimitives -> (False, True) + aarch64 = case platformArch platform of + ArchAArch64 -> True + _ -> False x86ish = case platformArch platform of ArchX86 -> True ArchX86_64 -> True ===================================== compiler/GHC/StgToCmm/Config.hs ===================================== @@ -70,6 +70,7 @@ data StgToCmmConfig = StgToCmmConfig , stgToCmmAllowQuotRem2 :: !Bool -- ^ Allowed to generate QuotRem , stgToCmmAllowExtendedAddSubInstrs :: !Bool -- ^ Allowed to generate AddWordC, SubWordC, Add2, etc. , stgToCmmAllowIntMul2Instr :: !Bool -- ^ Allowed to generate IntMul2 instruction + , stgToCmmAllowWordMul2Instr :: !Bool -- ^ Allowed to generate WordMul2 instruction , stgToCmmAllowFMAInstr :: FMASign -> Bool -- ^ Allowed to generate FMA instruction , stgToCmmTickyAP :: !Bool -- ^ Disable use of precomputed standard thunks. ------------------------------ SIMD flags ------------------------------------ ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1623,7 +1623,7 @@ emitPrimOp cfg primop = else Right genericIntSubCOp WordMul2Op -> \args -> opCallishHandledLater args $ - if allowExtAdd + if allowWord2Mul then Left (MO_U_Mul2 (wordWidth platform)) else Right genericWordMul2Op @@ -1850,6 +1850,7 @@ emitPrimOp cfg primop = allowQuotRem2 = stgToCmmAllowQuotRem2 cfg allowExtAdd = stgToCmmAllowExtendedAddSubInstrs cfg allowInt2Mul = stgToCmmAllowIntMul2Instr cfg + allowWord2Mul = stgToCmmAllowWordMul2Instr cfg allowFMA = stgToCmmAllowFMAInstr cfg ===================================== libraries/os-string ===================================== @@ -1 +1 @@ -Subproject commit 8e13019854e1497cb83581bbcab25e763fcc4d4b +Subproject commit e1dd3bcfab56a6616c73ee9220de425d55545bc8 ===================================== rts/Interpreter.c ===================================== @@ -4,6 +4,30 @@ * Copyright (c) The GHC Team, 1994-2002. * ---------------------------------------------------------------------------*/ +/* +Note [CBV Functions and the interpreter] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When the byte code interpreter loads a reference to a value it often +ends up as a non-tagged pointers *especially* if we already know a value +is a certain constructor and therefore don't perform an eval on the reference. +This causes friction with CBV functions which assume +their value arguments are properly tagged by the caller. + +In order to ensure CBV functions still get passed tagged functions we have +three options: +a) Special case the interpreter behaviour into the tag inference analysis. + If we assume the interpreter can't properly tag value references the STG passes + would then wrap such calls in appropriate evals which are executed at runtime. + This would ensure tags by doing additional evals at runtime. +b) When the interpreter pushes references for known constructors instead of + pushing the objects address add the tag to the value pushed. This is what + the NCG backends do. +c) When the interpreter pushes a reference inspect the closure of the object + and apply the appropriate tag at runtime. + +For now we use approach c). Mostly because it's easiest to implement. We also don't +tag functions as tag inference currently doesn't rely on those being properly tagged. +*/ #include "rts/PosixSource.h" #include "Rts.h" @@ -1306,7 +1330,42 @@ run_BCO: case bci_PUSH_G: { W_ o1 = BCO_GET_LARGE_ARG; - SpW(-1) = BCO_PTR(o1); + StgClosure *tagged_obj = (StgClosure*) BCO_PTR(o1); + + tag_push_g: + ASSERT(LOOKS_LIKE_CLOSURE_PTR((StgClosure*) tagged_obj)); + // Here we make sure references we push are tagged. + // See Note [CBV Functions and the interpreter] in Info.hs + + //Safe some memory reads if we already have a tag. + if(GET_CLOSURE_TAG(tagged_obj) == 0) { + StgClosure *obj = UNTAG_CLOSURE(tagged_obj); + switch ( get_itbl(obj)->type ) { + case IND: + case IND_STATIC: + { + tagged_obj = ACQUIRE_LOAD(&((StgInd*)obj)->indirectee); + goto tag_push_g; + } + case CONSTR: + case CONSTR_1_0: + case CONSTR_0_1: + case CONSTR_2_0: + case CONSTR_1_1: + case CONSTR_0_2: + case CONSTR_NOCAF: + // The value is already evaluated, so we can just return it. However, + // before we do, we MUST ensure that the pointer is tagged, because we + // might return to a native `case` expression, which assumes the returned + // pointer is tagged so it can use the tag to select an alternative. + tagged_obj = tagConstr(obj); + break; + default: + break; + } + } + + SpW(-1) = (W_) tagged_obj; Sp_subW(1); goto nextInsn; } ===================================== testsuite/tests/codeGen/should_run/CtzClz0.hs ===================================== @@ -0,0 +1,27 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE MagicHash #-} + +module Main where + +import GHC.Exts +import Control.Monad + +#include + +{-# OPAQUE x #-} -- needed to avoid triggering constant folding +x :: Word +x = 0 + +main :: IO () +main = do + let !(W# w) = x + + guard (W# (ctz# w) == WORD_SIZE_IN_BITS) + guard (W# (ctz8# w) == 8) + guard (W# (ctz16# w) == 16) + guard (W# (ctz32# w) == 32) + + guard (W# (clz# w) == WORD_SIZE_IN_BITS) + guard (W# (clz8# w) == 8) + guard (W# (clz16# w) == 16) + guard (W# (clz32# w) == 32) ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -249,3 +249,4 @@ test('T24664b', normal, compile_and_run, ['-O']) test('T23034', [req_c , when(arch('x86_64') and opsys('darwin'), expect_broken(25018)) ], compile_and_run, ['-O2 T23034_c.c']) +test('CtzClz0', normal, compile_and_run, ['']) ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -50,6 +50,7 @@ test('T4383', normal, compile_and_run, ['']) test('add2', normal, compile_and_run, ['-fobject-code']) test('mul2', normal, compile_and_run, ['-fobject-code']) +test('mul2int', normal, compile_and_run, ['-fobject-code']) test('quotRem2', normal, compile_and_run, ['-fobject-code']) test('T5863', normal, compile_and_run, ['']) ===================================== testsuite/tests/numeric/should_run/mul2int.hs ===================================== @@ -0,0 +1,35 @@ +{-# LANGUAGE MagicHash, UnboxedTuples #-} + +import GHC.Exts +import Data.Bits + +main :: IO () +main = do g 5 6 + g (-5) 6 + g 0x7ECA71DBFF1B7D8C 49 + g (-0x7ECA71DBFF1B7D8C) 49 + g 0x7ECA71DBFF1B7D8C 0x7E0EC51DFD94FE35 + g 0x7ECA71DBFF1B7D8C (-0x7E0EC51DFD94FE35) + + +g :: Int -> Int -> IO () +g wx@(I# x) wy@(I# y) + = do putStrLn "-----" + putStrLn ("Doing " ++ show wx ++ " * " ++ show wy) + case x `timesInt2#` y of + (# n, h, l #) -> + do let wh = I# h + wl = I# l + wlw = W# (int2Word# l) + wn = I# n + r | wn == 1 = shiftL (fromIntegral wh) (finiteBitSize wh) + + fromIntegral wlw + | otherwise = fromIntegral wl + + putStrLn ("High: " ++ show wh) + putStrLn ("Low: " ++ show wl) + putStrLn ("Needed: " ++ show wn) + putStrLn ("Result: " ++ show (r :: Integer)) + putStrLn ("Should be: " ++ show (fromIntegral wx * fromIntegral wy :: Integer)) + + ===================================== testsuite/tests/numeric/should_run/mul2int.stdout ===================================== @@ -0,0 +1,42 @@ +----- +Doing 5 * 6 +High: 0 +Low: 30 +Needed: 0 +Result: 30 +Should be: 30 +----- +Doing -5 * 6 +High: -1 +Low: -30 +Needed: 0 +Result: -30 +Should be: -30 +----- +Doing 9136239983766240652 * 49 +High: 24 +Low: 4953901435516553164 +Needed: 1 +Result: 447675759204545791948 +Should be: 447675759204545791948 +----- +Doing -9136239983766240652 * 49 +High: -25 +Low: -4953901435516553164 +Needed: 1 +Result: -447675759204545791948 +Should be: -447675759204545791948 +----- +Doing 9136239983766240652 * 9083414231051992629 +High: 4498802171008813567 +Low: 3355592377236579836 +Needed: 1 +Result: 82988252286848496451678442784944154108 +Should be: 82988252286848496451678442784944154108 +----- +Doing 9136239983766240652 * -9083414231051992629 +High: -4498802171008813568 +Low: -3355592377236579836 +Needed: 1 +Result: -82988252286848496451678442784944154108 +Should be: -82988252286848496451678442784944154108 ===================================== testsuite/tests/numeric/should_run/mul2int.stdout-ws-32 ===================================== @@ -0,0 +1,42 @@ +----- +Doing 5 * 6 +High: 0 +Low: 30 +Needed: 0 +Result: 30 +Should be: 30 +----- +Doing -5 * 6 +High: -1 +Low: -30 +Needed: 0 +Result: -30 +Should be: -30 +----- +Doing -14975604 * 49 +High: -1 +Low: -733804596 +Needed: 0 +Result: -733804596 +Should be: -733804596 +----- +Doing 14975604 * 49 +High: 0 +Low: 733804596 +Needed: 0 +Result: 733804596 +Should be: 733804596 +----- +Doing -14975604 * -40567243 +High: 141449 +Low: 137487868 +Needed: 1 +Result: 607518966539772 +Should be: 607518966539772 +----- +Doing -14975604 * 40567243 +High: -141450 +Low: -137487868 +Needed: 1 +Result: -607518966539772 +Should be: -607518966539772 ===================================== testsuite/tests/th/should_compile/T24870/Def.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE TemplateHaskell #-} + +module SDef where + +{-# NOINLINE aValue #-} +aValue = True + +{-# NOINLINE aStrictFunction #-} +aStrictFunction !x = [| x |] ===================================== testsuite/tests/th/should_compile/T24870/Use.hs ===================================== @@ -0,0 +1,9 @@ +{-# LANGUAGE TemplateHaskell #-} + +module SUse where + +import qualified Language.Haskell.TH.Syntax as TH +import SDef +import GHC.Exts + +bar = $( inline aStrictFunction aValue ) ===================================== testsuite/tests/th/should_compile/T24870/all.T ===================================== @@ -0,0 +1,6 @@ +# The interpreter must uphold tagging invariants, and failed to do so in #24870 +# We test this here by having the interpreter calls a strict worker function +# with a reference to a value it constructed. +# See also Note [CBV Functions and the interpreter] +test('T24870', [extra_files(['Def.hs', 'Use.hs']), req_th], + multimod_compile, ['Def Use', '-dtag-inference-checks -v0']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a92613c21bc0d728d87fb48eb0a3f9bff20e04f5...6faa8336f63b1635e6a04564a8ec29ab7ce42a31 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a92613c21bc0d728d87fb48eb0a3f9bff20e04f5...6faa8336f63b1635e6a04564a8ec29ab7ce42a31 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 16:44:43 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 13 Jan 2025 11:44:43 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] X86 NCG: Fix argument promotion in foreign C calls Message-ID: <678542fb6e606_2477a0c2164908@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 3928048e by Peter Trommler at 2025-01-13T17:24:23+01:00 X86 NCG: Fix argument promotion in foreign C calls Promote 8 bit and 16 bit signed arguments by sign extension. Fixes #25018 (cherry picked from commit a82121b3b6fdc2ac47211f71871b3ab21e5f6276) - - - - - 2 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - testsuite/tests/codeGen/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2660,10 +2660,11 @@ genCCall32 :: CmmExpr -- ^ address of the function to call -> [CmmFormal] -- ^ where to put the result -> [CmmActual] -- ^ arguments (of mixed type) -> NatM InstrBlock -genCCall32 addr conv dest_regs args = do +genCCall32 addr (ForeignConvention _ argHints _ _) dest_regs args = do config <- getConfig let platform = ncgPlatform config - prom_args = map (maybePromoteCArg platform W32) args + args_hints = zip args (argHints ++ repeat NoHint) + prom_args = map (maybePromoteCArg platform W32) args_hints -- If the size is smaller than the word, we widen things (see maybePromoteCArg) arg_size_bytes :: CmmType -> Int @@ -2817,10 +2818,11 @@ genCCall64 :: CmmExpr -- ^ address of function to call -> [CmmFormal] -- ^ where to put the result -> [CmmActual] -- ^ arguments (of mixed type) -> NatM InstrBlock -genCCall64 addr conv dest_regs args = do +genCCall64 addr conv@(ForeignConvention _ argHints _ _) dest_regs args = do platform <- getPlatform -- load up the register arguments - let prom_args = map (maybePromoteCArg platform W32) args + let args_hints = zip args (argHints ++ repeat NoHint) + let prom_args = map (maybePromoteCArg platform W32) args_hints let load_args :: [CmmExpr] -> [Reg] -- int regs avail for args @@ -3058,9 +3060,11 @@ genCCall64 addr conv dest_regs args = do assign_code dest_regs) -maybePromoteCArg :: Platform -> Width -> CmmExpr -> CmmExpr -maybePromoteCArg platform wto arg - | wfrom < wto = CmmMachOp (MO_UU_Conv wfrom wto) [arg] +maybePromoteCArg :: Platform -> Width -> (CmmExpr, ForeignHint) -> CmmExpr +maybePromoteCArg platform wto (arg, hint) + | wfrom < wto = case hint of + SignedHint -> CmmMachOp (MO_SS_Conv wfrom wto) [arg] + _ -> CmmMachOp (MO_UU_Conv wfrom wto) [arg] | otherwise = arg where wfrom = cmmExprWidth platform arg ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -246,7 +246,5 @@ test('T24295a', normal, compile_and_run, ['-O -floopification']) test('T24295b', normal, compile_and_run, ['-O -floopification -fpedantic-bottoms']) test('T24664a', normal, compile_and_run, ['-O']) test('T24664b', normal, compile_and_run, ['-O']) -test('T23034', [req_c - , when(arch('x86_64') and opsys('darwin'), expect_broken(25018)) - ], compile_and_run, ['-O2 T23034_c.c']) test('CtzClz0', normal, compile_and_run, ['']) +test('T23034', req_c, compile_and_run, ['-O2 T23034_c.c']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3928048eea781394a688506414566793a46cf756 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3928048eea781394a688506414566793a46cf756 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 17:27:41 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 13 Jan 2025 12:27:41 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] 25 commits: configure: Set LD_STAGE0 appropiately when 9.10.1 is used as a boot compiler Message-ID: <67854d0d81cdd_2477a053ca141373b@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 5bc9d132 by Matthew Pickering at 2025-01-13T17:31:09+01:00 configure: Set LD_STAGE0 appropiately when 9.10.1 is used as a boot compiler In 9.10.1 the "ld command" has been removed, so we fall back to using the more precise "merge objects command" when it's available as LD_STAGE0 is only used to set the object merging command in hadrian. Fixes #24949 (cherry picked from commit 564981bda9a6a309ff0f524610af0f908432442f) - - - - - 8746a86c by Matthew Pickering at 2025-01-13T17:31:18+01:00 hadrian: Don't build ghci object files for ./hadrian/ghci target There is some convoluted logic which determines whether we build ghci object files are not. In any case, if you set `ghcDynPrograms = pure False` then it forces them to be built. Given we aren't ever building executables with this flavour it's fine to leave `ghcDynPrograms` as the default and it should be a bit faster to build less. Also fixes #24949 (cherry picked from commit a949c792388b5662dd199497541f9ad51c78d1a8) - - - - - 01d6b09b by Matthew Pickering at 2025-01-13T17:34:34+01:00 ci: Unset ALEX/HAPPY variables when testing bootstrap jobs Ticket #24826 reports a regression in 9.10.1 when building from a source distribution. This patch is an attempt to reproduce the issue on CI by more aggressively removing `alex` and `happy` from the environment. (cherry picked from commit 3f9548fe97c728ed60ba26811e4fe248fc28d2a7) - - - - - bc0fc221 by Andrea Bedini at 2025-01-13T17:34:44+01:00 hadrian: Ignore build-tool-depends fields in cabal files hadrian does not utilise the build-tool-depends fields in cabal files and their presence can cause issues when building source distribution (see #24826) Ideally Cabal would support building "full" source distributions which would remove the need for workarounds in hadrian but for now we can patch the build-tool-depends out of the cabal files. Fixes #24826 (cherry picked from commit aba2c9d4728262cd9a2d711eded9050ac131c6c1) - - - - - d6d2abe2 by Zubin Duggal at 2025-01-13T17:34:59+01:00 compiler: Fingerprint -fwrite-if-simplified-core We need to recompile if this flag is changed because later modules might depend on the simplified core for this module if -fprefer-bytecode is enabled. Fixes #24656 (cherry picked from commit dddc9dff0547733a10e7f505612ab9df3a7c21b6) - - - - - b3322a3a by Alex Mason at 2025-01-13T17:35:10+01:00 ncg(aarch64): Add fsqrt instruction, byteSwap primitives [#24956] Implements the FSQRT machop using native assembly rather than a C call. Implements MO_BSwap by producing assembly to do the byte swapping instead of producing a foreign call a C function. In `tar`, the hot loop for `deserialise` got almost 4x faster by avoiding the foreign call which caused spilling live variables to the stack -- this means the loop did 4x more memory read/writing than necessary in that particular case! (cherry picked from commit dee035bf618d75a18fe72dd3977434c0749a2156) - - - - - 0183e434 by Sylvain Henry at 2025-01-13T17:35:20+01:00 Linker: use m32 allocator for sections when NEED_PLT (#24432) Use M32 allocator to avoid fragmentation when allocating ELF sections. We already did this when NEED_PLT was undefined. Failing to do this led to relocations impossible to fulfil (#24432). (cherry picked from commit 5104ee615503617a1c124fe1d92f6aa2d263b7d0) - - - - - 9c5cf8f8 by Sylvain Henry at 2025-01-13T17:35:25+01:00 RTS: allow M32 allocation outside of 4GB range when assuming -fPIC (cherry picked from commit 52d6698479f951e07def237b0474ee22d27e621a) - - - - - 2822e96b by Sylvain Henry at 2025-01-13T17:35:31+01:00 Linker: fix stub offset Remove unjustified +8 offset that leads to memory corruption (cf discussion in #24432). (cherry picked from commit c34fef56367142fa55e9861092f64cc7b9946fa1) - - - - - ecd99e0b by Simon Peyton Jones at 2025-01-13T17:35:45+01:00 Address #25055, by disabling case-of-runRW# in Gentle phase See Note [Case-of-case and full laziness] in GHC.Driver.Config.Core.Opt.Simplify (cherry picked from commit de5d9852dbdd367611bf9e45e69c723d26351992) - - - - - 670a8cbc by Andreas Klebinger at 2025-01-13T17:40:11+01:00 Fix -freg-graphs for FP and AARch64 NCG (#24941). It seems we reserve 8 registers instead of four for global regs based on the layout in Note [AArch64 Register assignments]. I'm not sure it's neccesary, but for now we just accept this state of affairs and simple update -fregs-graph to account for this. (cherry picked from commit 3f89ab92da74c4ed45da68fe92ff81e7b9caa53d) - - - - - 823fec13 by Simon Peyton Jones at 2025-01-13T17:46:45+01:00 Fix nasty bug in occurrence analyser As #25096 showed, the occurrence analyser was getting one-shot info flat out wrong. This commit does two things: * It fixes the bug and actually makes the code a bit tidier too. The work is done in the new function GHC.Core.Opt.OccurAnal.mkRhsOccEnv, especially the bit that prepares the `occ_one_shots` for the RHS. See Note [The OccEnv for a right hand side] * When floating out a binding we must be conservative about one-shot info. But we were zapping the entire demand info, whereas we only really need zap the /top level/ cardinality. See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels For some reason there is a 2.2% improvement in compile-time allocation for CoOpt_Read. Otherwise nickels and dimes. Metric Decrease: CoOpt_Read (cherry picked from commit f6b4c1c9be71fc6fe4688337752ffa4ad84180d9) - - - - - 7c82602d by Arnaud Spiwack at 2025-01-13T17:47:24+01:00 Add tests for 25081 (cherry picked from commit e2f2a56e42d25bae178ae1692390bbbd6275176c) - - - - - 84ff3c72 by Arnaud Spiwack at 2025-01-13T17:47:32+01:00 Scale multiplicity in list comprehension Fixes #25081 (cherry picked from commit 23f50640e705c132f1a0689d4850866d0f0d76a6) - - - - - 544f2ba7 by doyougnu at 2025-01-13T17:47:42+01:00 Rts linker: add case for pc-rel 64 relocation part of the upstream haskell.nix patches (cherry picked from commit bfe4b3d3bbb98b39169fad063c6c32f06d167756) - - - - - 278b7f18 by Sylvain Henry at 2025-01-13T17:47:57+01:00 Only lookup ghcversion.h file in the RTS include-dirs by default. The code was introduced in 3549c952b535803270872adaf87262f2df0295a4. It used `getPackageIncludePath` which name doesn't convey that it looks into all include paths of the preload units too. So this behavior is probably unintentional and it should be ok to change it. Fix #25106 (cherry picked from commit f954f42823f6ca3588425a0d543d93ace86d89e4) - - - - - c1d30b65 by Andreas Klebinger at 2025-01-13T17:48:11+01:00 Add since annotation for -fkeep-auto-rules. This partially addresses #25082. - - - - - 219d34f9 by Andreas Klebinger at 2025-01-13T17:57:21+01:00 Mention `-fkeep-auto-rules` in release notes. It was added earlier but hadn't appeared in any release notes yet. Partially addresses #25082. - - - - - df444de5 by Sylvain Henry at 2025-01-13T18:01:33+01:00 Cmm: don't perform unsound optimizations on 32-bit compiler hosts - beef61351b240967b49169d27a9a19565cf3c4af enabled the use of MO_Add/MO_Sub for 64-bit operations in the C and LLVM backends - 6755d833af8c21bbad6585144b10e20ac4a0a1ab did the same for the x86 NCG backend However we store some literal values as `Int` in the compiler. As a result, some Cmm optimizations transformed target 64-bit literals into compiler `Int`. If the compiler is 32-bit, this leads to computing with wrong literals (see #24893 and #24700). This patch disables these Cmm optimizations for 32-bit compilers. This is unsatisfying (optimizations shouldn't be compiler-word-size dependent) but it fixes the bug and it makes the patch easy to backport. A proper fix would be much more invasive but it shall be implemented in the future. Co-authored-by: amesgen <amesgen at amesgen.de> (cherry picked from commit 7446a09a2d5b04b95cd43c03659b5647853124ce) - - - - - bc68b829 by Sylvain Henry at 2025-01-13T18:01:45+01:00 AARCH64 linker: skip NONE relocations This patch is part of the patches upstreamed from haskell.nix. See https://github.com/input-output-hk/haskell.nix/pull/1960 for the original report/patch. (cherry picked from commit c749bdfd3e21d712dc2b966482eb010165bdeebe) - - - - - 0d853dcc by sheaf at 2025-01-13T18:02:24+01:00 GHCi debugger: drop record name spaces for Ids When binding new local variables at a breakpoint, we should create Ids with variable namespace, and not record field namespace. Otherwise the rest of the compiler falls over because the IdDetails are wrong. Fixes #25109 (cherry picked from commit c29b2b5a77611b2bd6c3089765079bc43aec3e22) - - - - - 7241f7bf by Sylvain Henry at 2025-01-13T18:03:39+01:00 JS: support rubbish static literals (#25177) Support for rubbish dynamic literals was added in #24664. This patch does the same for static literals. Fix #25177 (cherry picked from commit 5092dbff750ee5b6fd082b7eed8574922a2b0bf4) - - - - - 784028b6 by Arsen Arsenović at 2025-01-13T18:04:06+01:00 ghc-toolchain: Don't leave stranded a.outs when testing for -g0 This happened because, when ghc-toolchain tests for -g0, it does so by compiling an empty program. This compilation creates an a.out. Since we create a temporary directory, lets place the test program compilation in it also, so that it gets cleaned up. Fixes: 25b0b40467d0a12601497117c0ad14e1fcab0b74 Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/25203 (cherry picked from commit b16605e7c135f8cfd357a60c7f358132faec6a84) - - - - - e9403d89 by Cheng Shao at 2025-01-13T18:04:16+01:00 rts: fix checkClosure error message This patch fixes an error message in checkClosure() when the closure has already been evacuated. The previous logic was meant to print the evacuated closure's type in the error message, but it was completely wrong, given info was not really an info table, but a tagged pointer that points to the closure's new address. (cherry picked from commit 0d3bc2fa3a9a8c342ec34bb9d32e493655a4ec69) - - - - - d55abf10 by Simon Peyton Jones at 2025-01-13T18:06:05+01:00 Add ZonkAny and document it This MR fixed #24817 by adding ZonkAny, which takes a Nat argument. See Note [Any types] in GHC.Builtin.Types, especially wrinkle (Any4). (cherry picked from commit cfbff65a8bde902b4510cdaead847bf7a52b4018) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/AArch64/Regs.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToJS/Literal.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Utils/Outputable.hs - configure.ac The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3928048eea781394a688506414566793a46cf756...d55abf10ff541174a0119f9e142ec4acaf2f2661 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3928048eea781394a688506414566793a46cf756...d55abf10ff541174a0119f9e142ec4acaf2f2661 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 17:58:52 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 13 Jan 2025 12:58:52 -0500 Subject: [Git][ghc/ghc][master] Remove SDocs from ErrCtxt & ErrInfo Message-ID: <6785545c549cf_2477a09e54bc235f2@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 30 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Errors/Types/PromotionErr.hs - compiler/GHC/Tc/Gen/Annotation.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2e7bf4467ba6ac39340453f4a03eac105bb8e653 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2e7bf4467ba6ac39340453f4a03eac105bb8e653 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 17:59:49 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 13 Jan 2025 12:59:49 -0500 Subject: [Git][ghc/ghc][master] Re CLC #300 - Specify fmap for NonEmpty as map Message-ID: <67855494f0587_2477a096e6b428088@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - 30 changed files: - libraries/base/changelog.md - libraries/base/src/Data/List/NonEmpty.hs - libraries/base/src/Data/Semigroup.hs - libraries/base/src/GHC/Base.hs - libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/src/GHC/Internal/Base.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs - libraries/ghc-internal/src/GHC/Internal/Data/Data.hs - libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs - libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs - + libraries/ghc-internal/src/GHC/Internal/Data/NonEmpty.hs - libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs - libraries/ghc-internal/src/GHC/Internal/Generics.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs - libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs - libraries/ghc-internal/src/GHC/Internal/Text/ParserCombinators/ReadP.hs - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - testsuite/tests/plugins/plugins09.stdout - testsuite/tests/plugins/plugins10.stdout - testsuite/tests/plugins/plugins11.stdout - testsuite/tests/plugins/static-plugins.stdout - testsuite/tests/profiling/should_run/callstack001.stdout - testsuite/tests/simplCore/should_compile/rule2.stderr Changes: ===================================== libraries/base/changelog.md ===================================== @@ -8,6 +8,7 @@ ([GHC #25066](https://gitlab.haskell.org/ghc/ghc/-/issues/25066), [CLC proposal #290](https://github.com/haskell/core-libraries-committee/issues/290)) * `Data.List.NonEmpty.{init,last,tails1}` are now defined using only total functions (rather than partial ones). ([CLC proposal #293](https://github.com/haskell/core-libraries-committee/issues/293)) * `Data.List.NonEmpty` functions now have the same laziness as their `Data.List` counterparts (i.e. make them more strict than they currently are) ([CLC proposal #107](https://github.com/haskell/core-libraries-committee/issues/107)) + * `instance Functor NonEmpty` is now specified using `map` (rather than duplicating code). ([CLC proposal #300](https://github.com/haskell/core-libraries-committee/issues/300)) ## 4.21.0.0 *TBA* * Introduce `Data.Bounded` module exporting the `Bounded` typeclass (finishing [CLC proposal #208](https://github.com/haskell/core-libraries-committee/issues/208)) ===================================== libraries/base/src/Data/List/NonEmpty.hs ===================================== @@ -123,7 +123,7 @@ import qualified GHC.Internal.Data.Foldable as Foldable import GHC.Internal.Data.Function (on) import GHC.Internal.Data.Ord (comparing) import GHC.Internal.Stack.Types (HasCallStack) -import GHC.Internal.Data.List.NonEmpty +import GHC.Internal.Data.List.NonEmpty (NonEmpty (..), map, zip, zipWith) infixr 5 <| @@ -290,10 +290,6 @@ toList (a :| as) = a : as lift :: Foldable f => ([a] -> [b]) -> f a -> NonEmpty b lift f = fromList . f . Foldable.toList --- | Map a function over a 'NonEmpty' stream. -map :: (a -> b) -> NonEmpty a -> NonEmpty b -map f (a :| as) = f a :| fmap f as - -- | The 'inits' function takes a stream @xs@ and returns all the -- finite prefixes of @xs@, starting with the shortest. The result is -- 'NonEmpty' because the result always contains the empty list as the first ===================================== libraries/base/src/Data/Semigroup.hs ===================================== @@ -105,7 +105,7 @@ module Data.Semigroup ( , ArgMax ) where -import GHC.Internal.Base hiding (Any) +import GHC.Internal.Base hiding (Any, NonEmpty(..)) import GHC.Internal.Enum import GHC.Internal.Show import GHC.Internal.Read @@ -116,6 +116,7 @@ import Data.Bifoldable import Data.Bifunctor import Data.Bitraversable import GHC.Internal.Data.Foldable +import GHC.Internal.Data.NonEmpty (NonEmpty(..)) import GHC.Internal.Data.Traversable import GHC.Internal.Data.Semigroup.Internal import GHC.Internal.Control.Monad.Fix ===================================== libraries/base/src/GHC/Base.hs ===================================== @@ -138,7 +138,8 @@ module GHC.Base , divModInt#, divModInt8#, divModInt16#, divModInt32# ) where -import GHC.Internal.Base +import GHC.Internal.Base hiding ( NonEmpty(..) ) +import GHC.Internal.Data.NonEmpty ( NonEmpty(..) ) import GHC.Prim hiding ( -- Hide dataToTag# ops because they are expected to break for ===================================== libraries/ghc-internal/ghc-internal.cabal.in ===================================== @@ -152,6 +152,7 @@ Library GHC.Internal.Data.List.NonEmpty GHC.Internal.Data.Maybe GHC.Internal.Data.Monoid + GHC.Internal.Data.NonEmpty GHC.Internal.Data.OldList GHC.Internal.Data.Ord GHC.Internal.Data.Proxy ===================================== libraries/ghc-internal/src/GHC/Internal/Base.hs ===================================== @@ -17,7 +17,7 @@ GHC.Prim Has no implementation. It defines built-in things, and copied to make GHC.Prim.hi GHC.Internal.Base Classes: Eq, Ord, Functor, Monad - Types: List, (), Int, Bool, Ordering, Char, String + Types: List, (), Int, Bool, Ordering, Char, String, NonEmpty GHC.Internal.Data.Tuple Types: tuples, plus instances for GHC.Internal.Base classes @@ -29,6 +29,13 @@ GHC.Internal.Data.Maybe Type: Maybe, plus instances for GHC.Internal.Base c GHC.Internal.List List functions +GHC.Internal.Data.NonEmpty Orphan instances for GHC.Internal.Base.NonEmpty of + GHC.Internal.Base classes (other than Eq and Ord) + plus function map + +GHC.Internal.Data.List.NonEmpty Re-export GHC.Internal.Data.NonEmpty plus + functions zip and zipWith + GHC.Internal.Num Class: Num, plus instances for Int Type: Integer, plus instances for all classes so far (Eq, Ord, Num, Show) @@ -753,12 +760,6 @@ needed to make foldr/build forms efficient are turned off, we'll get reasonably efficient translations anyway. -} --- | @since base-4.9.0.0 -instance Semigroup (NonEmpty a) where - (a :| as) <> bs = a :| (as ++ toList bs) - where - toList (c :| cs) = c : cs - -- | @since base-4.9.0.0 instance Semigroup b => Semigroup (a -> b) where f <> g = \x -> f x <> g x @@ -1709,27 +1710,6 @@ data NonEmpty a = a :| [a] , Ord -- ^ @since base-4.9.0.0 ) --- | @since base-4.9.0.0 -instance Functor NonEmpty where - fmap f (a :| as) = f a :| fmap f as - b <$ (_ :| as) = b :| (b <$ as) - --- | @since base-4.9.0.0 -instance Applicative NonEmpty where - pure a = a :| [] - (<*>) = ap - liftA2 = liftM2 - --- | @since base-4.9.0.0 -instance Monad NonEmpty where - (a :| as) >>= f = - case f a of - b :| bs -> b :| (bs ++ bs') - where - bs' = as >>= toList . f - toList (c :| cs) = c : cs - - ---------------------------------------------- -- The list type ===================================== libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs ===================================== @@ -32,9 +32,10 @@ import GHC.Internal.Data.Function ( fix ) import GHC.Internal.Data.Maybe import GHC.Internal.Data.Monoid ( Monoid, Dual(..), Sum(..), Product(..) , First(..), Last(..), Alt(..), Ap(..) ) +import GHC.Internal.Data.NonEmpty ( NonEmpty(..) ) import GHC.Internal.Data.Ord ( Down(..) ) import GHC.Internal.Data.Tuple ( Solo(..), snd ) -import GHC.Internal.Base ( Monad, NonEmpty(..), errorWithoutStackTrace, (.) ) +import GHC.Internal.Base ( Monad, errorWithoutStackTrace, (.) ) import GHC.Internal.Generics import GHC.Internal.List ( head, drop ) import GHC.Internal.Control.Monad.ST.Imp ===================================== libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs ===================================== @@ -22,9 +22,9 @@ import GHC.Internal.Control.Monad (liftM, liftM2, Monad(..)) import GHC.Internal.Data.Functor.Identity import qualified GHC.Internal.Data.Functor import GHC.Internal.Data.Monoid +import GHC.Internal.Data.NonEmpty ( NonEmpty(..) ) import GHC.Internal.Data.Ord ( Down(..) ) import GHC.Internal.Data.Proxy -import GHC.Internal.Base (NonEmpty(..)) --import qualified Data.List.NonEmpty as NE import GHC.Internal.Generics import qualified GHC.Internal.Data.List.NonEmpty as NE ===================================== libraries/ghc-internal/src/GHC/Internal/Data/Data.hs ===================================== @@ -115,11 +115,12 @@ import GHC.Internal.Data.Either import GHC.Internal.Data.Eq import GHC.Internal.Data.Maybe import GHC.Internal.Data.Monoid +import GHC.Internal.Data.NonEmpty ( NonEmpty(..) ) import GHC.Internal.Data.Ord import GHC.Internal.Data.List (findIndex) import GHC.Internal.Data.Typeable import GHC.Internal.Data.Version( Version(..) ) -import GHC.Internal.Base hiding (Any, IntRep, FloatRep) +import GHC.Internal.Base hiding (Any, IntRep, FloatRep, NonEmpty(..)) import GHC.Internal.List import GHC.Internal.Num import GHC.Internal.Read ===================================== libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs ===================================== @@ -1529,4 +1529,3 @@ the number of elements combined). The `mconcat` implementations for `Text` and `ByteString` preallocate the required storage, and then combine all the list elements in a single pass. -} - ===================================== libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs ===================================== @@ -4,9 +4,10 @@ module GHC.Internal.Data.List.NonEmpty ( NonEmpty(..) , zip , zipWith + , map ) where -import GHC.Internal.Base +import GHC.Internal.Data.NonEmpty (NonEmpty (..), map) import qualified GHC.Internal.Data.List as List -- | The 'zip' function takes two streams and returns a stream of ===================================== libraries/ghc-internal/src/GHC/Internal/Data/NonEmpty.hs ===================================== @@ -0,0 +1,48 @@ +{-# LANGUAGE Trustworthy #-} +{-# OPTIONS_GHC -Wno-orphans #-} + +module GHC.Internal.Data.NonEmpty + ( NonEmpty (..) + , map + ) where + +import GHC.Internal.Base + ( Applicative (..), Functor (..), Monad (..), NonEmpty (..) + , Semigroup (..), (++), (.), ap, liftM2 + ) + +-- The following were moved here from module Data.List.NonEmpty of the base +-- package: map. + +-- | Map a function over a 'NonEmpty' stream. +map :: (a -> b) -> NonEmpty a -> NonEmpty b +map f (a :| as) = f a :| fmap f as + +-- The following orphan instances were moved here from module GHC.Internal.Base: +-- Semigroup, Functor, Applicative and Monad. + +-- | @since base-4.9.0.0 +instance Semigroup (NonEmpty a) where + (a :| as) <> bs = a :| (as ++ toList bs) + where + toList (c :| cs) = c : cs + +-- | @since base-4.9.0.0 +instance Functor NonEmpty where + fmap = map + b <$ (_ :| as) = b :| (b <$ as) + +-- | @since base-4.9.0.0 +instance Applicative NonEmpty where + pure a = a :| [] + (<*>) = ap + liftA2 = liftM2 + +-- | @since base-4.9.0.0 +instance Monad NonEmpty where + (a :| as) >>= f = + case f a of + b :| bs -> b :| (bs ++ bs') + where + bs' = as >>= toList . f + toList (c :| cs) = c : cs ===================================== libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs ===================================== @@ -486,4 +486,3 @@ foldMapDefault :: forall t m a . (Traversable t, Monoid m) {-# INLINE foldMapDefault #-} -- See Note [Function coercion] in Data.Functor.Utils. foldMapDefault = coerce (traverse @t @(Const m) @a @()) - ===================================== libraries/ghc-internal/src/GHC/Internal/Generics.hs ===================================== @@ -1879,4 +1879,3 @@ instance SingKind DecidedStrictness where fromSing SDecidedLazy = DecidedLazy fromSing SDecidedStrict = DecidedStrict fromSing SDecidedUnpack = DecidedUnpack - ===================================== libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs ===================================== @@ -30,10 +30,11 @@ import Data.List.NonEmpty ( NonEmpty(..) ) import GHC.Exts (TYPE) import Prelude hiding (Applicative(..)) #else -import GHC.Internal.Base hiding (Type, Module, inline) +import GHC.Internal.Base hiding (NonEmpty (..), Type, Module, inline) import GHC.Internal.Data.Foldable import GHC.Internal.Data.Functor import GHC.Internal.Data.Maybe +import GHC.Internal.Data.NonEmpty (NonEmpty(..)) import GHC.Internal.Data.Traversable (traverse, sequenceA) import GHC.Internal.Integer import GHC.Internal.List (zip) ===================================== libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs ===================================== @@ -50,8 +50,9 @@ import GHC.Internal.Lexeme ( startsVarSym, startsVarId ) import GHC.Internal.Data.Either import GHC.Internal.Type.Reflection import GHC.Internal.Data.Bool -import GHC.Internal.Base hiding (Type, Module, inline) +import GHC.Internal.Base hiding (NonEmpty(..), Type, Module, inline) import GHC.Internal.Data.Foldable +import GHC.Internal.Data.NonEmpty (NonEmpty(..)) import GHC.Internal.Integer import GHC.Internal.Real import GHC.Internal.Word ===================================== libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs ===================================== @@ -50,8 +50,9 @@ import Foreign.C.String import Foreign.C.Types import GHC.Types (TYPE, RuntimeRep(..)) #else -import GHC.Internal.Base hiding (Type, Module, sequence) +import GHC.Internal.Base hiding (NonEmpty(..),Type, Module, sequence) import GHC.Internal.Data.Data hiding (Fixity(..)) +import GHC.Internal.Data.NonEmpty (NonEmpty(..)) import GHC.Internal.Data.Traversable import GHC.Internal.Word import GHC.Internal.Generics (Generic) ===================================== libraries/ghc-internal/src/GHC/Internal/Text/ParserCombinators/ReadP.hs ===================================== @@ -74,7 +74,8 @@ module GHC.Internal.Text.ParserCombinators.ReadP import GHC.Internal.Unicode ( isSpace ) import GHC.Internal.List ( replicate, null ) -import GHC.Internal.Base hiding ( many ) +import GHC.Internal.Base hiding ( NonEmpty (..), many ) +import GHC.Internal.Data.NonEmpty ( NonEmpty (..) ) import GHC.Internal.Control.Monad.Fail ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -11052,7 +11052,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Ap instance GHC.Internal.Base.Applicative GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Applicative ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Applicative ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11066,6 +11065,7 @@ instance forall s. GHC.Internal.Base.Applicative (GHC.Internal.Control.Monad.ST. instance GHC.Internal.Base.Applicative Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall e. GHC.Internal.Base.Applicative (GHC.Internal.Data.Either.Either e) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11086,7 +11086,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Fu instance GHC.Internal.Base.Functor GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Functor ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. GHC.Internal.Base.Functor ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11104,6 +11103,7 @@ instance forall s. GHC.Internal.Base.Functor (GHC.Internal.Control.Monad.ST.Lazy instance GHC.Internal.Base.Functor Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall a. GHC.Internal.Base.Functor (GHC.Internal.Data.Either.Either a) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11128,7 +11128,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Mo instance GHC.Internal.Base.Monad GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Monad ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Monad ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11141,6 +11140,7 @@ instance forall s. GHC.Internal.Base.Monad (GHC.Internal.Control.Monad.ST.Lazy.I instance GHC.Internal.Base.Monad Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall e. GHC.Internal.Base.Monad (GHC.Internal.Data.Either.Either e) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11218,7 +11218,6 @@ instance forall k (p :: k). GHC.Internal.Base.Monoid (GHC.Internal.Generics.U1 p instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Types.IO a) -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup [a] -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Maybe.Maybe a) -- Defined in ‘GHC.Internal.Base’ -instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Semigroup GHC.Types.Ordering -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Solo a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Semigroup a, GHC.Internal.Base.Semigroup b) => GHC.Internal.Base.Semigroup (a, b) -- Defined in ‘GHC.Internal.Base’ @@ -11248,6 +11247,7 @@ instance forall a b. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigrou instance forall a. GHC.Internal.Base.Semigroup (Data.Functor.Contravariant.Predicate a) -- Defined in ‘Data.Functor.Contravariant’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Data.Functor.Identity.Identity a) -- Defined in ‘GHC.Internal.Data.Functor.Identity’ instance [safe] forall k (f :: k -> *) (a :: k) (g :: k -> *). (GHC.Internal.Base.Semigroup (f a), GHC.Internal.Base.Semigroup (g a)) => GHC.Internal.Base.Semigroup (Data.Functor.Product.Product f g a) -- Defined in ‘Data.Functor.Product’ +instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Semigroup GHC.Internal.Data.Semigroup.Internal.All -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Semigroup GHC.Internal.Data.Semigroup.Internal.Any -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Data.Semigroup.Internal.Dual a) -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -14093,7 +14093,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Ap instance GHC.Internal.Base.Applicative GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Applicative ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Applicative ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -14107,6 +14106,7 @@ instance forall s. GHC.Internal.Base.Applicative (GHC.Internal.Control.Monad.ST. instance GHC.Internal.Base.Applicative Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall e. GHC.Internal.Base.Applicative (GHC.Internal.Data.Either.Either e) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -14127,7 +14127,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Fu instance GHC.Internal.Base.Functor GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Functor ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. GHC.Internal.Base.Functor ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -14145,6 +14144,7 @@ instance forall s. GHC.Internal.Base.Functor (GHC.Internal.Control.Monad.ST.Lazy instance GHC.Internal.Base.Functor Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall a. GHC.Internal.Base.Functor (GHC.Internal.Data.Either.Either a) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -14169,7 +14169,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Mo instance GHC.Internal.Base.Monad GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Monad ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Monad ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -14182,6 +14181,7 @@ instance forall s. GHC.Internal.Base.Monad (GHC.Internal.Control.Monad.ST.Lazy.I instance GHC.Internal.Base.Monad Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall e. GHC.Internal.Base.Monad (GHC.Internal.Data.Either.Either e) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -14256,7 +14256,6 @@ instance forall k (p :: k). GHC.Internal.Base.Monoid (GHC.Internal.Generics.U1 p instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Types.IO a) -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup [a] -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Maybe.Maybe a) -- Defined in ‘GHC.Internal.Base’ -instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Semigroup GHC.Types.Ordering -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Solo a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Semigroup a, GHC.Internal.Base.Semigroup b) => GHC.Internal.Base.Semigroup (a, b) -- Defined in ‘GHC.Internal.Base’ @@ -14286,6 +14285,7 @@ instance forall a b. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigrou instance forall a. GHC.Internal.Base.Semigroup (Data.Functor.Contravariant.Predicate a) -- Defined in ‘Data.Functor.Contravariant’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Data.Functor.Identity.Identity a) -- Defined in ‘GHC.Internal.Data.Functor.Identity’ instance [safe] forall k (f :: k -> *) (a :: k) (g :: k -> *). (GHC.Internal.Base.Semigroup (f a), GHC.Internal.Base.Semigroup (g a)) => GHC.Internal.Base.Semigroup (Data.Functor.Product.Product f g a) -- Defined in ‘Data.Functor.Product’ +instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Semigroup GHC.Internal.Data.Semigroup.Internal.All -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Semigroup GHC.Internal.Data.Semigroup.Internal.Any -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Data.Semigroup.Internal.Dual a) -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -11320,7 +11320,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Ap instance GHC.Internal.Base.Applicative GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Applicative ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Applicative ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11334,6 +11333,7 @@ instance forall s. GHC.Internal.Base.Applicative (GHC.Internal.Control.Monad.ST. instance GHC.Internal.Base.Applicative Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall e. GHC.Internal.Base.Applicative (GHC.Internal.Data.Either.Either e) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11354,7 +11354,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Fu instance GHC.Internal.Base.Functor GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Functor ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. GHC.Internal.Base.Functor ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11372,6 +11371,7 @@ instance forall s. GHC.Internal.Base.Functor (GHC.Internal.Control.Monad.ST.Lazy instance GHC.Internal.Base.Functor Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall a. GHC.Internal.Base.Functor (GHC.Internal.Data.Either.Either a) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11396,7 +11396,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Mo instance GHC.Internal.Base.Monad GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Monad ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Monad ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11409,6 +11408,7 @@ instance forall s. GHC.Internal.Base.Monad (GHC.Internal.Control.Monad.ST.Lazy.I instance GHC.Internal.Base.Monad Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall e. GHC.Internal.Base.Monad (GHC.Internal.Data.Either.Either e) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11484,7 +11484,6 @@ instance forall k (p :: k). GHC.Internal.Base.Monoid (GHC.Internal.Generics.U1 p instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Types.IO a) -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup [a] -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Maybe.Maybe a) -- Defined in ‘GHC.Internal.Base’ -instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Semigroup GHC.Types.Ordering -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Solo a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Semigroup a, GHC.Internal.Base.Semigroup b) => GHC.Internal.Base.Semigroup (a, b) -- Defined in ‘GHC.Internal.Base’ @@ -11514,6 +11513,7 @@ instance forall a b. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigrou instance forall a. GHC.Internal.Base.Semigroup (Data.Functor.Contravariant.Predicate a) -- Defined in ‘Data.Functor.Contravariant’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Data.Functor.Identity.Identity a) -- Defined in ‘GHC.Internal.Data.Functor.Identity’ instance [safe] forall k (f :: k -> *) (a :: k) (g :: k -> *). (GHC.Internal.Base.Semigroup (f a), GHC.Internal.Base.Semigroup (g a)) => GHC.Internal.Base.Semigroup (Data.Functor.Product.Product f g a) -- Defined in ‘Data.Functor.Product’ +instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Semigroup GHC.Internal.Data.Semigroup.Internal.All -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Semigroup GHC.Internal.Data.Semigroup.Internal.Any -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Data.Semigroup.Internal.Dual a) -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -11052,7 +11052,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Ap instance GHC.Internal.Base.Applicative GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Applicative ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Applicative ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11066,6 +11065,7 @@ instance forall s. GHC.Internal.Base.Applicative (GHC.Internal.Control.Monad.ST. instance GHC.Internal.Base.Applicative Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall e. GHC.Internal.Base.Applicative (GHC.Internal.Data.Either.Either e) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11086,7 +11086,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Fu instance GHC.Internal.Base.Functor GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Functor ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. GHC.Internal.Base.Functor ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11104,6 +11103,7 @@ instance forall s. GHC.Internal.Base.Functor (GHC.Internal.Control.Monad.ST.Lazy instance GHC.Internal.Base.Functor Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall a. GHC.Internal.Base.Functor (GHC.Internal.Data.Either.Either a) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Functor GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11128,7 +11128,6 @@ instance forall (m :: * -> *). GHC.Internal.Base.Monad m => GHC.Internal.Base.Mo instance GHC.Internal.Base.Monad GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Monad ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Monad ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -11141,6 +11140,7 @@ instance forall s. GHC.Internal.Base.Monad (GHC.Internal.Control.Monad.ST.Lazy.I instance GHC.Internal.Base.Monad Data.Complex.Complex -- Defined in ‘Data.Complex’ instance forall e. GHC.Internal.Base.Monad (GHC.Internal.Data.Either.Either e) -- Defined in ‘GHC.Internal.Data.Either’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Functor.Identity.Identity -- Defined in ‘GHC.Internal.Data.Functor.Identity’ +instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Dual -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Product -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Monad GHC.Internal.Data.Semigroup.Internal.Sum -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ @@ -11218,7 +11218,6 @@ instance forall k (p :: k). GHC.Internal.Base.Monoid (GHC.Internal.Generics.U1 p instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Types.IO a) -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup [a] -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Maybe.Maybe a) -- Defined in ‘GHC.Internal.Base’ -instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Semigroup GHC.Types.Ordering -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Solo a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Semigroup a, GHC.Internal.Base.Semigroup b) => GHC.Internal.Base.Semigroup (a, b) -- Defined in ‘GHC.Internal.Base’ @@ -11248,6 +11247,7 @@ instance forall a b. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigrou instance forall a. GHC.Internal.Base.Semigroup (Data.Functor.Contravariant.Predicate a) -- Defined in ‘Data.Functor.Contravariant’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Data.Functor.Identity.Identity a) -- Defined in ‘GHC.Internal.Data.Functor.Identity’ instance [safe] forall k (f :: k -> *) (a :: k) (g :: k -> *). (GHC.Internal.Base.Semigroup (f a), GHC.Internal.Base.Semigroup (g a)) => GHC.Internal.Base.Semigroup (Data.Functor.Product.Product f g a) -- Defined in ‘Data.Functor.Product’ +instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Data.NonEmpty’ instance GHC.Internal.Base.Semigroup GHC.Internal.Data.Semigroup.Internal.All -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance GHC.Internal.Base.Semigroup GHC.Internal.Data.Semigroup.Internal.Any -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Data.Semigroup.Internal.Dual a) -- Defined in ‘GHC.Internal.Data.Semigroup.Internal’ ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout ===================================== @@ -10648,7 +10648,6 @@ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Ord.Down -- Defined in instance GHC.Internal.Base.Applicative GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Applicative ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Applicative ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -10657,7 +10656,6 @@ instance GHC.Internal.Base.Functor GHC.Internal.Data.Ord.Down -- Defined in ‘G instance GHC.Internal.Base.Functor GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Functor ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. GHC.Internal.Base.Functor ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -10669,7 +10667,6 @@ instance GHC.Internal.Base.Monad GHC.Internal.Data.Ord.Down -- Defined in ‘GHC instance GHC.Internal.Base.Monad GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Monad ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Monad ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -10692,7 +10689,6 @@ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Types.IO a) -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup [a] -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Maybe.Maybe a) -- Defined in ‘GHC.Internal.Base’ -instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Semigroup GHC.Types.Ordering -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Solo a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Semigroup a, GHC.Internal.Base.Semigroup b) => GHC.Internal.Base.Semigroup (a, b) -- Defined in ‘GHC.Internal.Base’ ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 ===================================== @@ -10651,7 +10651,6 @@ instance GHC.Internal.Base.Applicative GHC.Internal.Data.Ord.Down -- Defined in instance GHC.Internal.Base.Applicative GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Applicative GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Applicative Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Applicative ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Applicative ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -10660,7 +10659,6 @@ instance GHC.Internal.Base.Functor GHC.Internal.Data.Ord.Down -- Defined in ‘G instance GHC.Internal.Base.Functor GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Functor GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Functor Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Functor ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. GHC.Internal.Base.Functor ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -10672,7 +10670,6 @@ instance GHC.Internal.Base.Monad GHC.Internal.Data.Ord.Down -- Defined in ‘GHC instance GHC.Internal.Base.Monad GHC.Types.IO -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad [] -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad GHC.Internal.Maybe.Maybe -- Defined in ‘GHC.Internal.Base’ -instance GHC.Internal.Base.Monad GHC.Internal.Base.NonEmpty -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Monad Solo -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Monoid a => GHC.Internal.Base.Monad ((,) a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Monoid a, GHC.Internal.Base.Monoid b) => GHC.Internal.Base.Monad ((,,) a b) -- Defined in ‘GHC.Internal.Base’ @@ -10695,7 +10692,6 @@ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Types.IO a) -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup [a] -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (GHC.Internal.Maybe.Maybe a) -- Defined in ‘GHC.Internal.Base’ -instance forall a. GHC.Internal.Base.Semigroup (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’ instance GHC.Internal.Base.Semigroup GHC.Types.Ordering -- Defined in ‘GHC.Internal.Base’ instance forall a. GHC.Internal.Base.Semigroup a => GHC.Internal.Base.Semigroup (Solo a) -- Defined in ‘GHC.Internal.Base’ instance forall a b. (GHC.Internal.Base.Semigroup a, GHC.Internal.Base.Semigroup b) => GHC.Internal.Base.Semigroup (a, b) -- Defined in ‘GHC.Internal.Base’ ===================================== testsuite/tests/plugins/plugins09.stdout ===================================== @@ -1,6 +1,7 @@ parsePlugin(a,b) interfacePlugin: Prelude interfacePlugin: GHC.Internal.Base +interfacePlugin: GHC.Internal.Data.NonEmpty interfacePlugin: GHC.Internal.Float interfacePlugin: GHC.Prim.Ext typeCheckPlugin (rn) ===================================== testsuite/tests/plugins/plugins10.stdout ===================================== @@ -3,6 +3,7 @@ interfacePlugin: Prelude interfacePlugin: Language.Haskell.TH interfacePlugin: Language.Haskell.TH.Quote interfacePlugin: GHC.Internal.Base +interfacePlugin: GHC.Internal.Data.NonEmpty interfacePlugin: GHC.Internal.Float interfacePlugin: GHC.Prim.Ext interfacePlugin: GHC.Internal.TH.Quote ===================================== testsuite/tests/plugins/plugins11.stdout ===================================== @@ -1,6 +1,7 @@ parsePlugin() interfacePlugin: Prelude interfacePlugin: GHC.Internal.Base +interfacePlugin: GHC.Internal.Data.NonEmpty interfacePlugin: GHC.Internal.Float interfacePlugin: GHC.Prim.Ext typeCheckPlugin (rn) ===================================== testsuite/tests/plugins/static-plugins.stdout ===================================== @@ -2,6 +2,7 @@ parsePlugin() interfacePlugin: Prelude interfacePlugin: GHC.Internal.Base +interfacePlugin: GHC.Internal.Data.NonEmpty interfacePlugin: GHC.Internal.Float interfacePlugin: GHC.Prim.Ext interfacePlugin: GHC.Internal.System.IO ===================================== testsuite/tests/profiling/should_run/callstack001.stdout ===================================== @@ -1,2 +1,2 @@ -["GHC.Internal.TopHandler.runMainIO1 ()","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","Main.mapM.go (callstack001.hs:13:17-19)","Main.f (callstack001.hs:7:7-49)","Main.f (callstack001.hs:7:10-35)","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1348:5-55)","GHC.Internal.Base.$fMonadIO1 ()","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 ()"] -["GHC.Internal.TopHandler.runMainIO1 ()","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1348:5-55)","GHC.Internal.Base.$fMonadIO1 ()","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 ()"] +["GHC.Internal.TopHandler.runMainIO1 ()","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","Main.mapM.go (callstack001.hs:13:17-19)","Main.f (callstack001.hs:7:7-49)","Main.f (callstack001.hs:7:10-35)","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1349:5-55)","GHC.Internal.Base.$fMonadIO1 ()","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 ()"] +["GHC.Internal.TopHandler.runMainIO1 ()","Main.main (callstack001.hs:17:8-21)","Main.mapM (callstack001.hs:10:13-17)","Main.mapM.go (callstack001.hs:(12,21)-(15,25))","GHC.Internal.Base.>>= (libraries/ghc-internal/src/GHC/Internal/Base.hs:1349:5-55)","GHC.Internal.Base.$fMonadIO1 ()","GHC.Internal.Stack.CCS.currentCallStack (libraries/ghc-internal/src/GHC/Internal/Stack/CCS.hsc:126:1-16)","GHC.Internal.Stack.CCS.currentCallStack1 ()"] ===================================== testsuite/tests/simplCore/should_compile/rule2.stderr ===================================== @@ -10,12 +10,14 @@ ==================== Grand total simplifier statistics ==================== -Total ticks: 12 +Total ticks: 13 2 PreInlineUnconditionally 1 f 1 ds -1 UnfoldingDone 1 Roman.bar +2 UnfoldingDone + 1 GHC.Internal.Base.id + 1 Roman.bar 1 RuleFired 1 foo/bar 1 LetFloatFromLet 1 7 BetaReduction @@ -27,5 +29,3 @@ Total ticks: 12 1 m 1 ds 8 SimplifierDone 8 - - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d62b970b79b61138bca678761cc745911d9125d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d62b970b79b61138bca678761cc745911d9125d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 18:01:34 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 13 Jan 2025 13:01:34 -0500 Subject: [Git][ghc/ghc][master] compiler/coreprep: Turn off dictionary speculation by default Message-ID: <678554fe782_2477a0e74a6432255@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 4 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - docs/users_guide/using-optimisation.rst - testsuite/tests/rts/ipe/T24005/t24005.hs Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -2054,12 +2054,27 @@ floats and how far they go. Note [Controlling Speculative Evaluation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Most of the time, speculative evaluation has a positive effect on performance, -but we have found a case where speculative evaluation of dictionary functions -leads to a performance regression #25284. - -Therefore we have some flags to control it. See the optimization section in -the User's Guide for the description of these flags and when to use them. +Most of the time, speculative evaluation in the coreprep phase has a positive +effect on performance, however we have found that some forms of speculative +evaluation can lead to large performance regressions. See #25284. + +Therefore we have some flags to control which types of speculative evaluation +are done: + + -fspec-eval + Globally enable/disable speculative evaluation ( -fno-spec-eval also turns + off all other speculative evaluation). On by default for all + optimization levels. Turning on this flag by itself should never cause + a performance regression. Please open a ticket if you find any. + + -fspec-eval-dictfun + Enable speculative evaluation for dictionary functions. Off by default + since it can cause an increase in allocations (#24284). We have no + examples that show a large performance improvement when turning on this + flag. Please open a ticket if you find any. + +Also see the optimization section in the User's Guide for the description of +these flags and when to use them. Note [Floats and FloatDecision] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Driver/DynFlags.hs ===================================== @@ -1288,7 +1288,7 @@ optLevelFlags -- see Note [Documenting optimisation flags] -- , ([2], Opt_StaticArgumentTransformation) -- Static Argument Transformation needs investigation. See #9374 , ([0,1,2], Opt_SpecEval) - , ([0,1,2], Opt_SpecEvalDictFun) + , ([], Opt_SpecEvalDictFun) ] ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -428,7 +428,7 @@ as such you shouldn't need to set any of them explicitly. A flag :category: :reverse: -fno-spec-eval-dictfun - :default: on + :default: off :since: 9.14.1 Enables speculative (strict) evaluation of dictionary functions. ===================================== testsuite/tests/rts/ipe/T24005/t24005.hs ===================================== @@ -32,5 +32,5 @@ instance Show a => Show (B a) where main :: IO () main = do -- Should both result in InfoProvs with correct source locations - (\(Box d) -> print =<< whereFrom d) $ mkBox @(Show A) - (\(Box d) -> print =<< whereFrom d) $ mkBox @(Show (B A)) + (\(Box !d) -> print =<< whereFrom d) $ mkBox @(Show A) + (\(Box !d) -> print =<< whereFrom d) $ mkBox @(Show (B A)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab3ab3e3d489a351e84f4fe681de1731549376a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab3ab3e3d489a351e84f4fe681de1731549376a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 18:32:28 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 13 Jan 2025 13:32:28 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] 4 commits: Remove SDocs from ErrCtxt & ErrInfo Message-ID: <67855c3cd682f_28e88bc7880836a6@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 040c4294 by Patrick at 2025-01-14T02:30:44+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 30 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Errors/Types/PromotionErr.hs - compiler/GHC/Tc/Gen/Annotation.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1afaf853f59c7d4bd80a79639d375be15380faf5...040c429472850832e3a75c310bc0e23f1f82cc88 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1afaf853f59c7d4bd80a79639d375be15380faf5...040c429472850832e3a75c310bc0e23f1f82cc88 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 18:35:53 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 13 Jan 2025 13:35:53 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593] Enhance kind inference for data family instances Message-ID: <67855d09ef1b8_28e88bc46e48433a@gitlab.mail> Patrick pushed to branch wip/soulomoon/suggest-UnliftedNewtypes-unlifted-data-family-25593 at Glasgow Haskell Compiler / GHC Commits: 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 13 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs - + testsuite/tests/indexed-types/should_compile/T25611a.hs - + testsuite/tests/indexed-types/should_compile/T25611b.hs - testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.hs → testsuite/tests/indexed-types/should_compile/T25611c.hs - + testsuite/tests/indexed-types/should_compile/T25611d.hs - testsuite/tests/indexed-types/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2468,7 +2469,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3921,14 +3922,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1140,7 +1140,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1257,7 +1257,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2128,7 +2128,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2223,14 +2223,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -715,7 +716,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env ; skol_info <- mkSkolemInfo FamInstSkol ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -740,8 +741,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -919,8 +919,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -928,7 +927,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -944,16 +943,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1005,9 +1005,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1033,6 +1040,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1187,31 +1209,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_compile/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/indexed-types/should_compile/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.hs → testsuite/tests/indexed-types/should_compile/T25611c.hs ===================================== @@ -6,7 +6,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE GADTs #-} -module UnliftedNewtypesUnassociatedFamily where +module T25611c where import GHC.Int (Int(I#)) import GHC.Word (Word(W#)) @@ -15,9 +15,15 @@ import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) data family DF :: TYPE (r :: RuntimeRep) --- All these fail: see #18891 and !4419 +-- it used to be failed: see #18891 and !4419 -- See Note [Kind inference for data family instances] -- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 newtype instance DF = MkDF1a Int# newtype instance DF = MkDF2a Word# newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/indexed-types/should_compile/T25611d.hs ===================================== @@ -0,0 +1,38 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,8 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype family instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,8 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • In the associated newtype family instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the associated newtype family instance declaration for ‘Bar’ ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype family instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype family instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype family instance declaration for ‘DF’ - ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d9cacd5b09019c4ce2ccea9a509220bb44e36a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d9cacd5b09019c4ce2ccea9a509220bb44e36a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 13 18:59:23 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 13 Jan 2025 13:59:23 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] 5 commits: Remove SDocs from ErrCtxt & ErrInfo Message-ID: <6785628b848d4_28e88b3b66cc903b1@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - fcdf16e5 by Patrick at 2025-01-14T02:47:13+08:00 allow newtype instance in gadt syntax update T23308 move T18891a from should_fail to should_compile Move T21447 from should_fail to should_compile Remove `IsGADT` case - - - - - 30 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Errors/Types/PromotionErr.hs - compiler/GHC/Tc/Gen/Annotation.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3bf19b5c64cea02639a21a25e38bcc0f3c085fdb...fcdf16e591743af1a358bbcc5727662102a4f653 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3bf19b5c64cea02639a21a25e38bcc0f3c085fdb...fcdf16e591743af1a358bbcc5727662102a4f653 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 00:09:06 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Mon, 13 Jan 2025 19:09:06 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.10] 230 commits: Fix eta-expansion in Prep Message-ID: <6785ab222f21b_31a5b397499c27545@gitlab.mail> Cheng Shao pushed to branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: 94e008c5 by Simon Peyton Jones at 2024-08-19T09:28:48+02:00 Fix eta-expansion in Prep As #25033 showed, we were eta-expanding in a way that broke a join point, which messed up Note [CorePrep invariants]. The fix is rather easy. See Wrinkle (EA1) of Note [Eta expansion of arguments in CorePrep] (cherry picked from commit 8bf6fd68001bc1dabdd974506fc735e22e8257a9) - - - - - 13f3cc8f by Teo Camarasu at 2024-12-06T16:59:29+01:00 Add HasCallStack to T23221 This makes the test a bit easier to debug (cherry picked from commit 18c495c1bf3e37daf0030c983ffdd7697eb4072b) - - - - - 6986a1ef by Teo Camarasu at 2024-12-06T17:07:50+01:00 rts: use live words to estimate heap size We use live words rather than live blocks to determine the size of the heap for determining memory retention. Most of the time these two metrics align, but they can come apart in normal usage when using the nonmoving collector. The nonmoving collector leads to a lot of partially occupied blocks. So, using live words is more accurate. They can also come apart when the heap is suffering from high levels fragmentation caused by small pinned objects, but in this case, the block size is the more accurate metric. Since this case is best avoided anyway. It is ok to accept the trade-off that we might try (and probably) fail to return more memory in this case. See also the Note [Statistics for retaining memory] Resolves #23397 (cherry picked from commit 2f71e8b0dc346d3b74cf1ea6da8c63f9c9fe2073) - - - - - 9bcf1f1c by ur4t at 2024-12-06T17:10:53+01:00 GHCi: fix improper location of ghci_history file Fixes #24266 (cherry picked from commit 6f0a62db5dc79640433c61e83ea1427665304869) - - - - - 82616fb0 by Andreas Klebinger at 2024-12-06T17:14:58+01:00 Mention .ghci_history XGD changes in changelog. - - - - - 25d72bab by Cheng Shao at 2024-12-06T17:18:03+01:00 rts: do not prefetch mark_closure bdescr in non-moving gc when ASSERTS_ENABLED This commit fixes a small an oversight in !12148: the prefetch logic in non-moving GC may trap in debug RTS because it calls Bdescr() for mark_closure which may be a static one. It's fine in non-debug RTS because even invalid bdescr addresses are prefetched, they will not cause segfaults, so this commit implements the most straightforward fix: don't prefetch mark_closure bdescr when assertions are enabled. (cherry picked from commit 8f74b38148f0d8b9341099cb0edda6f7698a4369) - - - - - 8958612c by Teo Camarasu at 2024-12-06T17:20:07+01:00 rts: Allocate non-moving segments with megablocks Non-moving segments are 8 blocks long and need to be aligned. Previously we serviced allocations by grabbing 15 blocks, finding an aligned 8 block group in it and returning the rest. This proved to lead to high levels of fragmentation as a de-allocating a segment caused an 8 block gap to form, and this could not be reused for allocation. This patch introduces a segment allocator based around using entire megablocks to service segment allocations in bulk. When there are no free segments, we grab an entire megablock and fill it with aligned segments. As the megablock is free, we can easily guarantee alignment. Any unused segments are placed on a free list. It only makes sense to free segments in bulk when all of the segments in a megablock are freeable. After sweeping, we grab the free list, sort it, and find all groups of segments where they cover the megablock and free them. This introduces a period of time when free segments are not available to the mutator, but the risk that this would lead to excessive allocation is low. Right after sweep, we should have an abundance of partially full segments, and this pruning step is relatively quick. In implementing this we drop the logic that kept NONMOVING_MAX_FREE segments on the free list. We also introduce an eventlog event to log the amount of pruned/retained free segments. See Note [Segment allocation strategy] Resolves #24150 ------------------------- Metric Decrease: T13253 T19695 ------------------------- (cherry picked from commit 5e36e7ced6a8aa183762e1df97da20b460e19bcf) - - - - - 8cb44392 by Matthew Craven at 2024-12-09T13:36:25+01:00 Remove unused ghc-internal module "GHC.Internal.Constants" (cherry picked from commit c6c190718972330504c048b013e5c2596b3c0c1e) - - - - - c16c0dea by Matthew Craven at 2024-12-09T14:25:07+01:00 CorePrep: Rework lowering of BigNat# literals Don't use bigNatFromWord#, because that's terrible: * We shouldn't have to traverse a linked list at run-time to build a BigNat# literal. That's just silly! * The static List object we have to create is much larger than the actual BigNat#'s contents, bloating code size. * We have to read the corresponding interface file, which causes un-tracked implicit dependencies. (#23942) Instead, encode them into the appropriate platform-dependent sequence of bytes, and generate code that copies these bytes at run-time from an Addr# literal into a new ByteArray#. A ByteArray# literal would be the correct thing to generate, but these are not yet supported; see also #17747. Somewhat surprisingly, this change results in a slight reduction in compiler allocations, averaging around 0.5% on ghc's compiler performance tests, including when compiling programs that contain no bignum literals to begin with. The specific cause of this has not been investigated. Since this lowering no longer reads the interface file for GHC.Num.BigNat, the reasoning in Note [Depend on GHC.Num.Integer] is obsoleted. But the story of un-tracked built-in dependencies remains complex, and Note [Tracking dependencies on primitives] now exists to explain this complexity. Additionally, many empty imports have been modified to refer to this new note and comply with its guidance. Several empty imports necessary for other reasons have also been given brief explanations. Metric Decrease: MultiLayerModulesTH_OneShot (cherry picked from commit 6d8f274b8677fcf9519d569875145f9f5434d779) - - - - - 0b3c9d24 by Andreas Klebinger at 2024-12-09T14:27:39+01:00 Add changelog entry for BigNat# lowering changes. - - - - - 53d78e35 by Fendor at 2024-12-09T17:11:34+01:00 Replace `SizedSeq` with `FlatBag` for flattened structure LinkedLists are notoriously memory ineffiecient when all we do is traversing a structure. As 'UnlinkedBCO' has been identified as a data structure that impacts the overall memory usage of GHCi sessions, we avoid linked lists and prefer flattened structure for storing. We introduce a new memory efficient representation of sequential elements that has special support for the cases: * Empty * Singleton * Tuple Elements This improves sharing in the 'Empty' case and avoids the overhead of 'Array' until its constant overhead is justified. (cherry picked from commit 5f085d3af61e3f7a73652dfc1ae57e7ed7d691f2) - - - - - d4cf1dc7 by Fendor at 2024-12-09T17:11:34+01:00 Compact FlatBag array representation `Array` contains three additional `Word`'s we do not need in `FlatBag`. Move `FlatBag` to `SmallArray`. Expand the API of SmallArray by `sizeofSmallArray` and add common traversal functions, such as `mapSmallArray` and `foldMapSmallArray`. Additionally, allow users to force the elements of a `SmallArray` via `rnfSmallArray`. (cherry picked from commit 82cfe10c8c3ec68e1b054e2d6b88e1a8830c60bf) - - - - - a90fac71 by Fendor at 2024-12-09T17:11:34+01:00 Avoid UArray when indexing is not required `UnlinkedBCO`'s can occur many times in the heap. Each `UnlinkedBCO` references two `UArray`'s but never indexes them. They are only needed to encode the elements into a `ByteArray#`. The three words for the lower bound, upper bound and number of elements are essentially unused, thus we replace `UArray` with a wrapper around `ByteArray#`. This saves us up to three words for each `UnlinkedBCO`. Further, to avoid re-allocating these words for `ResolvedBCO`, we repeat the procedure for `ResolvedBCO` and add custom `Binary` and `Show` instances. For example, agda's repl session has around 360_000 UnlinkedBCO's, so avoiding these three words is already saving us around 8MB residency. (cherry picked from commit 88cb3e1079e88ba10065ce260a96095ae96d58e8) - - - - - 68a1c9dd by Andreas Klebinger at 2024-12-09T17:11:34+01:00 Changelog for !12170 and !12142 - - - - - 73f25e46 by Rodrigo Mesquita at 2024-12-09T17:11:34+01:00 rts: free error message before returning Fixes a memory leak in rts/linker/PEi386.c (cherry picked from commit dd530bb7e22e953e4cec64a5fd6c39fddc152c6f) - - - - - c9979fed by Alexis King at 2024-12-09T17:11:34+01:00 linker: Avoid linear search when looking up Haskell symbols via dlsym See the primary Note [Looking up symbols in the relevant objects] for a more in-depth explanation. When dynamically loading a Haskell symbol (typical when running a splice or GHCi expression), before this commit we would search for the symbol in all dynamic libraries that were loaded. However, this could be very inefficient when too many packages are loaded (which can happen if there are many package dependencies) because the time to lookup the would be linear in the number of packages loaded. This commit drastically improves symbol loading performance by introducing a mapping from units to the handles of corresponding loaded dlls. These handles are returned by dlopen when we load a dll, and can then be used to look up in a specific dynamic library. Looking up a given Name is now much more precise because we can get lookup its unit in the mapping and lookup the symbol solely in the handles of the dynamic libraries loaded for that unit. In one measurement, the wait time before the expression was executed went from +-38 seconds down to +-2s. This commit also includes Note [Symbols may not be found in pkgs_loaded], explaining the fallback to the old behaviour in case no dll can be found in the unit mapping for a given Name. Fixes #23415 Co-authored-by: Rodrigo Mesquita (@alt-romes) (cherry picked from commit e008a19a7f9e8f22aada0b4e1049744f49d39aad) - - - - - b663c9e0 by Rodrigo Mesquita at 2024-12-09T17:11:34+01:00 rts: Make addDLL a wrapper around loadNativeObj Rewrite the implementation of `addDLL` as a wrapper around the more principled `loadNativeObj` rts linker function. The latter should be preferred while the former is preserved for backwards compatibility. `loadNativeObj` was previously only available on ELF platforms, so this commit further refactors the rts linker to transform loadNativeObj_ELF into loadNativeObj_POSIX, which is available in ELF and MachO platforms. The refactor made it possible to remove the `dl_mutex` mutex in favour of always using `linker_mutex` (rather than a combination of both). Lastly, we implement `loadNativeObj` for Windows too. (cherry picked from commit dcfaa190e1e1182a2efe4e2f601affbb832a49bb) - - - - - 67890fdb by Rodrigo Mesquita at 2024-12-09T17:11:34+01:00 Use symbol cache in internal interpreter too This commit makes the symbol cache that was used by the external interpreter available for the internal interpreter too. This follows from the analysis in #23415 that suggests the internal interpreter could benefit from this cache too, and that there is no good reason not to have the cache for it too. It also makes it a bit more uniform to have the symbol cache range over both the internal and external interpreter. This commit also refactors the cache into a function which is used by both `lookupSymbol` and also by `lookupSymbolInDLL`, extending the caching logic to `lookupSymbolInDLL` too. (cherry picked from commit 12931698261a1cee6a00b731d143270cd60e5f2d) - - - - - 353b6ec1 by Ben Gamari at 2024-12-09T17:11:34+01:00 testsuite: Add test for lookupSymbolInNativeObj (cherry picked from commit dccd3ea159b03cc1972cf47ee3cf8bda73ec0c5a) - - - - - 920ccafc by Andreas Klebinger at 2024-12-09T17:11:34+01:00 Changelog for !12264 (Lookup symbols in relevant DLLs only) - - - - - 99399b92 by Andreas Klebinger at 2024-12-09T17:12:58+01:00 NCG: Fix a bug where we errounously removed a required jump instruction. Add a new method to the Instruction class to check if we can eliminate a jump in favour of fallthrough control flow. Fixes #24507 (cherry picked from commit 0fe2b410ac0d8951f07ffcc9f3c6c97bc312df48) - - - - - 6ea0d4f7 by Andreas Klebinger at 2024-12-09T17:13:42+01:00 Add changelog for !12370 - Bug in jump shortcutting. - - - - - 8692ced5 by Simon Peyton Jones at 2024-12-09T17:18:17+01:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> (cherry picked from commit 5e4f4ba835fd24135759ee7a2d0d5c636a8a1505) - - - - - c52e8047 by Andreas Klebinger at 2024-12-09T17:19:50+01:00 Changelog for !12416 Entry for "Don't generate wrappers for `type data` constructors with StrictData." - - - - - 8e13b22e by Matthew Pickering at 2024-12-09T17:21:24+01:00 Linearise ghc-internal and base build This is achieved by requesting the final package database for ghc-internal, which mandates it is fully built as a dependency of configuring the `base` package. This is at the expense of cross-package parrallelism between ghc-internal and the base package. Fixes #24436 (cherry picked from commit 8a06ddf68bb5a9985e3a7b8464dd04b928c36b90) - - - - - 220f15b2 by Andreas Klebinger at 2024-12-12T15:19:22+01:00 Accept backport metric changes. The MLM test regresses slightly (+2.5% compiler bytes allocated). That seems within reason. ------------------------- Metric Increase: MultiLayerModulesTH_OneShot ------------------------- - - - - - 9cd1ae5b by Fendor at 2024-12-13T13:18:27+01:00 Escape multiple arguments in the settings file Uses responseFile syntax. The issue arises when GHC is installed on windows into a location that has a space, for example the user name is 'Fake User'. The $topdir will also contain a space, consequentially. When we resolve the top dir in the string `-I$topdir/mingw/include`, then `words` will turn this single argument into `-I/C/Users/Fake` and `User/.../mingw/include` which trips up the flag argument parser of various tools such as gcc or clang. We avoid this by escaping the $topdir before replacing it in `initSettngs`. Additionally, we allow to escape spaces and quotation marks for arguments in `settings` file. Add regression test case to count the number of options after variable expansion and argument escaping took place. Additionally, we check that escaped spaces and double quotation marks are correctly parsed. (cherry picked from commit 31bf85ee49fe2ca0b17eaee0774e395f017a9373) - - - - - 8d3b0c32 by Andreas Klebinger at 2024-12-13T13:29:03+01:00 Changelog for !11938 - Escape multiple arguments in the settings file. - - - - - 156b8aa3 by Andreas Klebinger at 2024-12-13T19:46:22+01:00 RTS: Emit warning when -M < -H Fixes #24487 (cherry picked from commit 9e91744a19dcd699896341baadf98f99b1250839) - - - - - 4d5d4404 by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: fix typos and namings (fixes #24602) You may noted that I've also changed term of ``` , global "h$vt_double" ||= toJExpr IntV ``` See "IntV" and ``` WaitReadOp -> \[] [fd] -> pure $ PRPrimCall $ returnS (app "h$waidRead" [fd]) ``` See "h$waidRead" (cherry picked from commit c70b9ddb6dc232e22a49ddc757865bd3bc9c46a7) - - - - - fc56b471 by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: trivial checks for variable presence (fixes #24602) (cherry picked from commit 3db54f9bcdcd20a2497447bf76176470db900143) - - - - - 1ed663cc by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: fs module imported twice (by emscripten and by ghc-internal). ghc-internal import wrapped in a closure to prevent conflict with emscripten (fixes #24602) Better solution is to use some JavaScript module system like AMD, CommonJS or even UMD. It will be investigated at other issues. At first glance we should try UMD (See https://github.com/umdjs/umd) (cherry picked from commit 777f108f74f0a81274775d504dffe46c5fdfc33f) - - - - - d3477264 by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: thread.js requires h$fds and h$fdReady to be declared for static code analysis, minimal code copied from GHCJS (fixes #24602) I've just copied some old pieces of GHCJS from publicly available sources (See https://github.com/Taneb/shims/blob/a6dd0202dcdb86ad63201495b8b5d9763483eb35/src/io.js#L607). Also I didn't put details to h$fds. I took minimal and left only its object initialization: `var h$fds = {};` (cherry picked from commit a45a57127bb7eaceae92e0edf057c053eb4d5367) - - - - - 549ce324 by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: heap and stack overflows reporting defined as js hard failure (fixes #24602) These errors were treated as a hard failure for browser application. The fix is trivial: just throw error. (cherry picked from commit ad90bf1237e0c9d2013399bd8cd1315f2845d9e7) - - - - - 8335f195 by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: Stubs for code without actual implementation detected by Google Closure Compiler (fixes #24602) These errors were fixed just by introducing stubbed functions with throw for further implementation. (cherry picked from commit 5962fa526e071d77fd4970b57d957a622e13207c) - - - - - db00df21 by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: Add externs to linker (fixes #24602) After enabling jsdoc and built-in google closure compiler types I was needed to deal with the following: 1. Define NodeJS-environment types. I've just copied minimal set of externs from semi-official repo (see https://github.com/externs/nodejs/blob/6c6882c73efcdceecf42e7ba11f1e3e5c9c041f0/v8/nodejs.js#L8). 2. Define Emscripten-environment types: `HEAP8`. Emscripten already provides some externs in our code but it supposed to be run in some module system. And its definitions do not work well in plain bundle. 3. We have some functions which purpose is to add to functions some contextual information via function properties. These functions should be marked as `modifies` to let google closure compiler remove calls if these functions are not used actually by call graph. Such functions are: `h$o`, `h$sti`, `h$init_closure`, `h$setObjInfo`. 4. STG primitives such as registries and stuff from `GHC.StgToJS`. `dXX` properties were already present at externs generator function but they are started from `7`, not from `1`. This message is related: `// fixme does closure compiler bite us here?` (cherry picked from commit a0694298aad5f2f428311d6e787484a250c9de43) - - - - - 3a270b4d by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: added both tests: for size and for correctness (fixes #24602) By some reason MacOS builds add to stderr messages like: Ignoring unexpected archive entry: __.SYMDEF ... However I left stderr to `/dev/null` for compatibility with linux CI builds. (cherry picked from commit e58bb29f8a4808fd4b74b653b1893f78121c7df4) - - - - - 5348bbe9 by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: Disable js linker warning for empty symbol table to make js tests running consistent across environments (cherry picked from commit 909f3a9c8dac5d15c2492c008e370be60f50b50c) - - - - - 68da8237 by Serge S. Gulin at 2024-12-18T16:28:16+01:00 JS: Add special preprocessor for js files due of needing to keep jsdoc comments (fixes #24602) Our js files have defined google closure compiler types at jsdoc entries but these jsdoc entries are removed by cpp preprocessor. I considered that reusing them in javascript-backend would be a nice thing. Right now haskell processor uses `-traditional` option to deal with comments and `//` operators. But now there are following compiler options: `-C` and `-CC`. You can read about them at GCC (see https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-CC) and CLang (see https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-CC). It seems that `-CC` works better for javascript jsdoc than `-traditional`. At least it leaves `/* ... */` comments w/o changes. (cherry picked from commit 83eb10da239e6bef0d06dbba174809f99c463d8d) - - - - - e234268d by Cheng Shao at 2024-12-18T16:28:16+01:00 Update autoconf scripts Scripts taken from autoconf 948ae97ca5703224bd3eada06b7a69f40dd15a02 (cherry picked from commit 36f2c3422d7f3620078dba701f57275a3708aff5) - - - - - f1de8643 by Sylvain Henry at 2024-12-18T16:28:16+01:00 GHCi: support inlining breakpoints (#24712) When a breakpoint is inlined, its context may change (e.g. tyvars in scope). We must take this into account and not used the breakpoint tick index as its sole identifier. Each instance of a breakpoint (even with the same tick index) now gets a different "info" index. We also need to distinguish modules: - tick module: module with the break array (tick counters, status, etc.) - info module: module having the CgBreakInfo (info at occurrence site) (cherry picked from commit b85b11994e0130ff2401dd4bbdf52330e0bcf776) - - - - - cd9f53ba by Cheng Shao at 2024-12-18T16:28:16+01:00 wasm: use scheduler.postTask() for context switch when available This patch makes use of scheduler.postTask() for JSFFI context switch when it's available. It's a more principled approach than our MessageChannel based setImmediate() implementation, and it's available in latest version of Chromium based browsers. (cherry picked from commit 43d48b449a46e805e3baeafbafa62b6cd6f761c9) - - - - - c01dc7f1 by Matthew Craven at 2024-12-18T16:28:16+01:00 Add test cases for #24664 ...since none are present in the original MR !12463 fixing this issue. (cherry picked from commit a19201d42cfd3aa54faeb1b5a95b715b9a67a01a) - - - - - 5a8790db by Arsen Arsenović at 2024-12-18T16:28:16+01:00 Split out the C-- preprocessor, and make it pass -g0 Previously, C-- was processed with the C preprocessor program. This means that it inherited flags passed via -optc. A flag that is somewhat often passed through -optc is -g. At certain -g levels (>=2), GCC starts emitting defines *after* preprocessing, for the purposes of debug info generation. This is not useful for the C-- compiler, and, in fact, causes lexer errors. We can suppress this effect (safely, if supported) via -g0. As a workaround, in older versions of GCC (<=10), GCC only emitted defines if a certain set of -g*3 flags was passed. Newer versions check the debug level. For the former, we filter out those -g*3 flags and, for the latter, we specify -g0 on top of that. As a compatible and effective solution, this change adds a C-- preprocessor distinct from the C compiler and preprocessor, but that keeps its flags. The command line produced for C-- preprocessing now looks like: $pgmCmmP $optCs_without_g3 $g0_if_supported $optCmmP Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/24474 (cherry picked from commit 25b0b40467d0a12601497117c0ad14e1fcab0b74) - - - - - f2cc943d by Andreas Klebinger at 2024-12-18T16:28:16+01:00 Add release notes for some backported 9.10.2 patches. Contains notes for: !11938: Escape multiple arguments in the settings file !12201: RTS: Emit warning when -M < -H !12495: Update autoconf scripts !12500: GHCi: support cross-module inlining of breakpoints !12550: wasm: use scheduler.postTask() for context switch when available !12569: Split out the C-- preprocessor, and make it pass -g0 - - - - - 1016a4b1 by Andreas Klebinger at 2024-12-18T16:28:17+01:00 -fprof-late: Only insert cost centres on functions/non-workfree cafs. They are usually useless and doing so for data values comes with a large compile time/code size overhead. Fixes #24103 (cherry picked from commit 9b4129a580e6c1d18197ef2ed3a8b89d52a2b133) - - - - - 0c850206 by Ben Gamari at 2024-12-18T16:28:17+01:00 IPE: Eliminate dependency on Read Instead of encoding the closure type as decimal string we now simply represent it as an integer, eliminating the need for `Read` in `GHC.Internal.InfoProv.Types.peekInfoProv`. Closes #24504. ------------------------- Metric Decrease: T24602_perf_size size_hello_artifact ------------------------- (cherry picked from commit ab840ce6f83a74f36dac939d087b69f97404399a) - - - - - c15c6a8d by Cheng Shao at 2024-12-18T16:28:17+01:00 testsuite: fix testwsdeque with recent clang This patch fixes compilation of testwsdeque.c with recent versions of clang, which will fail with the error below: ``` testwsdeque.c:95:33: error: warning: format specifies type 'long' but the argument has type 'void *' [-Wformat] 95 | barf("FAIL: %ld %d %d", p, n, val); | ~~~ ^ testwsdeque.c:95:39: error: warning: format specifies type 'int' but the argument has type 'StgWord' (aka 'unsigned long') [-Wformat] 95 | barf("FAIL: %ld %d %d", p, n, val); | ~~ ^~~ | %lu testwsdeque.c:133:42: error: error: incompatible function pointer types passing 'void (void *)' to parameter of type 'OSThreadProc *' (aka 'void *(*)(void *)') [-Wincompatible-function-pointer-types] 133 | createOSThread(&ids[n], "thief", thief, (void*)(StgWord)n); | ^~~~~ /workspace/ghc/_build/stage1/lib/../lib/x86_64-linux-ghc-9.11.20240502/rts-1.0.2/include/rts/OSThreads.h:193:51: error: note: passing argument to parameter 'startProc' here 193 | OSThreadProc *startProc, void *param); | ^ 2 warnings and 1 error generated. ``` (cherry picked from commit a9979f55d0f688fabd25ee318e44b9addd904988) - - - - - 3329ca03 by Cheng Shao at 2024-12-18T16:28:17+01:00 ghc-heap: fix typo in ghc-heap cbits (cherry picked from commit 2b1af08b94024c104b54eadd710855e9f8a90fb6) - - - - - a15b3383 by doyougnu at 2024-12-18T16:28:17+01:00 testsuite: expand size testing infrastructure - closes #24191 - adds windows_skip, wasm_skip, wasm_arch, find_so, _find_so - path_from_ghcPkg, collect_size_ghc_pkg, collect_object_size, find_non_inplace functions to testsuite - adds on_windows and req_dynamic_ghc predicate to testsuite The design is to not make the testsuite too smart and simply offload to ghc-pkg for locations of object files and directories. (cherry picked from commit 9bae34d87f6c978e03031c549920071857c9080c) - - - - - 4b5b67a4 by Matthew Pickering at 2024-12-18T16:28:17+01:00 tests: Widen acceptance window for dir and so size tests These are testing things which are sometimes out the control of a GHC developer. Therefore we shouldn't fail CI if something about these dependencies change because we can't do anything about it. It is still useful to have these statistics for visualisation in grafana though. Ticket #24759 (cherry picked from commit c49493f242fc78fbf23ef3642df531a19c3b4b24) - - - - - 216ad9f9 by Matthew Pickering at 2024-12-18T16:28:17+01:00 Disable rts_so test It has already manifested large fluctuations and destabilising CI Fixes #24762 (cherry picked from commit 9562808d02db67838844d874c632f18af904949c) - - - - - 20552645 by Torsten Schmits at 2024-12-18T16:28:17+01:00 refactor quadratic search in warnMissingHomeModules (cherry picked from commit bc672166acd8f2815d58b6d214e69373abec4486) - - - - - 158c9dbf by Torsten Schmits at 2024-12-18T16:28:17+01:00 add test that runs MakeDepend on thousands of modules (cherry picked from commit 7875e8cbe5d9b69a1a77354317b2bf9478172686) - - - - - ee3e6c79 by Matthew Pickering at 2024-12-18T16:28:17+01:00 driver: Fix -Wmissing-home-modules when multiple units have the same module name It was assumed that module names were unique but that isn't true with multiple units. The fix is quite simple, maintain a set of `(ModuleName, UnitId)` and query that to see whether the module has been specified. Fixes #25122 (cherry picked from commit 951ce3d5904a1d34d49787d444f99e251e24d4e7) - - - - - 1faf2c60 by Sylvain Henry at 2024-12-18T16:28:17+01:00 Reverse arguments to stgCallocBytes (fix #24828) (cherry picked from commit 6838a7c32ca29b5d44adc9d6280d3a960f31be7c) - - - - - 6d00956c by Ben Gamari at 2024-12-18T16:28:17+01:00 rts: Fix size of StgOrigThunkInfo frames Previously the entry code of the `stg_orig_thunk` frame failed to account for the size of the profiling header as it hard-coded the frame size. Fix this. Fixes #24809. (cherry picked from commit 6d7e6ad803be11cb7a79dca727c37e4ef21cda4b) - - - - - 0be2daaf by Fendor at 2024-12-18T16:28:17+01:00 Add regression test T24809 for stg_orig_thunk_info_frame size (cherry picked from commit c645fe406cd4a3f4c152e51dfbcdeeb5e2930fb1) - - - - - 80afd1a9 by Andreas Klebinger at 2024-12-18T16:28:17+01:00 bindists: Check for existence of share folder before trying to copy it. This folder isn't distributed in windows bindists A lack of doing so resulted us copying loads of files twice. (cherry picked from commit 4181aa40fff5653a121cd2ece33ab0f7454d421d) - - - - - af123155 by Matthew Pickering at 2024-12-18T16:28:17+01:00 Remove ad-hoc installation of mingw toolchain in relocatable bindists This reverts 616ac30026e8dd7d2ebb98d92dde071eedf5d951 The choice about whether to install mingw is taken in the installation makefile. This is also broken on non-windows systems. The actual issue was the EnableDistroToolchain variable wasn't declared in mk/config.mk and therefore the check to install mingw was failing. (cherry picked from commit d216510e43deca5a9a221d2b799face293e38299) - - - - - 50974a94 by Cheng Shao at 2024-12-18T16:28:17+01:00 testsuite: fix T17920 for wasm backend T17920 was marked as fragile on wasm before; it can be trivially fixed by avoiding calling variadic printf() in cmm. (cherry picked from commit 7b4c19983bf6bc11b519b437a6204c38672721ea) - - - - - c8f98d01 by Simon Peyton Jones at 2024-12-18T16:28:17+01:00 Better skolemisation As #24810 showed, it is (a little) better to skolemise en-bloc, so that Note [Let-bound skolems] fires more often. See Note [Skolemisation en bloc] in GHC.Tc.Utils.Instantiate. (cherry picked from commit 3d9e4ce68a55f6bc5246d2d77729676010e85bbd) - - - - - e57d1433 by Ryan Scott at 2024-12-18T16:28:17+01:00 Add missing parenthesizePat in cvtp We need to ensure that the output of `cvtp` is parenthesized (at precedence `sigPrec`) so that any pattern signatures with a surrounding pattern signature can parse correctly. Fixes #24837. (cherry picked from commit a3cd3a1d0d186f2aa4d0273c6b3e74a442de2ef0) - - - - - 05338430 by crumbtoo at 2024-12-18T16:28:17+01:00 user_guide: Fix typo in MultiWayIf chapter Close #24829 (cherry picked from commit c5e00c35927d574f71bf77449817b131d1749750) - - - - - 53eeffd6 by Cheng Shao at 2024-12-18T16:28:17+01:00 rts: fix missing function prototypes in ClosureMacros.h (cherry picked from commit 3ca72ad974169aa39f391774875a9cc2a77ee967) - - - - - bbe4accd by Cheng Shao at 2024-12-18T16:28:17+01:00 rts: use __builtin_offsetof to implement STG_FIELD_OFFSET This patch fixes the STG_FIELD_OFFSET macro definition by using __builtin_offsetof, which is what gcc/clang uses to implement offsetof in standard C. The previous definition that uses NULL pointer involves subtle undefined behavior in C and thus reported by UndefinedBehaviorSanitizer as well: ``` rts/Capability.h:243:58: runtime error: member access within null pointer of type 'Capability' (aka 'struct Capability_') SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Capability.h:243:58 ``` (cherry picked from commit 05c4fafbc1693164d5f06ed062fc73bbf3f78deb) - - - - - 4879286a by Cheng Shao at 2024-12-18T16:28:17+01:00 rts: fix an unaligned load in nonmoving gc This patch fixes an unaligned load in nonmoving gc by ensuring the closure address is properly untagged first before attempting to prefetch its header. The unaligned load is reported by UndefinedBehaviorSanitizer: ``` rts/sm/NonMovingMark.c:921:9: runtime error: member access within misaligned address 0x0042005f3a71 for type 'StgClosure' (aka 'struct StgClosure_'), which requires 8 byte alignment 0x0042005f3a71: note: pointer points here 00 00 00 98 43 13 8e 12 7f 00 00 50 3c 5f 00 42 00 00 00 58 17 b7 92 12 7f 00 00 89 cb 5e 00 42 ^ SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/sm/NonMovingMark.c:921:9 ``` This issue had previously gone unnoticed since it didn't really harm runtime correctness, the invalid header address directly loaded from a tagged pointer is only used as prefetch address and will not cause segfaults. However, it still should be corrected because the prefetch would be rendered useless by this issue, and untagging only involves a single bitwise operation without memory access so it's cheap enough to add. (cherry picked from commit c77a48af6e1f38337b305fec794e8c999f1c7f3a) - - - - - 59b84e0f by Cheng Shao at 2024-12-18T16:28:17+01:00 rts: ensure gc_thread/gen_workspace is allocated with proper alignment gc_thread/gen_workspace are required to be aligned by 64 bytes. However, this property has not been properly enforced before, and numerous alignment violations at runtime has been caught by UndefinedBehaviorSanitizer that look like: ``` rts/sm/GC.c:1167:8: runtime error: member access within misaligned address 0x0000027a3390 for type 'gc_thread' (aka 'struct gc_thread_'), which requires 64 byte alignment 0x0000027a3390: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/sm/GC.c:1167:8 rts/sm/GC.c:1184:13: runtime error: member access within misaligned address 0x0000027a3450 for type 'gen_workspace' (aka 'struct gen_workspace_'), which requires 64 byte alignment 0x0000027a3450: note: pointer points here 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/sm/GC.c:1184:13 ``` This patch fixes the gc_thread/gen_workspace misalignment issue by explicitly allocating them with alignment constraint. (cherry picked from commit 7a660042395614e4b19534baf5b779f65059861e) - - - - - c4507307 by Cheng Shao at 2024-12-18T16:28:17+01:00 hadrian: disable PIC for in-tree GMP on wasm32 This patch disables PIC for in-tree GMP on wasm32 target. Enabling PIC unconditionally adds undesired code size and runtime overhead for wasm32. (cherry picked from commit f9c1ae122ec642c0d9236dffc971bc2d1ca38fba) - - - - - 794e71e1 by Cheng Shao at 2024-12-18T16:28:17+01:00 hadrian: disable in-tree gmp fft code path for wasm32 This patch disables in-tree GMP FFT code paths for wasm32 target in order to give up some performance of multiplying very large operands in exchange for reduced code size. (cherry picked from commit 1a32f82807ae01813f14bdf12fed75eb32799e18) - - - - - d08b9b83 by Cheng Shao at 2024-12-18T16:28:18+01:00 hadrian: build in-tree GMP with malloc-notreentrant on wasm32 This patch makes hadrian build in-tree GMP with the --enable-alloca=malloc-notreentrant configure option. We will only need malloc-reentrant when we have threaded RTS and SMP support on wasm32, which will take some time to happen, before which we should use malloc-notreentrant to avoid undesired runtime overhead. (cherry picked from commit 06277d56de91c8d21cbf71e8bc4096925b863acc) - - - - - ece0a0db by Andreas Klebinger at 2024-12-18T16:28:18+01:00 Add release notes for some backported patches. Add entries for the following backported MRs: !12498: -fprof-late: Don't add cost centres to static data. !12565: IPE: Eliminate dependency on Read !12591: ghc-heap: fix typo in ghc-heap cbits !12607: refactor quadratic search in warnMissingHomeModules !12621: rts: Fix size of StgOrigThunkInfo frames !12649 # bindists: Check for existence of shared folder before trying to copy it. !12653: Better skolemisation !12734: Various rts fixes for issues spotted by UndefinedBehaviorSanitizer !12592: hadrian: adjust in-tree GMP configure options for wasm32 - - - - - 1b847dec by Cheng Shao at 2024-12-18T16:28:18+01:00 hadrian: fix hadrian building with ghc-9.10.1 (cherry picked from commit be514bb48629747258416e602c8b00810b3863b0) - - - - - 7dd1423d by Cheng Shao at 2024-12-18T16:28:18+01:00 linters: fix lint-whitespace compilation with ghc-9.10.1 (cherry picked from commit ad38e954bf088b43fa1cecfeaf474b6b9c11e2ed) - - - - - 86723eed by Zubin Duggal at 2024-12-18T16:28:18+01:00 testsuite: Handle exceptions in framework_fail when testdir is not initialised When `framework_fail` is called before initialising testdir, it would fail with an exception reporting the testdir not being initialised instead of the actual failure. Ensure we report the actual reason for the failure instead of failing in this way. One way this can manifest is when trying to run a test that doesn't exist using `--only` (cherry picked from commit c56d728e1f8702db02cf7e7e3cdc567b3df47ac3) - - - - - 1d787538 by Arsen Arsenović at 2024-12-18T16:28:18+01:00 Add the cmm_cpp_is_gcc predicate to the testsuite A future C-- test called T24474-cmm-override-g0 relies on the GCC-specific behaviour of -g3 implying -dD, which, in turn, leads to it emitting #defines past the preprocessing stage. Clang, at least, does not do this, so the test would fail if ran on Clang. As the behaviour here being tested is ``-optCmmP-g3'' undoing effects of the workaround we apply as a fix for bug #24474, and the workaround was for GCC-specific behaviour, the test needs to be marked as fragile on other compilers. (cherry picked from commit 4d59abf295cd371448f22c1724b955dce4974302) - - - - - a73ffe72 by Ben Gamari at 2024-12-18T16:35:45+01:00 rts: Fix TSAN_ENABLED CPP guard This should be `#if defined(TSAN_ENABLED)`, not `#if TSAN_ENABLED`, lest we suffer warnings. (cherry picked from commit c8a4c050626f451461a3667589d40004b2547a1c) - - - - - a235a078 by Cheng Shao at 2024-12-18T16:35:56+01:00 rts: fix errors when compiling with TSAN This commit fixes rts compilation errors when compiling with TSAN: - xxx_FENCE macros are redefined and trigger CPP warnings. - Use SIZEOF_W. WORD_SIZE_IN_BITS is provided by MachDeps.h which Cmm.h doesn't include by default. (cherry picked from commit e91dad93ff50b429d5717c81fbd5fe20ff2defd9) - - - - - 6c30c754 by Cheng Shao at 2024-12-18T16:36:11+01:00 rts: fix clang-specific errors when compiling with TSAN This commit fixes clang-specific rts compilation errors when compiling with TSAN: - clang doesn't have -Wtsan flag - Fix prototype of ghc_tsan_* helper functions - __tsan_atomic_* functions aren't clang built-ins and sanitizer/tsan_interface_atomic.h needs to be included - On macOS, TSAN runtime library is libclang_rt.tsan_osx_dynamic.dylib, not libtsan. -fsanitize-thread as a link-time flag will take care of linking the TSAN runtime library anyway so remove tsan as an rts extra library (cherry picked from commit a9ab9455b0159c955ea8c38ac113e4cbe47d410f) - - - - - c05d1181 by Cheng Shao at 2024-12-18T16:36:58+01:00 compiler: fix github link to __tsan_memory_order in a comment (cherry picked from commit 865bd717cc4c63d6926138c5b8c71addcf70a1e7) - - - - - f39baa8c by Cheng Shao at 2024-12-18T16:38:32+01:00 ci: improve TSAN CI jobs - Run TSAN jobs with +thread_sanitizer_cmm which enables Cmm instrumentation as well. - Run TSAN jobs in deb12 which ships gcc-12, a reasonably recent gcc that @bgamari confirms he's using in #GHC:matrix.org. Ideally we should be using latest clang release for latest improvements in sanitizers, though that's left as future work. - Mark TSAN jobs as manual+allow_failure in validate pipelines. The purpose is to demonstrate that we have indeed at least fixed building of TSAN mode in CI without blocking the patch to land, and once merged other people can begin playing with TSAN using their own dev setups and feature branches. (cherry picked from commit 07cb627c8232f573bd6a8ea1b7c110ff3c1b5d22) - - - - - 51d3b2d0 by Andrei Borzenkov at 2024-12-19T15:44:28+01:00 Improve pattern to type pattern transformation (23739) `pat_to_type_pat` function now can handle more patterns: - TuplePat - ListPat - LitPat - NPat - ConPat Allowing these new constructors in type patterns significantly increases possible shapes of type patterns without `type` keyword. This patch also changes how lookups in `lookupOccRnConstr` are performed, because we need to fall back into types when we didn't find a constructor on data level to perform `ConPat` to type transformation properly. (cherry picked from commit 2c0f8ddbdf351ed84395afa04a2654a7cbe2ad35) - - - - - 164133ec by Andreas Klebinger at 2024-12-19T15:50:05+01:00 Removed a test whose change was not backported (T23764). - - - - - 4e89c144 by Sylvain Henry at 2024-12-19T15:51:07+01:00 Type-check default declarations before deriving clauses (#24566) See added Note and #24566. Default declarations must be type-checked before deriving clauses. (cherry picked from commit 52072f8e2121fe49a8367027efa3d8db32325f84) - - - - - 6601403b by Simon Peyton Jones at 2024-12-19T18:36:54+01:00 Print more info about kinds in error messages This fixes #24553, where GHC unhelpfully said error: [GHC-83865] • Expected kind ‘* -> * -> *’, but ‘Foo’ has kind ‘* -> * -> *’ See Note [Showing invisible bits of types in error messages] (cherry picked from commit b72705e9b2ae5575aef92ede6ff975bbbe43004d) - - - - - 1a7a0500 by Matthew Pickering at 2024-12-19T20:05:43+01:00 testsuite: workaround bug in python-3.12 There is some unexplained change to binding behaviour in python-3.12 which requires moving this import from the top-level into the scope of the function. I didn't feel any particular desire to do a deep investigation as to why this changed as the code works when modified like this. No one in the python IRC channel seemed to know what the problem was. (cherry picked from commit 43aa99b8169fc6d8552844cd6fa0ce3cd4308185) - - - - - 6c1bf036 by Max Ulidtko at 2024-12-20T13:28:23+01:00 GHCi: Support local Prelude Fixes #10920, an issue where GHCi bails out when started alongside a file named Prelude.hs or Prelude.lhs (even empty file suffices). The in-source Note [GHCi and local Preludes] documents core reasoning. Supplementary changes: * add debug traces for module lookups under -ddump-if-trace; * drop stale comment in GHC.Iface.Load; * reduce noise in -v3 traces from GHC.Utils.TmpFs; * new test, which also exercizes HomeModError. (cherry picked from commit 977b6b64e184795f3f12ac5b2637707f0696457c) - - - - - 03727a8e by Cheng Shao at 2024-12-20T13:30:00+01:00 compiler: emit NaturallyAligned when element type & index type are the same width This commit fixes a subtle mistake in alignmentFromTypes that used to generate Unaligned when element type & index type are the same width. Fixes #24930. (cherry picked from commit 0cff083abb24701530974872b21cf897c9955a9a) - - - - - 487c8c8d by qqwy at 2024-12-20T13:32:00+01:00 Replace '?callStack' implicit param with HasCallStack in GHC.Internal.Exception.throw (cherry picked from commit edfe6140be64f0d9365f7e954d3db534d63bb04f) - - - - - 33ee13b5 by Cheng Shao at 2024-12-20T13:32:54+01:00 rts: use page sized mblocks on wasm This patch changes mblock size to page size on wasm. It allows us to simplify our wasi-libc fork, makes it much easier to test third party libc allocators like emmalloc/mimalloc, as well as experimenting with threaded RTS in wasm. (cherry picked from commit 558353f4e22643b94b9710a45c3364c518d57b46) - - - - - 71115f23 by Simon Peyton Jones at 2024-12-20T13:40:27+01:00 Localise a case-binder in SpecConstr.mkSeqs This small change fixes #24944 See (SCF1) in Note [SpecConstr and strict fields] (cherry picked from commit 246bc3a43a57b7c9ea907bd9ef15b7ef7c490681) - - - - - e417441e by Andreas Klebinger at 2024-12-20T13:43:40+01:00 Expand the `inline` rule to look through casts/ticks. Fixes #24808 (cherry picked from commit a593f28426ca508a72b49d0112ef934ce9f453fd) - - - - - 113e76d3 by Simon Peyton Jones at 2024-12-20T13:51:19+01:00 Fix a float-out error Ticket #24768 showed that the Simplifier was accidentally destroying a join point. It turned out to be that we were sending a bottoming join point to the top, accidentally abstracting over /other/ join points. Easily fixed. (cherry picked from commit 03c5dfbf52969504ca3473cb2eb7b3f7cf96d4b3) - - - - - d39bdab8 by Peter Trommler at 2024-12-20T13:58:28+01:00 PPC NCG: Fix sign hints in C calls Sign hints for parameters are in the second component of the pair. Fixes #23034 (cherry picked from commit 7fe85b1354a13749f14d588e3cc742b8ae2d8da9) - - - - - a92613c2 by Andreas Klebinger at 2024-12-20T16:00:28+01:00 More 9.10.2 Changelog notes. - - - - - ba97aa2d by Alex Mason at 2025-01-13T15:01:42+01:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 (cherry picked from commit dbdf1995956a7457c34b6895c67ef48f6c8384f2) - - - - - 52812e1c by Matthew Pickering at 2025-01-13T15:04:41+01:00 Bump os-string submodule to 2.0.2.2 Closes #24786 (cherry picked from commit 0528509028ef6c4d80d47aad9fd80de6c662c8a2) - - - - - a085f505 by Alex Mason at 2025-01-13T15:05:55+01:00 Add AArch64 CLZ, CTZ, RBIT primop implementations. Adds support for emitting the clz and rbit instructions, which are used by GHC.Prim.clz*#, GHC.Prim.ctz*# and GHC.Prim.bitReverse*#. (cherry picked from commit 71010381f4270966de334193ab2bfc67f8524212) - - - - - 6faa8336 by Andreas Klebinger at 2025-01-13T15:06:40+01:00 GHCi interpreter: Tag constructor closures when possible. When evaluating PUSH_G try to tag the reference we are pushing if it's a constructor. This is potentially helpful for performance and required to fix #24870. (cherry picked from commit 1bfa91115b8320ed99a5e946147528e21ca4f3e1) - - - - - 3928048e by Peter Trommler at 2025-01-13T17:24:23+01:00 X86 NCG: Fix argument promotion in foreign C calls Promote 8 bit and 16 bit signed arguments by sign extension. Fixes #25018 (cherry picked from commit a82121b3b6fdc2ac47211f71871b3ab21e5f6276) - - - - - 5bc9d132 by Matthew Pickering at 2025-01-13T17:31:09+01:00 configure: Set LD_STAGE0 appropiately when 9.10.1 is used as a boot compiler In 9.10.1 the "ld command" has been removed, so we fall back to using the more precise "merge objects command" when it's available as LD_STAGE0 is only used to set the object merging command in hadrian. Fixes #24949 (cherry picked from commit 564981bda9a6a309ff0f524610af0f908432442f) - - - - - 8746a86c by Matthew Pickering at 2025-01-13T17:31:18+01:00 hadrian: Don't build ghci object files for ./hadrian/ghci target There is some convoluted logic which determines whether we build ghci object files are not. In any case, if you set `ghcDynPrograms = pure False` then it forces them to be built. Given we aren't ever building executables with this flavour it's fine to leave `ghcDynPrograms` as the default and it should be a bit faster to build less. Also fixes #24949 (cherry picked from commit a949c792388b5662dd199497541f9ad51c78d1a8) - - - - - 01d6b09b by Matthew Pickering at 2025-01-13T17:34:34+01:00 ci: Unset ALEX/HAPPY variables when testing bootstrap jobs Ticket #24826 reports a regression in 9.10.1 when building from a source distribution. This patch is an attempt to reproduce the issue on CI by more aggressively removing `alex` and `happy` from the environment. (cherry picked from commit 3f9548fe97c728ed60ba26811e4fe248fc28d2a7) - - - - - bc0fc221 by Andrea Bedini at 2025-01-13T17:34:44+01:00 hadrian: Ignore build-tool-depends fields in cabal files hadrian does not utilise the build-tool-depends fields in cabal files and their presence can cause issues when building source distribution (see #24826) Ideally Cabal would support building "full" source distributions which would remove the need for workarounds in hadrian but for now we can patch the build-tool-depends out of the cabal files. Fixes #24826 (cherry picked from commit aba2c9d4728262cd9a2d711eded9050ac131c6c1) - - - - - d6d2abe2 by Zubin Duggal at 2025-01-13T17:34:59+01:00 compiler: Fingerprint -fwrite-if-simplified-core We need to recompile if this flag is changed because later modules might depend on the simplified core for this module if -fprefer-bytecode is enabled. Fixes #24656 (cherry picked from commit dddc9dff0547733a10e7f505612ab9df3a7c21b6) - - - - - b3322a3a by Alex Mason at 2025-01-13T17:35:10+01:00 ncg(aarch64): Add fsqrt instruction, byteSwap primitives [#24956] Implements the FSQRT machop using native assembly rather than a C call. Implements MO_BSwap by producing assembly to do the byte swapping instead of producing a foreign call a C function. In `tar`, the hot loop for `deserialise` got almost 4x faster by avoiding the foreign call which caused spilling live variables to the stack -- this means the loop did 4x more memory read/writing than necessary in that particular case! (cherry picked from commit dee035bf618d75a18fe72dd3977434c0749a2156) - - - - - 0183e434 by Sylvain Henry at 2025-01-13T17:35:20+01:00 Linker: use m32 allocator for sections when NEED_PLT (#24432) Use M32 allocator to avoid fragmentation when allocating ELF sections. We already did this when NEED_PLT was undefined. Failing to do this led to relocations impossible to fulfil (#24432). (cherry picked from commit 5104ee615503617a1c124fe1d92f6aa2d263b7d0) - - - - - 9c5cf8f8 by Sylvain Henry at 2025-01-13T17:35:25+01:00 RTS: allow M32 allocation outside of 4GB range when assuming -fPIC (cherry picked from commit 52d6698479f951e07def237b0474ee22d27e621a) - - - - - 2822e96b by Sylvain Henry at 2025-01-13T17:35:31+01:00 Linker: fix stub offset Remove unjustified +8 offset that leads to memory corruption (cf discussion in #24432). (cherry picked from commit c34fef56367142fa55e9861092f64cc7b9946fa1) - - - - - ecd99e0b by Simon Peyton Jones at 2025-01-13T17:35:45+01:00 Address #25055, by disabling case-of-runRW# in Gentle phase See Note [Case-of-case and full laziness] in GHC.Driver.Config.Core.Opt.Simplify (cherry picked from commit de5d9852dbdd367611bf9e45e69c723d26351992) - - - - - 670a8cbc by Andreas Klebinger at 2025-01-13T17:40:11+01:00 Fix -freg-graphs for FP and AARch64 NCG (#24941). It seems we reserve 8 registers instead of four for global regs based on the layout in Note [AArch64 Register assignments]. I'm not sure it's neccesary, but for now we just accept this state of affairs and simple update -fregs-graph to account for this. (cherry picked from commit 3f89ab92da74c4ed45da68fe92ff81e7b9caa53d) - - - - - 823fec13 by Simon Peyton Jones at 2025-01-13T17:46:45+01:00 Fix nasty bug in occurrence analyser As #25096 showed, the occurrence analyser was getting one-shot info flat out wrong. This commit does two things: * It fixes the bug and actually makes the code a bit tidier too. The work is done in the new function GHC.Core.Opt.OccurAnal.mkRhsOccEnv, especially the bit that prepares the `occ_one_shots` for the RHS. See Note [The OccEnv for a right hand side] * When floating out a binding we must be conservative about one-shot info. But we were zapping the entire demand info, whereas we only really need zap the /top level/ cardinality. See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels For some reason there is a 2.2% improvement in compile-time allocation for CoOpt_Read. Otherwise nickels and dimes. Metric Decrease: CoOpt_Read (cherry picked from commit f6b4c1c9be71fc6fe4688337752ffa4ad84180d9) - - - - - 7c82602d by Arnaud Spiwack at 2025-01-13T17:47:24+01:00 Add tests for 25081 (cherry picked from commit e2f2a56e42d25bae178ae1692390bbbd6275176c) - - - - - 84ff3c72 by Arnaud Spiwack at 2025-01-13T17:47:32+01:00 Scale multiplicity in list comprehension Fixes #25081 (cherry picked from commit 23f50640e705c132f1a0689d4850866d0f0d76a6) - - - - - 544f2ba7 by doyougnu at 2025-01-13T17:47:42+01:00 Rts linker: add case for pc-rel 64 relocation part of the upstream haskell.nix patches (cherry picked from commit bfe4b3d3bbb98b39169fad063c6c32f06d167756) - - - - - 278b7f18 by Sylvain Henry at 2025-01-13T17:47:57+01:00 Only lookup ghcversion.h file in the RTS include-dirs by default. The code was introduced in 3549c952b535803270872adaf87262f2df0295a4. It used `getPackageIncludePath` which name doesn't convey that it looks into all include paths of the preload units too. So this behavior is probably unintentional and it should be ok to change it. Fix #25106 (cherry picked from commit f954f42823f6ca3588425a0d543d93ace86d89e4) - - - - - c1d30b65 by Andreas Klebinger at 2025-01-13T17:48:11+01:00 Add since annotation for -fkeep-auto-rules. This partially addresses #25082. - - - - - 219d34f9 by Andreas Klebinger at 2025-01-13T17:57:21+01:00 Mention `-fkeep-auto-rules` in release notes. It was added earlier but hadn't appeared in any release notes yet. Partially addresses #25082. - - - - - df444de5 by Sylvain Henry at 2025-01-13T18:01:33+01:00 Cmm: don't perform unsound optimizations on 32-bit compiler hosts - beef61351b240967b49169d27a9a19565cf3c4af enabled the use of MO_Add/MO_Sub for 64-bit operations in the C and LLVM backends - 6755d833af8c21bbad6585144b10e20ac4a0a1ab did the same for the x86 NCG backend However we store some literal values as `Int` in the compiler. As a result, some Cmm optimizations transformed target 64-bit literals into compiler `Int`. If the compiler is 32-bit, this leads to computing with wrong literals (see #24893 and #24700). This patch disables these Cmm optimizations for 32-bit compilers. This is unsatisfying (optimizations shouldn't be compiler-word-size dependent) but it fixes the bug and it makes the patch easy to backport. A proper fix would be much more invasive but it shall be implemented in the future. Co-authored-by: amesgen <amesgen at amesgen.de> (cherry picked from commit 7446a09a2d5b04b95cd43c03659b5647853124ce) - - - - - bc68b829 by Sylvain Henry at 2025-01-13T18:01:45+01:00 AARCH64 linker: skip NONE relocations This patch is part of the patches upstreamed from haskell.nix. See https://github.com/input-output-hk/haskell.nix/pull/1960 for the original report/patch. (cherry picked from commit c749bdfd3e21d712dc2b966482eb010165bdeebe) - - - - - 0d853dcc by sheaf at 2025-01-13T18:02:24+01:00 GHCi debugger: drop record name spaces for Ids When binding new local variables at a breakpoint, we should create Ids with variable namespace, and not record field namespace. Otherwise the rest of the compiler falls over because the IdDetails are wrong. Fixes #25109 (cherry picked from commit c29b2b5a77611b2bd6c3089765079bc43aec3e22) - - - - - 7241f7bf by Sylvain Henry at 2025-01-13T18:03:39+01:00 JS: support rubbish static literals (#25177) Support for rubbish dynamic literals was added in #24664. This patch does the same for static literals. Fix #25177 (cherry picked from commit 5092dbff750ee5b6fd082b7eed8574922a2b0bf4) - - - - - 784028b6 by Arsen Arsenović at 2025-01-13T18:04:06+01:00 ghc-toolchain: Don't leave stranded a.outs when testing for -g0 This happened because, when ghc-toolchain tests for -g0, it does so by compiling an empty program. This compilation creates an a.out. Since we create a temporary directory, lets place the test program compilation in it also, so that it gets cleaned up. Fixes: 25b0b40467d0a12601497117c0ad14e1fcab0b74 Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/25203 (cherry picked from commit b16605e7c135f8cfd357a60c7f358132faec6a84) - - - - - e9403d89 by Cheng Shao at 2025-01-13T18:04:16+01:00 rts: fix checkClosure error message This patch fixes an error message in checkClosure() when the closure has already been evacuated. The previous logic was meant to print the evacuated closure's type in the error message, but it was completely wrong, given info was not really an info table, but a tagged pointer that points to the closure's new address. (cherry picked from commit 0d3bc2fa3a9a8c342ec34bb9d32e493655a4ec69) - - - - - d55abf10 by Simon Peyton Jones at 2025-01-13T18:06:05+01:00 Add ZonkAny and document it This MR fixed #24817 by adding ZonkAny, which takes a Nat argument. See Note [Any types] in GHC.Builtin.Types, especially wrinkle (Any4). (cherry picked from commit cfbff65a8bde902b4510cdaead847bf7a52b4018) - - - - - 8fefeeb3 by Cheng Shao at 2025-01-14T00:01:28+00:00 autoconf: set RELEASE=NO - - - - - 5c38b62c by Cheng Shao at 2025-01-14T00:01:28+00:00 Revert "hadrian: Refactor treatment of extra dependencies" This reverts commit 3a18d9e7aff51dae78df8866e12f36649d379a58. - - - - - 89b41713 by Teo Camarasu at 2025-01-14T00:01:28+00:00 Make template-haskell a stage1 package Promoting template-haskell from a stage0 to a stage1 package means that we can much more easily refactor template-haskell. We implement this by duplicating the in-tree `template-haskell`. A new `template-haskell-next` library is autogenerated to mirror `template-haskell` `stage1:ghc` to depend on the new interface of the library including the `Binary` instances without adding an explicit dependency on `template-haskell`. This is controlled by the `bootstrap-th` cabal flag When building `template-haskell` modules as part of this vendoring we do not have access to quote syntax, so we cannot use variable quote notation (`'Just`). So we either replace these with hand-written `Name`s or hide the code behind CPP. We can remove the `th_hack` from hadrian, which was required when building stage0 packages using the in-tree `template-haskell` library. For more details see Note [Bootstrapping Template Haskell]. Resolves #23536 Co-Authored-By: Sebastian Graf <sgraf1337 at gmail.com> Co-Authored-By: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> (cherry picked from commit 42bd040702d9a1c620354e7de05aaff6ee849f38) - - - - - 99c2d16e by Teo Camarasu at 2025-01-14T00:01:28+00:00 Remove unecessary stage0 packages Historically quite a few packages had to be stage0 as they depended on `template-haskell` and that was stage0. In #23536 we made it so that was no longer the case. This allows us to remove a bunch of packages from this list. A few still remain. A new version of `Win32` is required by `semaphore-compat`. Including `Win32` in the stage0 set requires also including `filepath` because otherwise Hadrian's dependency logic gets confused. Once our boot compiler has a newer version of `Win32` all of these will be able to be dropped. Resolves #24652 (cherry picked from commit dd339c7acaf842ab275ee153be3521314ab4b85d) - - - - - bc687037 by Sylvain Henry at 2025-01-14T00:01:28+00:00 Fix TH dependencies (#22229) Add a dependency between Syntax and Internal (via module reexport). (cherry picked from commit 4d78c53c527af05bc1b4944219fa88306449bae0) - - - - - 2c9509f4 by Ben Gamari at 2025-01-14T00:01:28+00:00 Bump time submodule to 1.14 As requested in #24528. ------------------------- Metric Decrease: ghc_bignum_so rts_so Metric Increase: cabal_syntax_dir rts_so time_dir time_so ------------------------- (cherry picked from commit 1dacb506f55b8ab0aacf84dcfbf9742ad68f47c6) - - - - - 761fa9a9 by Cheng Shao at 2025-01-14T00:01:28+00:00 testsuite: fix req_target_smp predicate (cherry picked from commit a580722ecb716b917a16521d5185c1dbc24d0ab9) - - - - - 2af93fc6 by Cheng Shao at 2025-01-14T00:01:28+00:00 testsuite: bump PartialDownSweep timeout to 5x on wasm32 (cherry picked from commit b1e0c313e6f0ef4a98ff37e2dc443ea452c58f7e) - - - - - 5b3600d4 by Cheng Shao at 2025-01-14T00:01:28+00:00 rts: fix I/O manager compilation errors for win32 target This patch fixes I/O manager compilation errors for win32 target discovered when cross-compiling to win32 using recent clang: ``` rts/win32/ThrIOManager.c:117:7: error: error: call to undeclared function 'is_io_mng_native_p'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 117 | if (is_io_mng_native_p ()) { | ^ | 117 | if (is_io_mng_native_p ()) { | ^ 1 error generated. `x86_64-w64-mingw32-clang' failed in phase `C Compiler'. (Exit code: 1) rts/fs.c:143:28: error: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes] 143 | int setErrNoFromWin32Error () { | ^ | void | 143 | int setErrNoFromWin32Error () { | ^ 1 error generated. `x86_64-w64-mingw32-clang' failed in phase `C Compiler'. (Exit code: 1) rts/win32/ConsoleHandler.c:227:9: error: error: call to undeclared function 'interruptIOManagerEvent'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 227 | interruptIOManagerEvent (); | ^ | 227 | interruptIOManagerEvent (); | ^ rts/win32/ConsoleHandler.c:227:9: error: note: did you mean 'getIOManagerEvent'? | 227 | interruptIOManagerEvent (); | ^ rts/include/rts/IOInterface.h:27:10: error: note: 'getIOManagerEvent' declared here 27 | void * getIOManagerEvent (void); | ^ | 27 | void * getIOManagerEvent (void); | ^ 1 error generated. `x86_64-w64-mingw32-clang' failed in phase `C Compiler'. (Exit code: 1) rts/win32/ConsoleHandler.c:196:9: error: error: call to undeclared function 'setThreadLabel'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 196 | setThreadLabel(cap, t, "signal handler thread"); | ^ | 196 | setThreadLabel(cap, t, "signal handler thread"); | ^ rts/win32/ConsoleHandler.c:196:9: error: note: did you mean 'postThreadLabel'? | 196 | setThreadLabel(cap, t, "signal handler thread"); | ^ rts/eventlog/EventLog.h:118:6: error: note: 'postThreadLabel' declared here 118 | void postThreadLabel(Capability *cap, | ^ | 118 | void postThreadLabel(Capability *cap, | ^ 1 error generated. `x86_64-w64-mingw32-clang' failed in phase `C Compiler'. (Exit code: 1) ``` (cherry picked from commit 710665bdd48b055d763c30b88d690fadd46a03af) - - - - - cacf04e9 by Cheng Shao at 2025-01-14T00:01:28+00:00 autoconf: remove unused context diff check This patch removes redundant autoconf check for the context diff program given it isn't actually been used anywhere, especially since make removal. (cherry picked from commit b7bcf72990c20bf88c57d7d2b4478d8f2ad18ac3) - - - - - 72e758b1 by Cheng Shao at 2025-01-14T00:01:28+00:00 testsuite: bump T22744 timeout to 5x (cherry picked from commit c739383b9de12acde0e16f444b1563ef102d5e07) - - - - - b68820e7 by Cheng Shao at 2025-01-14T00:01:28+00:00 testsuite: don't attempt to detect host cpu features when testing cross ghc The testsuite driver CPU feature detection logic only detects host CPU and only makes sense when we are not testing a cross GHC. (cherry picked from commit c4c6d714b93e65052c872df0c3b700302adaba97) - - - - - 482418ac by Cheng Shao at 2025-01-14T00:01:28+00:00 compiler: avoid saving foreign call target to local when there are no caller-save GlobalRegs This patch makes the STG->Cmm backend avoid saving foreign call target to local when there are no caller-save GlobalRegs. Since 321941a8ebe25192cdeece723e1058f2f47809ea, when we lower a foreign call, we unconditionally save the foreign call target to a temporary local first, then rely on cmmSink to clean it up later, which only happens with -fcmm-sink (implied by -O) and not in unoptimized code. And this is troublesome for the wasm backend NCG, which needs to infer a foreign call target symbol's type signature from the Cmm call site. Previously, the NCG has been emitting incorrect type signatures for unoptimized code, which happens to work with `wasm-ld` most of the time, but this is never future-proof against upstream toolchain updates, and it causes horrible breakages when LTO objects are included in linker input. Hence this patch. (cherry picked from commit 8dd8a076058baca45ac52ace25b9c2797d61ef84) - - - - - 934777ce by Cheng Shao at 2025-01-14T00:08:12+00:00 testsuite: add callee-no-local regression test (cherry picked from commit 986df1abe23aaad4142721fbdb7dd3791cf153ad) - - - - - b7292e6f by Cheng Shao at 2025-01-14T00:08:17+00:00 testsuite: bump MultiLayerModulesDefsGhciReload timeout to 10x (cherry picked from commit e17f2df9906e2edd5ded932c8dcac4818e6ce0e4) - - - - - 8133cf64 by Cheng Shao at 2025-01-14T00:08:17+00:00 hadrian: build C/C++ with split sections when enabled When split sections is enabled, ensure -fsplit-sections is passed to GHC as well when invoking GHC to compile C/C++; and pass -ffunction-sections -fdata-sections to gcc/clang when compiling C/C++ with the hadrian Cc builder. Fixes #23381. (cherry picked from commit 0958937e79efcbe9f1ff25c1d697d62b8796d910) - - - - - f920cdf0 by Cheng Shao at 2025-01-14T00:08:18+00:00 driver: build C/C++ with -ffunction-sections -fdata-sections when split sections is enabled When -fsplit-sections is passed to GHC, pass -ffunction-sections -fdata-sections to gcc/clang when building C/C++. Previously, -fsplit-sections was only respected by the NCG/LLVM backends, but not the unregisterised backend; the GHC driver did not pass -fdata-sections and -ffunction-sections to the C compiler, which resulted in excessive executable sizes. Fixes #23381. ------------------------- Metric Decrease: size_hello_artifact size_hello_unicode ------------------------- (cherry picked from commit 02b1f91e93b4e26c8fc227f48878a66f342cb68f) - - - - - dbe05f41 by Cheng Shao at 2025-01-14T00:08:18+00:00 testsuite: mark process005 as fragile on JS (cherry picked from commit fd47e2e38dd10d6f39cc7ee2c512cb3e6b56a44e) - - - - - 3238226f by Cheng Shao at 2025-01-14T00:08:18+00:00 compiler: remove ArchWasm32 special case in cmmDoCmmSwitchPlans This patch removes special consideration for ArchWasm32 in cmmDoCmmSwitchPlans, which means the compiler will now disable cmmImplementSwitchPlans for wasm unreg backend, just like unreg backend of other targets. We enabled it in the past to workaround some compile-time panic in older versions of LLVM, but those panics are no longer present, hence no need to keep this workaround. (cherry picked from commit bf0737c0b86a36ccc5523582dea6979e020fb547) - - - - - 74294494 by Cheng Shao at 2025-01-14T00:08:18+00:00 utils: add hie.yaml config file for ghc-config Add hie.yaml to ghc-config project directory so it can be edited using HLS. (cherry picked from commit 7eda4bd229452b5d998398a12c45c62ad3c61777) - - - - - 70ebf663 by Cheng Shao at 2025-01-14T00:08:18+00:00 hadrian: handle findExecutable "" gracefully hadrian may invoke findExecutable "" at run-time due to a certain program is not found by configure script. Which is fine and findExecutable is supposed to return Nothing in this case. However, on Windows there's a directory bug that throws an exception (see https://github.com/haskell/directory/issues/180), so we might as well use a wrapper for findExecutable and handle exceptions gracefully. (cherry picked from commit 1e5752f64a522c4025365856d92f78073a7b3bba) - - - - - 34b924ab by Cheng Shao at 2025-01-14T00:08:18+00:00 configure: do not set LLC/OPT/LLVMAS fallback values when FIND_LLVM_PROG fails When configure fails to find LLC/OPT/LLVMAS within supported version range, it used to set "llc"/"opt"/"clang" as fallback values. This behavior is particularly troublesome when the user has llc/opt/clang with other versions in their PATH and run the testsuite, since hadrian will incorrectly assume have_llvm=True and pass that to the testsuite driver, resulting in annoying optllvm test failures (#23186). If configure determines llc/opt/clang wouldn't work, then we shouldn't pretend it'll work at all, and the bindist configure will invoke FIND_LLVM_PROG check again at install time anyway. (cherry picked from commit 4eb5ad09cf93caa5791a735baa0e7ba86b916f2a) - - - - - 13c0ad4a by Cheng Shao at 2025-01-14T00:08:18+00:00 compiler: fix -ddump-cmm-raw when compiling .cmm This patch fixes missing -ddump-cmm-raw output when compiling .cmm, which is useful for debugging cmm related codegen issues. (cherry picked from commit 6346c669215c797abb977cf875da4e4238f5d064) - - - - - 54e43687 by Cheng Shao at 2025-01-14T00:08:18+00:00 testsuite: mark T7773 as fragile on wasm (cherry picked from commit ae50a8eb73a21decf3f6aa6cd9e4f236d11bdc3f) - - - - - be2b8b76 by Cheng Shao at 2025-01-14T00:08:18+00:00 compiler: remove unused CompilerInfo/LinkerInfo types This patch removes CompilerInfo/LinkerInfo types from the compiler since they aren't actually used anywhere. (cherry picked from commit 98ad1ea5ea9f113335df591cab362d841ee7b96b) - - - - - 51aeafb2 by Cheng Shao at 2025-01-14T00:08:18+00:00 testsuite: bump T7653 timeout for wasm (cherry picked from commit 2eee65e1a4f441e99b79f3dc6e7d60492e4cad78) - - - - - 195d8b9b by Cheng Shao at 2025-01-14T00:08:18+00:00 testsuite: skip objc-hi/objcxx-hi when cross compiling objc-hi/objcxx-hi should be skipped when cross compiling. The existing opsys('darwin') predicate only asserts the host system is darwin but tells us nothing about the target, hence the oversight. (cherry picked from commit 595c0894f630f4fc377c6bf14a5fb88ca0f1398c) - - - - - a410aff5 by Cheng Shao at 2025-01-14T00:08:18+00:00 rts: cleanup inlining logic This patch removes pre-C11 legacy code paths related to INLINE_HEADER/STATIC_INLINE/EXTERN_INLINE macros, ensure EXTERN_INLINE is treated as static inline in most cases (fixes #24945), and also corrects the comments accordingly. (cherry picked from commit 35a64220c9e47d64635ae732f33795c611eb1fc8) - - - - - 0a0abc53 by Cheng Shao at 2025-01-14T00:08:18+00:00 rts: replace ad-hoc MYTASK_USE_TLV with proper CC_SUPPORTS_TLS This patch replaces the ad-hoc `MYTASK_USE_TLV` with the `CC_SUPPORTS_TLS` macro. If TLS support is detected by autoconf, then we should use that for managing `myTask` in the threaded RTS. (cherry picked from commit f3017dd3a7e3a2bd8a4f0b9f86268ff403f8f7c6) - - - - - 120ed44b by Cheng Shao at 2025-01-14T00:08:18+00:00 testsuite: bump T17572 timeout on wasm32 (cherry picked from commit 64fba310c2d23a41c88514aed0a482fbe5a3b184) - - - - - dd8bfc12 by Cheng Shao at 2025-01-14T00:08:18+00:00 testsuite: remove undesired -fasm flag from test ways This patch removes the -fasm flag from test ways, except ways like optasm that explicitly state they are meant to be compiled with NCG backend. Most test ways should use the default codegen backend, and the precense of -fasm can cause stderr mismatches like this when GHC is configured with the unregisterised backend: ``` --- /dev/null +++ /tmp/ghctest-3hydwldj/test spaces/testsuite/tests/profiling/should_compile/prof-late-cc.run/prof-late-cc.comp.stderr.normalised @@ -0,0 +1,2 @@ +when making flags consistent: warning: [GHC-74335] [-Winconsistent-flags (in -Wdefault)] + Target platform uses unregisterised ABI, so compiling via C *** unexpected failure for prof-late-cc(prof_no_auto) ``` This has been breaking the wasm unreg nightly job since !12595 landed. (cherry picked from commit 8848884718044dbcc08be134d768040ffa18d336) - - - - - 79b43c0f by Cheng Shao at 2025-01-14T00:08:18+00:00 ghci: fix isMinTTY.h casing for Windows targets This commit fixes isMinTTY.h casing in isMinTTY.c that's compiled for Windows targets. While this looks harmless given Windows filesystems are case-insensitive by default, it does cause a compilation warning with recent versions of clang, so we might as well fix the casing: ``` driver\ghci\isMinTTY.c:10:10: error: warning: non-portable path to file '"isMinTTY.h"'; specified path differs in case from file name on disk [-Wnonportable-include-path] | 10 | #include "isMINTTY.h" | ^ #include "isMINTTY.h" ^~~~~~~~~~~~ "isMinTTY.h" 1 warning generated. ``` (cherry picked from commit 3a145315052d6f66f9682ecff87b522011165d59) - - - - - a0942c45 by Cheng Shao at 2025-01-14T00:08:18+00:00 git: remove a.out and include it in .gitignore a.out is a configure script byproduct. It was mistakenly checked into the tree in !13118. This patch removes it, and include it in .gitignore to prevent a similar error in the future. (cherry picked from commit f0408eeb41286561d76d206a1f07cfe6b7c53d37) - - - - - f8369edc by Cheng Shao at 2025-01-14T00:08:18+00:00 driver: fix runWorkerLimit on wasm This commit fixes link-time unresolved symbol errors for sem_open etc on wasm, by making runWorkerLimit always behave single-threaded. This avoids introducing the jobserver logic into the final wasm module and thus avoids referencing the posix semaphore symbols. (cherry picked from commit ceca9efb3d437fb74263877d98d4fb4a45ee96b8) - - - - - c29a5fa5 by Cheng Shao at 2025-01-14T00:08:18+00:00 hadrian: remove unused ghciWithDebugger field from flavour config This patch removes the ghciWithDebugger field from flavour config since it's actually not used anywhere. (cherry picked from commit c6e5fd3d29219f69935eb117648e4eeab16bba13) - - - - - 362f384c by Cheng Shao at 2025-01-14T00:08:18+00:00 Drop obsolete libffi Makefile This patch drops obsolete libffi Makefile from the tree, given it's completely unused since removal of make build system in !7094. (cherry picked from commit 3fe843c730a2d882af98dac53958731624dfe0a3) - - - - - 34c2b36e by Cheng Shao at 2025-01-14T00:08:18+00:00 ghci: mitigate host/target word size mismatch in BCOByteArray serialization This patch mitigates a severe host/target word size mismatch issue in BCOByteArray serialization logic introduced since !12142, see added note for detailed explanation. (cherry picked from commit 90891962ad4d2c781e68062de01e25eea999ae1b) (cherry picked from commit 860596329a85295277aa21854f4aeae2b755c36f) (cherry picked from commit 30d12c468cd19940fecad1d6c89c51e5fe3f4050) - - - - - 11011b65 by Cheng Shao at 2025-01-14T00:08:18+00:00 ghci: use plain malloc for mkConInfoTable on non-TNTC platforms This patch avoids using mmap() to allocate executable memory for mkConInfoTable on platforms without tables-next-to-code, see added comment for explanation. (cherry picked from commit 839ac52e94f8ecf878e522dba0575466af248267) - - - - - 7692890c by Cheng Shao at 2025-01-14T00:08:18+00:00 ghc-internal: add missing CPPs for wasm This patch adds some missing CPP guards to ghc-internal, given those functions are non existent on wasm and would cause linking issues. (cherry picked from commit a998f69d2de062b7290e78221d55e8c49bf95bbc) - - - - - 57435136 by Cheng Shao at 2025-01-14T00:08:18+00:00 rts: rename prelude.js to prelude.mjs This commit renames prelude.js to prelude.mjs for wasm backend rts jsbits, and slightly adjusts the jsbits contents. This is for preparing the implementation of dyld.mjs that contains wasm dynamic linker logic, which needs to import prelude.mjs as a proper ESM module. (cherry picked from commit 71a471e7495f1fbf6b44cfbe4e930c99131c583e) - - - - - e0c2e46c by Cheng Shao at 2025-01-14T00:08:18+00:00 rts: add __wrapped_freeJSVal This commit wraps imported freeJSVal in a __wrapped_freeJSVal C function for wasm backend RTS. In general, wasm imports are only supposed to be directly called by C; they shouldn't be used as function pointers, which confuses wasm-ld at link-time when generating shared libraries. (cherry picked from commit 33d9db17f31f59ef72d6d8dac033a84c45d3c216) - - - - - d1df0400 by Cheng Shao at 2025-01-14T00:08:18+00:00 rts: correct stale link in comment (cherry picked from commit 0d0a16a81b3875c0e21c0bbe9659edc6312c4846) - - - - - f723c989 by Cheng Shao at 2025-01-14T00:08:18+00:00 rts: drop interpretBCO support from non-dyn ways on wasm This commit drops interpretBCO support from non dynamic rts ways on wasm. The bytecode interpreter is only useful when the RTS linker also works, and on wasm it only works for dynamic ways anyway. An additional benefit of dropping interpretBCO is reduction in code size of linked wasm modules, especially since interpretBCO references ffi_call which is an auto-generated large function in libffi-wasm and unused by most user applications. (cherry picked from commit 90a35c41bb676b5e68212f63b187d2c50439714c) - - - - - cb2e4186 by Cheng Shao at 2025-01-14T00:08:18+00:00 rts: don't build predefined GloblRegs for wasm PIC mode This commit wraps the predefined GlobalRegs in Wasm.S under a CPP guard to prevent building for PIC mode. When building dynamic ways of RTS, the wasm globals that represent STG GlobalRegs will be created and supplied by dyld.mjs. The current wasm dylink convention doesn't properly support exporting relocatable wasm globals at all, any wasm global exported by a .so is assumed to be a GOT.mem entry. (cherry picked from commit 98a32ec551dd95534c1a8eaccb0f67dbe5f19648) - - - - - 62c74f50 by Cheng Shao at 2025-01-14T00:08:18+00:00 rts: fix conflicting StgRun definitions on wasm This commit fixes conflicting StgRun definition when building dynamic ways of RTS for wasm in unregisterised mode. (cherry picked from commit bef94bde53f07a1b0d7eb16d3d0eb1bd62f5f992) - - - - - 370668dd by Cheng Shao at 2025-01-14T00:08:18+00:00 hadrian: use targetSupportsRPaths predicate This commit changes the hostSupportsRPaths predicate to targetSupportsRPaths and use that to decide whether to pass RPATH-related link-time options. It's not applied to stage0, we should just use the default link-time options of stageBoot ghc. (cherry picked from commit a6a82cdb7162f32a1b73a2a6224d6d9cd208962c) - - - - - 595520c3 by Cheng Shao at 2025-01-14T00:08:19+00:00 hadrian: disable internal-interpreter of ghc library when cross compiling This commit disable the internal-interpreter flag of ghc library when cross compiling, only external interpreter works in such cases. (cherry picked from commit f232c872c6adf4472b5a1c88812c57aa2aa76cbe) - - - - - 667ac259 by Cheng Shao at 2025-01-14T00:08:19+00:00 hadrian: enable internal-interpreter for ghc-bin stage0 This commit enables internal-interpreter flag for ghc-bin even when compiling stage0, as long as target supports ghci. It enables ghci functionality for cross targets that support ghci, since cross ghc-bin is really stage0. (cherry picked from commit 577c1819ab4eb3369cafdaf24114b74da21ce4b4) - - - - - a12248a5 by Cheng Shao at 2025-01-14T00:08:19+00:00 hadrian: fix CFLAGS for gmp shared objs on wasm This commit adds -fvisibility=default to CFLAGS of gmp when building for wasm. This is required to generate the ghc-bignum shared library without linking errors. Clang defaults to -fvisibility=hidden for wasm targets, which will cause issues when a symbol is expected to be exported in a shared library but without explicit visibility attribute annotation. (cherry picked from commit c247f2eef9e8450837cbaad1668c6178d094a8fb) - - - - - ac3c4797 by Cheng Shao at 2025-01-14T00:08:19+00:00 hadrian: re-enable PIC for gmp on wasm This commit re-enables --with-pic=yes configuration option of gmp when building for wasm, given we're about to include support for shared libraries, TH and ghci. (cherry picked from commit 775410fdfc5d6faf287eecdaae170af9f8a59bb9) - - - - - 477b90df by Cheng Shao at 2025-01-14T00:08:19+00:00 hadrian: add the host_fully_static flavour transformer This commit adds the host_fully_static flavour transformer to hadrian, which ensures stage0 is fully statically linked while still permitting stage1 libdir to contain shared libraries. This is intended to be used by the wasm backend to build portable linux bindists that contain wasm shared libraries. (cherry picked from commit b45080a3e34200767b76faca495f5aea95bb94f5) - - - - - 58fbc8c8 by Matthew Pickering at 2025-01-14T00:08:19+00:00 Update alpine release job to 3.20 alpine 3.20 was recently released and uses a new python and sphinx toolchain which could be useful to test. (cherry picked from commit 7bcda869abe650c60dac1bb5d64a2a0aeff71d6b) - - - - - 91d0f3ba by Cheng Shao at 2025-01-14T00:08:19+00:00 ci: update wasm jobs configuration This commit bumps ci-image revision to use updated wasm toolchain, and use host_fully_static instead of fully_static for wasm jobs so to ensure wasm shared libraries can be properly built. (cherry picked from commit 5043507ca32e31d14869a0a11dd317529f616fc2) - - - - - 4f8f12b3 by Cheng Shao at 2025-01-14T00:08:19+00:00 hadrian/testsuite: implement config.cross logic This commit implements the config.cross field in the testsuite driver. It comes from the "cross compiling" ghc info field for both in-tree/out-of-tree GHC, and is an accurate predicate of whether we're cross-compiling or not (compared to the precense of target emulator), and is useful to implement predicates to assert the precense of internal interpreter (only available on non-cross GHC) for tests that do require it (e.g. plugins). (cherry picked from commit 2956a3f7ecd58a6fda81447100404941c0ed837d) - - - - - 567c8eac by Cheng Shao at 2025-01-14T00:08:19+00:00 hadrian/compiler: implement targetRTSLinkerOnlySupportsSharedLibs This patch implements the targetRTSLinkerOnlySupportsSharedLibs predicate in hadrian. Its definition in hadrian is the single source of truth, and the information propagates to ghc settings file, ghc driver and testsuite driver. It is used in various places to ensure dynamic dependency is selected when the target RTS linker only supports loading dynamic code. (cherry picked from commit 8c74a0eda41255ead134f05598f5da70992a7054) - - - - - ad3375a7 by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: implement & use req_plugins predicate This commit implements req_plugins predicate to indicate that the test requires plugin functionality. Currently this means cross GHC is disabled since internal-interpreter doesn't work in cross GHC yet. (cherry picked from commit 3c21b696abc9acf375307eb91ccc678965487843) - - - - - 2841d111 by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: make use of config.interp_force_dyn This commit takes config.interp_force_dyn into consideration when setting up TH/ghci way flags. (cherry picked from commit 93b8af8009a6e174b8d75f766dba2dc4d9aa9119) - - - - - bace91fd by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: bump T17572 timeout (cherry picked from commit 94673d419a8cdf71d722c93da9860ad8807657e7) - - - - - 20e46828 by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: skip ghc api tests that attempt to spawn processes inside wasm This commit skips a few ghc api tests on wasm, since they would attempt to spawn processes inside wasm, which is not supported at all. (cherry picked from commit fa68f83355ecca1f72f4593a1ed0422fa8fcb6a6) - - - - - 4083c3f8 by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: skip T22840 due to broken -dtag-inference-checks on wasm (cherry picked from commit 1241c04e72107e1648f9aba5e857b48ec3bac96f) - - - - - 1d6b31bb by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: ensure $(ghciWayFlags) can be overridden This commit revises boilerplate.mk in testsuite as well as a few other places, to ensure the tests that do make use of $(ghciWayFlags) can receive the right $(ghciWayFlags) from testsuite driver config. (cherry picked from commit 78c8b90006ac4d0a4de4e72295f8a57de4b9beca) - - - - - 87045713 by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: skip rdynamic on wasm (cherry picked from commit 47989ecc6ddfbe68ba2213c6c2b0d29ed958c330) - - - - - c1dc80eb by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: skip T2615 on wasm This commit marks T2615 as skip on wasm, given LD_* environment variables aren't supported on wasm anyway. (cherry picked from commit fefb4ea1dee945ace173b63c808c593fc167803f) - - - - - ece36085 by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: mark MultiLayerModulesTH_Make/MultiLayerModulesTH_OneShot as fragile on wasm (cherry picked from commit 77c797625483be968bb51c1518020895ca5ecb11) - - - - - 7c50301f by Cheng Shao at 2025-01-14T00:08:19+00:00 testsuite: fix T16180 on wasm This commit fixes T16180 on wasm once TH support is flipped on. The fix is simply adding right asm code for wasm. (cherry picked from commit 69bb4745218d2d54c82e33fa529ccf9ba3819fac) - - - - - 0651d666 by Cheng Shao at 2025-01-14T00:08:19+00:00 driver: fix -fexternal-interpreter flag for JS backend Previously, -fexternal-interpreter is broken for JS backend, since GHC would attempt to launch a non-existent ghc-iserv* executable. This commit fixes it by adjusting pattern matching order in setTopSessionDynFlags. (cherry picked from commit 621c753dee540be65208d1fdcd1728ba9f2b4320) - - - - - b4bba2ca by Cheng Shao at 2025-01-14T00:08:19+00:00 driver: use interpreterDynamic predicate in preloadLib This commit use the interpreterDynamic predicate in preloadLib to decide if we should do dynLoadObjs instead of loadObj. Previously we used hostIsDynamic which was only written with non-cross internal interpreter in mind. The testsuite is also adjusted to remove hard-wired -fPIC flag for cbits (doesn't work in i386 RTS linker in vanilla way, #25260) and properly pass ghc_th_way_flags to ghc. (cherry picked from commit 80aa89831c18162ce5591400c41b4cd8f77db0e4) - - - - - 1e6e182f by Cheng Shao at 2025-01-14T00:08:19+00:00 compiler: fix Cmm dynamic CLabels for wasm This commit fixes the handling of dynamic CLabels for the wasm backend. Just do the simplest handling: preserve the original CLabel, both unreg/NCG backends can handle them properly without issue. (cherry picked from commit 744114618678ed1eac7a699c738ffa3223d1b41a) - - - - - ef977e6d by Cheng Shao at 2025-01-14T00:08:19+00:00 driver: add necessary compile-time flags for wasm PIC mode This commit adds necessary compile-time flags when compiling for wasm PIC mode, see added comment for detailed explanation. (cherry picked from commit f6abaf13c527e372edea2d70f9c012da8624e27c) - - - - - e81ba786 by Cheng Shao at 2025-01-14T00:08:19+00:00 driver: add necessary link-time flags for wasm shared libs This commit adds necessary link-time flags for wasm shared libs, see added comments for detailed explanation. (cherry picked from commit 9745fcfbffb6434bacdec69082739c9e0229c6f2) - - - - - f5fafa0a by Cheng Shao at 2025-01-14T00:08:19+00:00 driver: enforce -fno-use-rpaths for wasm This commit ensures the GHC driver never passes any RPATH-related link-time flags on wasm, which is not supported at all. (cherry picked from commit 649aae00c34014fcb64244de59961635563bf06a) - - - - - 2172b20b by Cheng Shao at 2025-01-14T00:08:19+00:00 driver: ensure static archives are picked when linking static .wasm modules This commit ensures static archives are picked when linking .wasm modules which are supposed to be fully static, even when ghc may be invoked with -dynamic, see added comment for explanation. (cherry picked from commit 47baa9044a786ab04b6b68cf008f1254471c3cc1) - - - - - edffbcfc by Cheng Shao at 2025-01-14T00:08:19+00:00 compiler: fix dynamic_too_enable for targets that require dynamic libraries This commit fixes dynamic_too_enable for targets whose RTS linker can only load dynamic code. (cherry picked from commit fc3a55917e9c6c64765f11e0703853b9eed230fe) - - - - - 08650af4 by Cheng Shao at 2025-01-14T00:08:20+00:00 compiler: fix checkNonStdWay for targets that require dynamic libraries This commit fixes checkNonStdWay to ensure that for targets whose RTS linker can only load dynamic code, the dynamic way of object is selected. (cherry picked from commit 94ef949ef8b52cebaf8d4a81d7a169e100da2a73) - - - - - eddc109b by Cheng Shao at 2025-01-14T00:08:20+00:00 ghc-bin: enforce dynamic way when the target requires so This commit makes ghc-bin use dynamic way when it is doing interactive stuff on certain targets whose RTS linker can only handle dynamic code. (cherry picked from commit 88e992489e1574b471a55ff9ddace2c81a09ba63) - - - - - 709bec66 by Cheng Shao at 2025-01-14T00:08:20+00:00 hadrian/ghci: add wasm dyld This commit adds the wasm dynamic linker implementation, as well as ghci logic to call it and hadrian logic to install it to the correct location. See the top-level note in utils/jsffi/dyld.mjs for more details. (cherry picked from commit 549582eff80da6a8c5b7449755eaa726c208c324) - - - - - 86ea726a by Cheng Shao at 2025-01-14T00:08:20+00:00 driver: fix getGccSearchDirectory for wasm target This commit fixes getGccSearchDirectory logic for wasm target, ensures the correct search directory containing libc.so etc can be found by GHC. getGccSearchDirectory is also exported so it can be used elsewhere to obtain the wasi-sdk libdir and pass to the dyld script. (cherry picked from commit b562e3a6fab87422f40997f84b11a05505df2fcb) - - - - - 928b42d9 by Cheng Shao at 2025-01-14T00:08:20+00:00 driver: add wasm backend iserv logic This commit adds wasm backend iserv logic to the driver, see added comments for explanation. (cherry picked from commit 2d6107dc0e461f6d339ea14712b6f0cb9a619680) - - - - - 9362667a by Cheng Shao at 2025-01-14T00:08:20+00:00 compiler: add PIC support to wasm backend NCG This commit adds support for generating PIC to the wasm backend NCG. (cherry picked from commit 61f5baa5bd6e8d0daa20af4dc7c3213a48f99019) - - - - - 0a1d2e8b by Cheng Shao at 2025-01-14T00:08:20+00:00 hadrian/compiler: flip on support for shared libs & ghci for wasm This commit flips on the support for shared libs and ghci for the wasm target, given all required support logic has been added in previous commits. (cherry picked from commit 652e72394b715abc931b1104a4b683bb16909695) - - - - - c92ce1e8 by Cheng Shao at 2025-01-14T00:08:20+00:00 testsuite: flip on support for shared libs, TH & ghci for wasm This commit flips on support for shared libs, TH & ghci for wasm in the testsuite, given support has been landed in previous commits. (cherry picked from commit 74a1f6818d1592ebceab8e0fbb6be1973f38fe78) - - - - - 489e3370 by Cheng Shao at 2025-01-14T00:08:20+00:00 Revert "compiler: start deprecating cmmToRawCmmHook" This reverts commit 1c064ef1f3e1aa2afc996e962ad53effa99ec5f4. Turns out the GHC-WPC project does use it to observe Cmm in the pipeline, see #25363. (cherry picked from commit 525d451e175c7d6acfa968ce99d8d3fc7a8af0c7) - - - - - 9abb751b by Cheng Shao at 2025-01-14T00:08:20+00:00 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. (cherry picked from commit 5bcfefd5bb73c18a9bad63d1813968832b696f9a) - - - - - 3364b4d3 by Luite Stegeman at 2025-01-14T00:08:20+00:00 Interpreter: Add locking for communication with external interpreter This adds locking to communication with the external interpreter to prevent concurrent tasks interfering with each other. This fixes Template Haskell with the external interpreter in parallel (-j) builds. Fixes #25083 - - - - - 0c373ab6 by Cheng Shao at 2025-01-14T00:08:20+00:00 wasm: bump dyld v8 heap size limit This patch adds `--max-old-space-size=8192` to wasm dyld shebang arguments to bump V8 heap size limit. The default limit (`heap_size_limit` returned by `v8.getHeapStatistics()`) is dynamically determined and a bit too low under certain workloads, and V8 would waste too much CPU time to garbage collect old generation heap more aggressively. Bumping the limit to 8G doesn't imply dyld would really take that much memory at run-time, but it lessens V8 heap stress significantly. (cherry picked from commit 14c5143899d164c7ac1213d918b4819684538c4b) - - - - - 718884fc by Cheng Shao at 2025-01-14T00:08:20+00:00 hadrian: make sure ghc-bin internal-interpreter is disabled for stage0 when not cross compiling This patch disables internal-interpreter flag for stage0 ghc-bin when not cross compiling, see added comment for explanation. Fixes #25406. (cherry picked from commit fde12aba9bb2d3ba607548dfba648f2a5ee00b59) - - - - - 0dad6161 by Cheng Shao at 2025-01-14T00:08:20+00:00 ghcid: use multi repl for ghcid (cherry picked from commit 589fea7f1035970f515d422e6956d7d09d363f8f) - - - - - c92da25a by Cheng Shao at 2025-01-14T00:08:20+00:00 wasm: fix safari console error message related to import("node:timers") This patch fixes the wasm backend JSFFI prelude script to avoid calling `import("node:timers")` on non-deno hosts. Safari doesn't like it and would print an error message to the console. Fixes https://gitlab.haskell.org/ghc/ghc-wasm-meta/-/issues/13. (cherry picked from commit 301c3b541de825b76cff59c739a8797b64321d1a) - - - - - 1ee6f2e4 by Cheng Shao at 2025-01-14T00:08:20+00:00 compiler: remove unused hscDecls/hscDeclsWithLocation This patch removes unused `hscDecls`/`hscDeclsWithLocation` functions from the compiler, to reduce maintenance burden when doing refactorings related to ghci. (cherry picked from commit e3496ef6c6f4cdb8bbef8b0e9dfa61219c32a575) - - - - - 4bf63e82 by Cheng Shao at 2025-01-14T00:08:20+00:00 testsuite: add T25414 test case marked as broken This commit adds T25414 test case to demonstrate #25414. It is marked as broken and will be fixed by the next commit. (cherry picked from commit 82213395dc2fbdc8b452336da0909896b4300218) - - - - - b6cd6d22 by Cheng Shao at 2025-01-14T00:08:20+00:00 driver: fix foreign stub handling logic in hscParsedDecls This patch fixes foreign stub handling logic in `hscParsedDecls`. Previously foreign stubs were simply ignored here, so any feature that involve foreign stubs would not work in ghci (e.g. CApiFFI). The patch reuses `generateByteCode` logic and eliminates a large chunk of duplicate logic that implements Core to bytecode generation pipeline here. Fixes #25414. (cherry picked from commit 677e3aa56e905524071fc9717a88ad2cd1bc2951) - - - - - 998eff67 by Cheng Shao at 2025-01-14T00:08:20+00:00 Remove unused USE_REPORT_PRELUDE code paths from the tree This patch removes unused `USE_REPORT_PRELUDE` code paths from the tree. They have been present since the first git revision 4fb94ae5e5d632748fa2e6c35e259eccc5a1a3f4, and might have been useful for debugging purposes many years ago, but these code paths are never actually built. Removing these ease maintenance of relevant modules in the future, and also allows us to get rid of `CPP` extension in those modules as a nice byproduct. (cherry picked from commit 573cad4bd9e7fc146581d9711d36c4e3bacbb6e9) - - - - - e00fdae1 by Cheng Shao at 2025-01-14T00:08:20+00:00 Remove obsolete executable wrappers from the tree The executable wrappers are handled by hadrian and bindist Makefile. The various .wrapper scripts in the tree are unused since removal of Make build system, so this patch removes them all. (cherry picked from commit 9ede97f3431cba9394904751762b9ab1a59dde0e) (cherry picked from commit 737e9e0bbf09475df92fe93cbe5bb76b299cbdfc) - - - - - 1269e36e by Cheng Shao at 2025-01-14T00:08:20+00:00 wasm: fix setImmediate() implementation for Cloudflare Workers This patch fixes setImmediate() implementation for Cloudflare Workers in the wasm backend's js prelude script. Cloudflare Workers doesn't support the MessageChannel API, and we use a setTimeout() based fallback implementation in this case. (cherry picked from commit c37b96fa267cc0419172ee5da6d969def5a8135b) (cherry picked from commit 6bd2d9ad7e5e3f444cba1fba062df50708848893) - - - - - a1978778 by Cheng Shao at 2025-01-14T00:08:20+00:00 wasm: fix FinalizationRegistry logic for Cloudflare Workers This patch fixes FinalizationRegistry related logic for Cloudflare Workers in wasm backend js post linker. Cloudflare Workers doesn't support FinalizationRegistry, in this case we use a dummy implementation that doesn't do anything. (cherry picked from commit bea8ea4cabcd51d098a361bd27d78884effa5d00) (cherry picked from commit 0346e7b71d4b48f91f2374e6864b15f8d8530fad) - - - - - df3aa970 by Cheng Shao at 2025-01-14T00:08:20+00:00 Remove obsolete cross-port script This patch removes the obsolete cross-port script in the tree. The script was based on the legacy Make build system which has been pruned from the tree long ago. For hadrian, proper support for two-stage bootstrapping onto a new unsupported platform is a work in progress in !11444. (cherry picked from commit 00d551bfac82d2974b09cf1c235dc56de49d257e) (cherry picked from commit 329a26da48ce812078ba5a6dc3dac11c872a1b9f) - - - - - dc15dd6d by Cheng Shao at 2025-01-14T00:08:20+00:00 hadrian: fix bindist makefile for wasm32-wasi target This patch fixes one incoherent place between bindist makefile and hadrian logic: I forgot to include wasi/wasm32 in OsSupportsGHCi/ArchSupportsGHCi as well. And this results in incorrect settings file generated after installing the bindist, and "Use interpreter"/"Have interpreter" fields incorrectly have "NO" values where they should be "YES" like --info output of in-tree version. (cherry picked from commit 75a2eae4cab9ba94f7ba331f64a65fe3519f26dd) (cherry picked from commit 735f3f9acd6c4346132157a9bd87448ed332a5f3) - - - - - 5ab7fc05 by Cheng Shao at 2025-01-14T00:08:20+00:00 misc: improve clangd compile_flags.txt flags This patch improves the compile_flags.txt config used to power clangd for the rts C codebase. The flags in the file are sampled & deduped from a real stage1 build with clang-19 and vastly improves the IDE accuracy when hacking the rts. For maximum code coverage under the default settings, compile_flags.txt defaults to threaded+profiled+dynamic+debug way. This does not mean profdyn needs to be actually built in _build/stage1 for IDE to work. To activate IDE for other RTS ways, simply remove one of the -D flags at the end of compile_flags.txt and restart clangd. (cherry picked from commit 59e0a77021e26c550fde39bf3b67a03dda497633) (cherry picked from commit 222a08aec5da56862c176202dc5d5f2d20e7cae2) - - - - - e0cc03f5 by Cheng Shao at 2025-01-14T00:08:20+00:00 testsuite: add regression test T25473 This commit adds regression test T25473 marked as broken due to #25473. It will be fixed in the subsequent commit. (cherry picked from commit ed2ed6c52e4b93b1afec5e5584aff4dc654bab04) (cherry picked from commit fb470cb623bc5dcd04a6ffda093be1400267b3d8) - - - - - a282de49 by Cheng Shao at 2025-01-14T00:08:20+00:00 wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. (cherry picked from commit bd0a8b7e7537499f7dc703f78ac96f34e4c40554) (cherry picked from commit 610b0f773f67ffef8383e2a680245d11dcfa38d2) - - - - - d3404e42 by Cheng Shao at 2025-01-14T00:08:20+00:00 ci: avoid depending on stack job for test-bootstrap jobs This patch makes test-bootstrap related ci jobs only depend on hadrian-ghc-in-ghci job to finish, consistent with other jobs in the full-build stage generated by gen_ci.hs. This allows the jobs to be spawned earlier and improve overall pipeline parallelism. (cherry picked from commit e684c40693577f47b1e6984f4c7994859edef6ad) (cherry picked from commit 4884eb08e2fdf422312cde0381dcabbc7208ec3c) - - - - - 2f4b8f39 by Cheng Shao at 2025-01-14T00:08:21+00:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. (cherry picked from commit 88c4fe1d8a3bdbedf3972fde12f663a974cc2191) (cherry picked from commit 5c7e7695698a664b671777f4c81470ecd7738ccf) - - - - - 0771892b by Cheng Shao at 2025-01-14T00:08:21+00:00 xxhash: bump to v0.8.3 (cherry picked from commit 42826a8941ecedd329844b675e26d30bdb6cd46b) (cherry picked from commit 3ea15740398fdb2c32234086be2c84172b1493f9) - - - - - 93298d42 by amesgen at 2025-01-14T00:08:21+00:00 wasm: prevent bundlers from resolving import("node:timers") (cherry picked from commit 7202a02c0a5238682de6a3a06a9b5137f02ad70c) (cherry picked from commit 5e60fd646823aa77b3401e5bd7f56cf369e77308) - - - - - 99166817 by Cheng Shao at 2025-01-14T00:08:21+00:00 ci: multi-project pipeline for wasm (cherry picked from commit 3655c3fd295cde9a78c15aa0ac002cf94bb813be) - - - - - 30 changed files: - .ghcid - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/jobs.yaml - CODEOWNERS - compile_flags.txt - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/AArch64.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/AArch64/Regs.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/934a8bb930390d5db1e5613ddfeafc8c80dd9b96...991668174d89b2eeda918302baa09bfcb98d7ff1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/934a8bb930390d5db1e5613ddfeafc8c80dd9b96...991668174d89b2eeda918302baa09bfcb98d7ff1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 00:09:33 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Mon, 13 Jan 2025 19:09:33 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/ghc-9.10 Message-ID: <6785ab3d735cd_31a5b3954f34277ce@gitlab.mail> Cheng Shao deleted branch wip/ghc-9.10 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 11:11:56 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Tue, 14 Jan 2025 06:11:56 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] 14 commits: Fix nasty bug in occurrence analyser Message-ID: <6786467ce7ef6_29c19d10ee2a452574@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 081a9d84 by Simon Peyton Jones at 2025-01-14T11:52:50+01:00 Fix nasty bug in occurrence analyser As #25096 showed, the occurrence analyser was getting one-shot info flat out wrong. This commit does two things: * It fixes the bug and actually makes the code a bit tidier too. The work is done in the new function GHC.Core.Opt.OccurAnal.mkRhsOccEnv, especially the bit that prepares the `occ_one_shots` for the RHS. See Note [The OccEnv for a right hand side] * When floating out a binding we must be conservative about one-shot info. But we were zapping the entire demand info, whereas we only really need zap the /top level/ cardinality. See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels For some reason there is a 2.2% improvement in compile-time allocation for CoOpt_Read. Otherwise nickels and dimes. Metric Decrease: CoOpt_Read (cherry picked from commit f6b4c1c9be71fc6fe4688337752ffa4ad84180d9) - - - - - 576b792a by Arnaud Spiwack at 2025-01-14T11:52:52+01:00 Add tests for 25081 (cherry picked from commit e2f2a56e42d25bae178ae1692390bbbd6275176c) - - - - - e39886ac by Arnaud Spiwack at 2025-01-14T11:52:52+01:00 Scale multiplicity in list comprehension Fixes #25081 (cherry picked from commit 23f50640e705c132f1a0689d4850866d0f0d76a6) - - - - - ddaa0928 by doyougnu at 2025-01-14T11:52:52+01:00 Rts linker: add case for pc-rel 64 relocation part of the upstream haskell.nix patches (cherry picked from commit bfe4b3d3bbb98b39169fad063c6c32f06d167756) - - - - - affa91f7 by Sylvain Henry at 2025-01-14T11:52:52+01:00 Only lookup ghcversion.h file in the RTS include-dirs by default. The code was introduced in 3549c952b535803270872adaf87262f2df0295a4. It used `getPackageIncludePath` which name doesn't convey that it looks into all include paths of the preload units too. So this behavior is probably unintentional and it should be ok to change it. Fix #25106 (cherry picked from commit f954f42823f6ca3588425a0d543d93ace86d89e4) - - - - - e94a2403 by Andreas Klebinger at 2025-01-14T11:52:52+01:00 Add since annotation for -fkeep-auto-rules. This partially addresses #25082. - - - - - b063ab38 by Andreas Klebinger at 2025-01-14T11:52:52+01:00 Mention `-fkeep-auto-rules` in release notes. It was added earlier but hadn't appeared in any release notes yet. Partially addresses #25082. - - - - - f2ed1384 by Sylvain Henry at 2025-01-14T11:52:52+01:00 Cmm: don't perform unsound optimizations on 32-bit compiler hosts - beef61351b240967b49169d27a9a19565cf3c4af enabled the use of MO_Add/MO_Sub for 64-bit operations in the C and LLVM backends - 6755d833af8c21bbad6585144b10e20ac4a0a1ab did the same for the x86 NCG backend However we store some literal values as `Int` in the compiler. As a result, some Cmm optimizations transformed target 64-bit literals into compiler `Int`. If the compiler is 32-bit, this leads to computing with wrong literals (see #24893 and #24700). This patch disables these Cmm optimizations for 32-bit compilers. This is unsatisfying (optimizations shouldn't be compiler-word-size dependent) but it fixes the bug and it makes the patch easy to backport. A proper fix would be much more invasive but it shall be implemented in the future. Co-authored-by: amesgen <amesgen at amesgen.de> (cherry picked from commit 7446a09a2d5b04b95cd43c03659b5647853124ce) - - - - - 145db9c8 by Sylvain Henry at 2025-01-14T11:52:52+01:00 AARCH64 linker: skip NONE relocations This patch is part of the patches upstreamed from haskell.nix. See https://github.com/input-output-hk/haskell.nix/pull/1960 for the original report/patch. (cherry picked from commit c749bdfd3e21d712dc2b966482eb010165bdeebe) - - - - - a777e025 by sheaf at 2025-01-14T11:52:52+01:00 GHCi debugger: drop record name spaces for Ids When binding new local variables at a breakpoint, we should create Ids with variable namespace, and not record field namespace. Otherwise the rest of the compiler falls over because the IdDetails are wrong. Fixes #25109 (cherry picked from commit c29b2b5a77611b2bd6c3089765079bc43aec3e22) - - - - - e1ce9a5b by Sylvain Henry at 2025-01-14T11:52:52+01:00 JS: support rubbish static literals (#25177) Support for rubbish dynamic literals was added in #24664. This patch does the same for static literals. Fix #25177 (cherry picked from commit 5092dbff750ee5b6fd082b7eed8574922a2b0bf4) - - - - - ff90f78f by Arsen Arsenović at 2025-01-14T11:52:52+01:00 ghc-toolchain: Don't leave stranded a.outs when testing for -g0 This happened because, when ghc-toolchain tests for -g0, it does so by compiling an empty program. This compilation creates an a.out. Since we create a temporary directory, lets place the test program compilation in it also, so that it gets cleaned up. Fixes: 25b0b40467d0a12601497117c0ad14e1fcab0b74 Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/25203 (cherry picked from commit b16605e7c135f8cfd357a60c7f358132faec6a84) - - - - - 82b35198 by Cheng Shao at 2025-01-14T11:52:53+01:00 rts: fix checkClosure error message This patch fixes an error message in checkClosure() when the closure has already been evacuated. The previous logic was meant to print the evacuated closure's type in the error message, but it was completely wrong, given info was not really an info table, but a tagged pointer that points to the closure's new address. (cherry picked from commit 0d3bc2fa3a9a8c342ec34bb9d32e493655a4ec69) - - - - - c9479053 by Simon Peyton Jones at 2025-01-14T11:52:53+01:00 Add ZonkAny and document it This MR fixed #24817 by adding ZonkAny, which takes a Nat argument. See Note [Any types] in GHC.Builtin.Types, especially wrinkle (Any4). (cherry picked from commit cfbff65a8bde902b4510cdaead847bf7a52b4018) - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToJS/Literal.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Utils/Outputable.hs - docs/users_guide/9.10.2-notes.rst - docs/users_guide/using-optimisation.rst - rts/linker/PEi386.c - rts/linker/elf_reloc_aarch64.c - rts/sm/Sanity.c - + testsuite/tests/codeGen/should_compile/T25177.hs - + testsuite/tests/codeGen/should_compile/T25177.stderr - testsuite/tests/codeGen/should_compile/all.T - + testsuite/tests/codeGen/should_run/T24700.hs - + testsuite/tests/codeGen/should_run/T24700.stdin - + testsuite/tests/codeGen/should_run/T24700.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d55abf10ff541174a0119f9e142ec4acaf2f2661...c9479053b7218e89c790916fa4a14b84cb289e9b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d55abf10ff541174a0119f9e142ec4acaf2f2661...c9479053b7218e89c790916fa4a14b84cb289e9b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 12:07:58 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Tue, 14 Jan 2025 07:07:58 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] 26 commits: X86 NCG: Fix argument promotion in foreign C calls Message-ID: <6786539ec8ca1_29c19d194e86868826@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 8a963d2c by Peter Trommler at 2025-01-14T12:44:32+01:00 X86 NCG: Fix argument promotion in foreign C calls Promote 8 bit and 16 bit signed arguments by sign extension. Fixes #25018 (cherry picked from commit a82121b3b6fdc2ac47211f71871b3ab21e5f6276) - - - - - d09da820 by Matthew Pickering at 2025-01-14T12:44:38+01:00 configure: Set LD_STAGE0 appropiately when 9.10.1 is used as a boot compiler In 9.10.1 the "ld command" has been removed, so we fall back to using the more precise "merge objects command" when it's available as LD_STAGE0 is only used to set the object merging command in hadrian. Fixes #24949 (cherry picked from commit 564981bda9a6a309ff0f524610af0f908432442f) - - - - - fffba270 by Matthew Pickering at 2025-01-14T12:44:39+01:00 hadrian: Don't build ghci object files for ./hadrian/ghci target There is some convoluted logic which determines whether we build ghci object files are not. In any case, if you set `ghcDynPrograms = pure False` then it forces them to be built. Given we aren't ever building executables with this flavour it's fine to leave `ghcDynPrograms` as the default and it should be a bit faster to build less. Also fixes #24949 (cherry picked from commit a949c792388b5662dd199497541f9ad51c78d1a8) - - - - - 20632a9f by Matthew Pickering at 2025-01-14T12:44:39+01:00 ci: Unset ALEX/HAPPY variables when testing bootstrap jobs Ticket #24826 reports a regression in 9.10.1 when building from a source distribution. This patch is an attempt to reproduce the issue on CI by more aggressively removing `alex` and `happy` from the environment. (cherry picked from commit 3f9548fe97c728ed60ba26811e4fe248fc28d2a7) - - - - - 4ecf7782 by Andrea Bedini at 2025-01-14T12:44:39+01:00 hadrian: Ignore build-tool-depends fields in cabal files hadrian does not utilise the build-tool-depends fields in cabal files and their presence can cause issues when building source distribution (see #24826) Ideally Cabal would support building "full" source distributions which would remove the need for workarounds in hadrian but for now we can patch the build-tool-depends out of the cabal files. Fixes #24826 (cherry picked from commit aba2c9d4728262cd9a2d711eded9050ac131c6c1) - - - - - 89a3ef84 by Zubin Duggal at 2025-01-14T12:44:39+01:00 compiler: Fingerprint -fwrite-if-simplified-core We need to recompile if this flag is changed because later modules might depend on the simplified core for this module if -fprefer-bytecode is enabled. Fixes #24656 (cherry picked from commit dddc9dff0547733a10e7f505612ab9df3a7c21b6) - - - - - 0d81d70a by Alex Mason at 2025-01-14T12:48:36+01:00 ncg(aarch64): Add fsqrt instruction, byteSwap primitives [#24956] Implements the FSQRT machop using native assembly rather than a C call. Implements MO_BSwap by producing assembly to do the byte swapping instead of producing a foreign call a C function. In `tar`, the hot loop for `deserialise` got almost 4x faster by avoiding the foreign call which caused spilling live variables to the stack -- this means the loop did 4x more memory read/writing than necessary in that particular case! (cherry picked from commit dee035bf618d75a18fe72dd3977434c0749a2156) - - - - - 27696fe0 by Sylvain Henry at 2025-01-14T12:48:38+01:00 Linker: use m32 allocator for sections when NEED_PLT (#24432) Use M32 allocator to avoid fragmentation when allocating ELF sections. We already did this when NEED_PLT was undefined. Failing to do this led to relocations impossible to fulfil (#24432). (cherry picked from commit 5104ee615503617a1c124fe1d92f6aa2d263b7d0) - - - - - d8dd7752 by Sylvain Henry at 2025-01-14T12:48:38+01:00 RTS: allow M32 allocation outside of 4GB range when assuming -fPIC (cherry picked from commit 52d6698479f951e07def237b0474ee22d27e621a) - - - - - 31e744b8 by Sylvain Henry at 2025-01-14T12:48:38+01:00 Linker: fix stub offset Remove unjustified +8 offset that leads to memory corruption (cf discussion in #24432). (cherry picked from commit c34fef56367142fa55e9861092f64cc7b9946fa1) - - - - - 61a648b3 by Simon Peyton Jones at 2025-01-14T12:48:38+01:00 Address #25055, by disabling case-of-runRW# in Gentle phase See Note [Case-of-case and full laziness] in GHC.Driver.Config.Core.Opt.Simplify (cherry picked from commit de5d9852dbdd367611bf9e45e69c723d26351992) - - - - - cb346572 by Andreas Klebinger at 2025-01-14T12:48:38+01:00 Fix -freg-graphs for FP and AARch64 NCG (#24941). It seems we reserve 8 registers instead of four for global regs based on the layout in Note [AArch64 Register assignments]. I'm not sure it's neccesary, but for now we just accept this state of affairs and simple update -fregs-graph to account for this. (cherry picked from commit 3f89ab92da74c4ed45da68fe92ff81e7b9caa53d) - - - - - 29c335b5 by Simon Peyton Jones at 2025-01-14T12:48:38+01:00 Fix nasty bug in occurrence analyser As #25096 showed, the occurrence analyser was getting one-shot info flat out wrong. This commit does two things: * It fixes the bug and actually makes the code a bit tidier too. The work is done in the new function GHC.Core.Opt.OccurAnal.mkRhsOccEnv, especially the bit that prepares the `occ_one_shots` for the RHS. See Note [The OccEnv for a right hand side] * When floating out a binding we must be conservative about one-shot info. But we were zapping the entire demand info, whereas we only really need zap the /top level/ cardinality. See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels For some reason there is a 2.2% improvement in compile-time allocation for CoOpt_Read. Otherwise nickels and dimes. Metric Decrease: CoOpt_Read (cherry picked from commit f6b4c1c9be71fc6fe4688337752ffa4ad84180d9) - - - - - 71d1331a by Arnaud Spiwack at 2025-01-14T12:48:38+01:00 Add tests for 25081 (cherry picked from commit e2f2a56e42d25bae178ae1692390bbbd6275176c) - - - - - d498425b by Arnaud Spiwack at 2025-01-14T12:48:38+01:00 Scale multiplicity in list comprehension Fixes #25081 (cherry picked from commit 23f50640e705c132f1a0689d4850866d0f0d76a6) - - - - - 3d52232c by doyougnu at 2025-01-14T12:48:39+01:00 Rts linker: add case for pc-rel 64 relocation part of the upstream haskell.nix patches (cherry picked from commit bfe4b3d3bbb98b39169fad063c6c32f06d167756) - - - - - 9db2e763 by Sylvain Henry at 2025-01-14T12:48:39+01:00 Only lookup ghcversion.h file in the RTS include-dirs by default. The code was introduced in 3549c952b535803270872adaf87262f2df0295a4. It used `getPackageIncludePath` which name doesn't convey that it looks into all include paths of the preload units too. So this behavior is probably unintentional and it should be ok to change it. Fix #25106 (cherry picked from commit f954f42823f6ca3588425a0d543d93ace86d89e4) - - - - - e4094ab3 by Andreas Klebinger at 2025-01-14T12:48:39+01:00 Add since annotation for -fkeep-auto-rules. This partially addresses #25082. - - - - - 1c1174d2 by Andreas Klebinger at 2025-01-14T12:48:39+01:00 Mention `-fkeep-auto-rules` in release notes. It was added earlier but hadn't appeared in any release notes yet. Partially addresses #25082. - - - - - 3f754d54 by Sylvain Henry at 2025-01-14T12:48:39+01:00 Cmm: don't perform unsound optimizations on 32-bit compiler hosts - beef61351b240967b49169d27a9a19565cf3c4af enabled the use of MO_Add/MO_Sub for 64-bit operations in the C and LLVM backends - 6755d833af8c21bbad6585144b10e20ac4a0a1ab did the same for the x86 NCG backend However we store some literal values as `Int` in the compiler. As a result, some Cmm optimizations transformed target 64-bit literals into compiler `Int`. If the compiler is 32-bit, this leads to computing with wrong literals (see #24893 and #24700). This patch disables these Cmm optimizations for 32-bit compilers. This is unsatisfying (optimizations shouldn't be compiler-word-size dependent) but it fixes the bug and it makes the patch easy to backport. A proper fix would be much more invasive but it shall be implemented in the future. Co-authored-by: amesgen <amesgen at amesgen.de> (cherry picked from commit 7446a09a2d5b04b95cd43c03659b5647853124ce) - - - - - 7c71a409 by Sylvain Henry at 2025-01-14T12:48:39+01:00 AARCH64 linker: skip NONE relocations This patch is part of the patches upstreamed from haskell.nix. See https://github.com/input-output-hk/haskell.nix/pull/1960 for the original report/patch. (cherry picked from commit c749bdfd3e21d712dc2b966482eb010165bdeebe) - - - - - 6fff383c by sheaf at 2025-01-14T12:48:39+01:00 GHCi debugger: drop record name spaces for Ids When binding new local variables at a breakpoint, we should create Ids with variable namespace, and not record field namespace. Otherwise the rest of the compiler falls over because the IdDetails are wrong. Fixes #25109 (cherry picked from commit c29b2b5a77611b2bd6c3089765079bc43aec3e22) - - - - - a201ff56 by Sylvain Henry at 2025-01-14T12:48:39+01:00 JS: support rubbish static literals (#25177) Support for rubbish dynamic literals was added in #24664. This patch does the same for static literals. Fix #25177 (cherry picked from commit 5092dbff750ee5b6fd082b7eed8574922a2b0bf4) - - - - - 1f850074 by Arsen Arsenović at 2025-01-14T12:48:39+01:00 ghc-toolchain: Don't leave stranded a.outs when testing for -g0 This happened because, when ghc-toolchain tests for -g0, it does so by compiling an empty program. This compilation creates an a.out. Since we create a temporary directory, lets place the test program compilation in it also, so that it gets cleaned up. Fixes: 25b0b40467d0a12601497117c0ad14e1fcab0b74 Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/25203 (cherry picked from commit b16605e7c135f8cfd357a60c7f358132faec6a84) - - - - - f7d7315d by Cheng Shao at 2025-01-14T12:48:39+01:00 rts: fix checkClosure error message This patch fixes an error message in checkClosure() when the closure has already been evacuated. The previous logic was meant to print the evacuated closure's type in the error message, but it was completely wrong, given info was not really an info table, but a tagged pointer that points to the closure's new address. (cherry picked from commit 0d3bc2fa3a9a8c342ec34bb9d32e493655a4ec69) - - - - - d90494ad by Simon Peyton Jones at 2025-01-14T12:48:39+01:00 Add ZonkAny and document it This MR fixed #24817 by adding ZonkAny, which takes a Nat argument. See Note [Any types] in GHC.Builtin.Types, especially wrinkle (Any4). (cherry picked from commit cfbff65a8bde902b4510cdaead847bf7a52b4018) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/AArch64/Regs.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToJS/Literal.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Utils/Outputable.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c9479053b7218e89c790916fa4a14b84cb289e9b...d90494adfd4ad2c9b82d7dffe360f3e2a0675621 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c9479053b7218e89c790916fa4a14b84cb289e9b...d90494adfd4ad2c9b82d7dffe360f3e2a0675621 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 12:09:30 2025 From: gitlab at gitlab.haskell.org (Adriaan Leijnse (@aidylns)) Date: Tue, 14 Jan 2025 07:09:30 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/aidylns/hsexpr-hshole-with-error Message-ID: <678653fa7f79a_29c19d18b16a869488@gitlab.mail> Adriaan Leijnse pushed new branch wip/aidylns/hsexpr-hshole-with-error at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/aidylns/hsexpr-hshole-with-error You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 12:10:11 2025 From: gitlab at gitlab.haskell.org (Adriaan Leijnse (@aidylns)) Date: Tue, 14 Jan 2025 07:10:11 -0500 Subject: [Git][ghc/ghc][wip/aidylns/ttg-remove-hsunboundvar-via-hshole] 218 commits: testsuite: normalise some versions in callstacks Message-ID: <67865423c43dd_29c19d1747f2469697@gitlab.mail> Adriaan Leijnse pushed to branch wip/aidylns/ttg-remove-hsunboundvar-via-hshole at Glasgow Haskell Compiler / GHC Commits: e56ed179 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: normalise some versions in callstacks (cherry picked from commit f230e29f30d0c1c566d4dd251807fcab76a2710e) - - - - - a28fc903 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: use -fhide-source-paths to normalise some backpack tests (cherry picked from commit b19de476bc5ce5c7792e8af1354b94a4286a1a13) - - - - - ed16d303 by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite/haddock: strip version identifiers and unit hashes from html tests (cherry picked from commit fbf0889eadc410d43dd5c1657e320634b6738fa5) - - - - - e45e5836 by Zubin Duggal at 2024-11-11T15:16:36+05:30 haddock: oneshot tests can drop files if they share modtimes. Stop this by including the filename in the key. Ideally we would use `ghc -M` output to do a proper toposort Partially addresses #25372 (cherry picked from commit e78c7ef96e395f1ef41f04790aebecd0409b92b9) - - - - - 9104e6eb by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: fix normalisation of T9930fail so that it doesn't get tripped up by ghc executable (ARGV[0]) differences (cherry picked from commit a79a587e025d42d34bb30e115fc5c7cab6c1e030) - - - - - 2c31264a by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: normalise windows file seperators (cherry picked from commit f858875e03b9609656b542aaaaff85ad0a83878a) - - - - - 2807f91b by Zubin Duggal at 2024-11-11T15:21:30+05:30 testsuite: Also match <VERSION> placeholders when normalising callsites - - - - - c02add17 by Ben Gamari at 2024-11-12T01:22:11-05:00 configure: Check version number validity Here we verify the previously informal invariant that stable release version numbers must have three components, preventing costly failed releases. Specifically, the check fails in the following scenarios: * `version=9.13` while `RELEASE=YES` since this would imply a release made from an unstable branch * `version=9.13.0` since unstable versions should only have two components * `version=9.12` since this has the wrong number of version components for a stable branch Fixes #25390. - - - - - 747fd322 by Teo Camarasu at 2024-11-12T01:22:49-05:00 docs: link to #14474 in the template-haskell docs - - - - - 6d96bb62 by Zubin Duggal at 2024-11-12T01:23:25-05:00 testsuite: normalise execvp vs exec differences in process tests Fixes #25431 - - - - - 502e6711 by Torsten Schmits at 2024-11-12T01:24:01-05:00 fix test lint that accumulated while the checks were broken I didn't fix the issues flagged by the #ifdef linter because it were so many that it seemed like the rule has become obsolete. - - - - - 223a4cb5 by Torsten Schmits at 2024-11-12T01:24:02-05:00 test driver: fix file collection for regex linters When a testsuite linter is executed with the `tracked` strategy, the driver runs `git ls-tree` to collect eligible files. This appears to have ceased producing any paths – `ls-tree` restricts its results to the current working directory, which is `testsuite/tests/linters` in this case. As a quick fix, this patch changes the working directory to match expectations. - - - - - 9ad9ac63 by Alan Zimmerman at 2024-11-12T01:24:39-05:00 EPA: Capture location of '_' for wild card type binder And keep track of promotion status in HsExplicitTupleTy, so the round-trip ppr test works for it. Updates Haddock output too, using the PromotionFlag in HsExplicitTupleTy. Closes #25454 - - - - - c37b96fa by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix setImmediate() implementation for Cloudflare Workers This patch fixes setImmediate() implementation for Cloudflare Workers in the wasm backend's js prelude script. Cloudflare Workers doesn't support the MessageChannel API, and we use a setTimeout() based fallback implementation in this case. - - - - - bea8ea4c by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix FinalizationRegistry logic for Cloudflare Workers This patch fixes FinalizationRegistry related logic for Cloudflare Workers in wasm backend js post linker. Cloudflare Workers doesn't support FinalizationRegistry, in this case we use a dummy implementation that doesn't do anything. - - - - - 00d551bf by Cheng Shao at 2024-11-13T08:48:21-05:00 Remove obsolete cross-port script This patch removes the obsolete cross-port script in the tree. The script was based on the legacy Make build system which has been pruned from the tree long ago. For hadrian, proper support for two-stage bootstrapping onto a new unsupported platform is a work in progress in !11444. - - - - - 75a2eae4 by Cheng Shao at 2024-11-13T08:48:58-05:00 hadrian: fix bindist makefile for wasm32-wasi target This patch fixes one incoherent place between bindist makefile and hadrian logic: I forgot to include wasi/wasm32 in OsSupportsGHCi/ArchSupportsGHCi as well. And this results in incorrect settings file generated after installing the bindist, and "Use interpreter"/"Have interpreter" fields incorrectly have "NO" values where they should be "YES" like --info output of in-tree version. - - - - - 0614abef by Alan Zimmerman at 2024-11-13T08:49:34-05:00 EPA: Correctly capture leading semis in decl list Closes #25467 - - - - - 00d58ae1 by Sebastian Graf at 2024-11-13T15:21:23-05:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. - - - - - 93233a66 by Ben Gamari at 2024-11-13T15:21:59-05:00 boot: Do not attempt to update config.sub While Apple ARM hardware was new we found that the autoconf scripts included in some boot packages were too old. As a mitigation for this, we introduced logic in the `boot` script to update the `config.sub` with that from the GHC tree. However, this causes submodules which have `config.sub` committted to appear to be dirty. This is a considerable headache. Now since `config.sub` with full platform support is more common we can remove `boot`'s `config.sub` logic. Fixes #19574. - - - - - fa66fa64 by Ryan Scott at 2024-11-14T19:05:00-05:00 Add regression test for #16234 Issue #16234 was likely fixed by !9765. This adds a regression test to ensure that it remains fixed. Fixes #16234. - - - - - bfe64df8 by Matthew Pickering at 2024-11-14T19:05:36-05:00 ghc-internal: Update to Unicode 16 This patch updates the automatically generated code for querying unicode properties to unicode 16. Fixes #25402 - - - - - 1fd83f86 by Ben Gamari at 2024-11-14T19:06:13-05:00 configure: Accept happy-2.1.2 happy-2.1 was released in late Oct 2024. I have confirmed that master bootstraps with it. Here we teach configure to accept this tool. Fixes #25438. - - - - - aa58fc5b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Tighten up invariants of PACK - - - - - 8aa4c10a by Ben Gamari at 2024-11-14T19:06:49-05:00 testsuite: Fix badly escaped literals Use raw string literals to ensure that `\s` is correctly interpreted as a character class. - - - - - 0e084029 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Improve documentation of SLIDE bytecode instruction - - - - - 9bf3663b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Assert that TEST*_P discriminators are valid - - - - - 1f668511 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Improve documentation of TEST*_P instructions - - - - - 59e0a770 by Cheng Shao at 2024-11-14T19:07:25-05:00 misc: improve clangd compile_flags.txt flags This patch improves the compile_flags.txt config used to power clangd for the rts C codebase. The flags in the file are sampled & deduped from a real stage1 build with clang-19 and vastly improves the IDE accuracy when hacking the rts. For maximum code coverage under the default settings, compile_flags.txt defaults to threaded+profiled+dynamic+debug way. This does not mean profdyn needs to be actually built in _build/stage1 for IDE to work. To activate IDE for other RTS ways, simply remove one of the -D flags at the end of compile_flags.txt and restart clangd. - - - - - c2c562e0 by Ben Gamari at 2024-11-14T19:08:01-05:00 testsuite: Don't consider untracked files in dirtiness check Considering trees containing untracked files as dirty is a bridge too far. The chance of an untracked file significantly affecting measured performanced metrics is quite small whereas not collecting measurements is quite inconvenient for some workflows. We now ignore untracked files in the dirtiness check. Fixes #25471. - - - - - ed2ed6c5 by Cheng Shao at 2024-11-14T19:08:37-05:00 testsuite: add regression test T25473 This commit adds regression test T25473 marked as broken due to #25473. It will be fixed in the subsequent commit. - - - - - bd0a8b7e by Cheng Shao at 2024-11-14T19:08:37-05:00 wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. - - - - - f1b0bc32 by Ben Gamari at 2024-11-14T19:09:13-05:00 rts/linker: Make FreeBSD declarations proper prototypes The iconv declarations for FreeBSD were previously not prototypes, leading to warnings. - - - - - 086cbbc1 by Ben Gamari at 2024-11-14T19:09:13-05:00 base: Drop redundant import in FreeBSD ExecutablePath implementation - - - - - 79ecd199 by Ben Gamari at 2024-11-14T19:09:13-05:00 compiler: Fix partial selector warnings in GHC.Runtime.Heap.Inspect - - - - - 1acb73bf by Andrew Lelechenko at 2024-11-15T06:10:47-05:00 gitlab: mention CLC in MR template - - - - - 8f2e0832 by Ben Gamari at 2024-11-15T06:11:24-05:00 rts: Allow use of GNU-stack notes on FreeBSD Previously we gated use of GNU-style non-executable stack notes to only apply on Linux. However, these are also supported by FreeBSD, which also uses ELF. Fix this. Fixes #25475. - - - - - 2c427cb0 by Ben Gamari at 2024-11-16T05:27:40-05:00 rts: Fix EINTR check in timerfd ticker When `poll` failed we previously checked that `errno == -EINTR` to silence the failure warning. However, this is wrong as `errno` values are generally not negated error codes (in contrast to many system call results, which is likely what the original author had in mind). Fixes #25477. - - - - - a0fa4941 by Ben Gamari at 2024-11-16T05:28:16-05:00 rts: Increase gen_workspace alignment to 128 bytes on AArch64 Increase to match the 128-byte cache-line size of Apple's ARMv8 implementation. Closes #25459. - - - - - 142d8afa by Ben Gamari at 2024-11-16T16:20:47-05:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - b7a146e5 by Ben Gamari at 2024-11-16T16:20:47-05:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - ddb7afa6 by Ben Gamari at 2024-11-16T16:21:23-05:00 users guide: Mention language extensions in equality constraints discussion As suggested in #24127, mention the language extensions necessary for usage of equality constriants in their documentation. Closes #24127. - - - - - 36133dac by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/9.14.1-notes: Fix list syntax - - - - - 888de658 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/debug-info: Fix duplicate flag descriptions - - - - - f120e427 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide: Fix reference to 9.14.1 release notes - - - - - 8e975032 by Ben Gamari at 2024-11-16T16:21:59-05:00 Introduce GHC.Tc.Plugin.lookupTHName This makes it significantly more convenient (and less GHC-version-dependent) to resolve a template-haskell name into a GHC Name. As proposed in #24741. - - - - - a0e168ec by ARATA Mizuki at 2024-11-16T16:22:40-05:00 x86 NCG SIMD: Lower packFloatX4#, insertFloatX4# and broadcastFloatX4# to SSE1 instructions Fixes #25441 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 3936bf1b by sheaf at 2024-11-16T16:23:22-05:00 X86 NCG: allow VXOR at scalar floating-point types The NCG can emit VXOR instructions at scalar floating-point types, but the pretty-printer would panic instead of emitting the appropriate VXORPS/VXORPD instructions. This patch rectifies that oversight. Fixes #25455 - - - - - d9dff93a by Ben Gamari at 2024-11-16T16:23:58-05:00 rts: Fix platform-dependent pointer casts Previously we had unnecessary (and incorrect) platform-dependent casts to turn `OSThreadIds`s into a integer. We now just uniformly cast first to a `uintptr_t` (which is always safe, regardless of whether `OSThreadId` is a pointer), and then cast to the desired integral type. This fixes a warning on musl platforms. - - - - - 6d95cdb8 by Ben Gamari at 2024-11-16T16:24:34-05:00 testsuite: Mark encoding004 as broken on FreeBSD Due to #22003, CP936 fails to roundtrip: ```diff == CP936 +Failed to roundtrip given mutant byte at index 891 (251 /= 123 at index 891) +Failed to roundtrip given mutant byte at index 1605 (197 /= 69 at index 1605) +Failed to roundtrip given mutant byte at index 2411 (235 /= 107 at index 2411) +Failed to roundtrip given mutant byte at index 6480 (208 /= 80 at index 6480) +Failed to roundtrip given mutant byte at index 6482 (210 /= 82 at index 6482) +Failed to roundtrip given mutant byte at index 6484 (212 /= 84 at index 6484) +Failed to roundtrip given mutant byte at index 6496 (224 /= 96 at index 6496) +Failed to roundtrip given mutant byte at index 7243 (203 /= 75 at index 7243) +Failed to roundtrip given mutant byte at index 7277 (237 /= 109 at index 7277) +Failed to roundtrip given mutant byte at index 8027 (219 /= 91 at index 8027) +Failed to roundtrip given mutant byte at index 8801 (225 /= 97 at index 8801) ``` - - - - - 26e86984 by Ben Gamari at 2024-11-18T04:05:31-05:00 hadrian: Allow haddock options to be passed via key-value settings - - - - - 6e68b117 by Matthew Pickering at 2024-11-18T04:06:07-05:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - a4e0d235 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 exceptions: Improve the message layout as per #285 This commit fixes the layout of the additional information included when displaying an exception, namely the type of the exception. It also fixes the default handler's heading message to work well together with the improved display message of SomeException. CLC proposal#285 - - - - - 284ffab3 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 Display type and callstack of exception on handler This commit changes the Exception instance of SomeException to *simply* display the underlying exception in `displayException`. The augmented exception message that included the type and backtrace of the exception are now only printed on a call to `displayExceptionWithInfo`. At a surface level, existing programs should behave the same since the `uncaughtExceptionHandler`, which is responsible for printing out uncaught exceptions to the user, will use `displayExceptionWithInfo` by default. However, unlike the instance's `displayException` method, the `uncaughtExceptionHandler` can be overriden with `setUncaughtExceptionHandler`. This makes the extra information opt-in without fixing it the instance, which can be valuable if your program wants to display uncaught exceptions to users in a user-facing way (ie without backtraces). This is what was originally agreed for CLC#231 or CLC#261 with regard to the type of the exception information. The call stack also becoming part of the default handler rather than the Exception instance is an ammendment to CLC#164. Discussion of the ammendment is part of CLC#285. - - - - - 36cddd2c by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Remove redundant CallStack from exceptions Before the exception backtraces proposal was implemented, ErrorCall accumulated its own callstack via HasCallStack constraints, but ExceptionContext is now accumulated automatically. The original ErrorCall mechanism is now redundant and we get a duplicate CallStack Updates Cabal submodule to fix their usage of ErrorCallWithLocation to ErrorCall CLC proposal#285 Fixes #25283 - - - - - 7a74330b by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Freeze call stack in error throwing functions CLC proposal#285 - - - - - 3abf31a4 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 De-duplicate displayContext and displayExceptionContext The former was unused except for one module where it was essentially re-defining displayExceptionContext. Moreover, this commit extends the fix from bfe600f5bb3ecd2c8fa71c536c63d3c46984e3f8 to displayExceptionContext too, which was missing. - - - - - c0d783f8 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Re-export NoBacktrace from Control.Exception This was originally proposed and accepted in section "2.7 Capturing Backtraces on Exceptions" of the CLC proposal for exception backtraces. However, the implementation missed this re-export, which this commit now fixes. - - - - - 802b5c3e by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Fix exception backtraces from GHCi When running the program with `runhaskell`/`runghc` the backtrace should match the backtrace one would get by compiling and running the program. But currently, an exception thrown in a program interpreted with `runhaskell` will: * Not include the original exception backtrace at all * Include the backtrace from the internal GHCi/ghc rethrowing of the original exception This commit fixes this divergence by not annotating the ghc(i) backtrace (with NoBacktrace) and making sure that the backtrace of the original exception is serialized across the boundary and rethrown with the appropriate context. Fixes #25116 The !13301 MR (not this commit in particular) improves performance of MultiLayerModules. Unfortunately, T3294 regresses on aarch64-linux-deb12 by 1% allocations. Since this patch must be merged for 9.12 ASAP, we will not be able to investigate the slight regression on this platform in time. ------------------------- Metric Decrease: MultiLayerModulesRecomp MultiLayerModulesTH_OneShot Metric Increase: T3294 ------------------------- - - - - - 3e89eb65 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 base: Add to changelog.md CLC #285 - - - - - d9326a48 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Bump array and stm submodules for testsuite The testsuites of array and stm had to be updated according to !13301. Updates submodule array and stm. - - - - - 325fcb5d by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Clean up code style of Nativei386 adjustor - - - - - 39bb6e58 by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Fix stack overrun error in Nativei386 adjustor We were reserving the wrong kind of adjustor context (the generic `AdjustorContext` used by other adjustor implementations, rather than the i386-specific `CCallContext`) to return the adjustor context while freeing, resulting in #25485. Fixes #25485. - - - - - 831aab22 by sheaf at 2024-11-18T21:22:36-05:00 Include diagnostic reason in -fdiagnostics-as-json This commit ensures that the -fdiagnostics-as-json output includes the diagnostic reason. This allows the full error message produced by GHC to be re-constructed from the JSON output. Fixes #25403 - - - - - 3e5bfdd3 by Ben Gamari at 2024-11-18T21:23:12-05:00 rts: Introduce printIPE This is a convenience utility for use in GDB. - - - - - 44d909a3 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Don't store boot locations in finder cache Partially reverts commit fff55592a7b Amends add(Home)ModuleToFinder so that locations for boot files are not stored in the finder cache. Removes InstalledModule field from InstalledFound constructor since it's the same as the key that was searched for. - - - - - 64c95292 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Concentrate boot extension logic in Finder With new mkHomeModLocation that takes an extra HscSource to add boot extensions if required. - - - - - 11bad98d by ARATA Mizuki at 2024-11-19T14:39:08-05:00 Better documentation for floating-point min/max and SIMD primitives See #25350 for floating-point min/max Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 791a47b2 by Arnaud Spiwack at 2024-11-20T14:00:05+00:00 Add test for #25185 - - - - - 374e18e5 by Arnaud Spiwack at 2024-11-20T14:09:30+00:00 Quick look: emit the multiplicity of app heads in tcValArgs Otherwise it's not scaled properly by the context, allowing unsound expressions. Fixes #25185. - - - - - 1fc02399 by sheaf at 2024-11-20T18:11:03-05:00 x86 NCG: fix regUsageOfInstr for VMOVU & friends This commit fixes the implementation of 'regUsageOfInstr' for vector operations that take an 'Operand' as the destination, by ensuring that when the destination is an address then the address should be *READ*, and not *WRITTEN*. Getting this wrong is a disaster, as it means the register allocator has incorrect information, which can lead to it discard stores to registers, segfaults ensuing. Fixes #25486 - - - - - 7bd407a6 by Brandon Chinn at 2024-11-21T14:08:15-05:00 Fix CRLF in multiline strings (#25375) - - - - - 7575709b by Rodrigo Mesquita at 2024-11-21T14:08:52-05:00 Improve reachability queries on ModuleGraph Introduces `ReachabilityIndex`, an index constructed from a `GHC.Data.Graph.Directed` `Graph` that supports fast reachability queries (in $O(1)$). This abstract data structure is exposed from `GHC.Data.Graph.Directed.Reachability`. This index is constructed from the module graph nodes and cached in `ModuleGraph`, enabling efficient reachability queries on the module graph. Previously, we'd construct a Map of Set of ModuleGraph nodes which used a lot of memory (`O(n^2)` in the number of nodes) and cache that in the `ModuleGraph`. By using the reachability index we get rid of this space leak in the module graph -- even though the index is still quadratic in the number of modules, it is much, much more space efficient due to its representation using an IntMap of IntSet as opposed to the transitive closure we previously cached. In a memory profile of MultiLayerModules with 100x100 modules, memory usage improved from 6GB residency to 2.8GB, out of which roughly 1.8GB are caused by a second space leak related to ModuleGraph. On the same program, it brings compile time from 7.5s to 5.5s. Note how we simplify `checkHomeUnitsClosed` in terms of `isReachableMany` and by avoiding constructing a second graph with the full transitive closure -- it suffices to answer the reachability query on the full graph without collapsing the transitive closure completely into nodes. Unfortunately, solving this leak means we have to do a little bit more work since we can no longer cache the result of turning vertex indices into nodes. This results in a slight regression in MultiLayerModulesTH_Make, but results in large performance and memory wins when compiling large amounts of modules. ------------------------- Metric Decrease: mhu-perf Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - bcbcdaaf by Cheng Shao at 2024-11-21T14:09:28-05:00 driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code This commit fixes an undefined symbol error in RTS linker when attempting to compile home modules with -fhpc and -fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for detailed description and analysis of the bug. Also adds T25510/T25510c regression tests to test make mode/oneshot mode of the bug. - - - - - 970ada5a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Bump ci-images For introduction of Alpine/i386 image. Thanks to Julian for the base image. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 8115abc2 by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Add release job for i386/Alpine As requested by Mikolaj and started by Julian. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 639f0149 by Ben Gamari at 2024-11-22T23:32:06-05:00 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ - - - - - 490d4d0a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Mark i386 Alpine test breakages Marks the following tests as broken on i386/Alpine: * T22033 due to #25497 * simd009, T25062_V16, T25169, T22187_run due to #25498 - - - - - 536cdf09 by Cheng Shao at 2024-11-22T23:32:42-05:00 compiler: remove unused GHC.Linker.Loader.loadExpr This patch removes the unused `GHC.Linker.Loader.loadExpr` function. It was moved from `GHC.Runtime.Linker.linkExpr` in `ghc-9.0` to `GHC.Linker.Loader.loadExpr` in `ghc-9.2`, and remain completely unused and untested ever since. There's also no third party user of this function to my best knowledge, so let's remove this. Anyone who wants to write their own GHC API function to load bytecode can consult the source code in older release branches. - - - - - 6ee35024 by Drew Fenwick at 2024-11-22T23:33:26-05:00 Fix a non-compiling example in the type abstractions docs This patch adds a missing Show constraint to a code example in the User Guide's type abstractions docs to fix issue #25422. - - - - - d1172e20 by Rodrigo Mesquita at 2024-11-22T23:34:02-05:00 Re-introduce ErrorCallWithLocation with a deprecation pragma With the removal of the duplicate backtrace, part of CLC proposal #285, the constructor `ErrorCallWithLocation` was removed from base. This commit re-introduces it with a deprecation. - - - - - 1187a60a by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Skip tests requiring Hadrian deps in out-of-tree testsuite runs Some testsuite tests require specific tools (e.g. `check-ppr` and `check-exact`) beyond those shipped in the binary distribution. Skip these tests. Fixes #13897. - - - - - c37d7a2e by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Declare exactprint tests' dependency on check-exact - - - - - 454ce957 by Ben Gamari at 2024-11-22T23:35:15-05:00 ghc-internal: Fix a few cases of missing Haddock markup - - - - - a249649b by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/GHCiPrimCall : Add missing Makefile includes - - - - - a021a493 by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/IpeStats: Use Make rather than shell interpolation - - - - - 6e1fbda7 by Ben Gamari at 2024-11-25T03:55:44-05:00 hadrian-ghci-multi: Pass -this-package-name in unit response files As noted in #25509, the `-this-package-name` must be passed for each package to ensure that GHC can response references to the packages' exposed modules via package-qualified imports. Fix this. Closes #25509. - - - - - a05e4a9b by Simon Hengel at 2024-11-25T03:56:33-05:00 Refactoring: Use `OnOff` more consistently for `Extension` - - - - - 7536181d by Matthew Pickering at 2024-11-25T14:00:07-05:00 driver: Always link against "base" package when one shot linking The default value for base-unit-id is stored in the settings file. At install time, this can be set by using the BASE_UNIT_ID environment variable. At runtime, the value can be set by `-base-unit-id` flag. For whether all this is a good idea, see #25382 Fixes #25382 - - - - - 7f90f319 by Andreas Klebinger at 2024-11-25T14:00:44-05:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 - - - - - 291388e1 by Cheng Shao at 2024-11-25T14:01:19-05:00 ci: minor nix-in-docker improvements This patch makes some minor improvements re nix-in-docker logic in the ci configuration: - Update `nixos/nix` to the latest version - Apply $CPUS to `cores`/`max-jobs` to avoid oversubscribing while allowing a reasonable degree of parallelism - Remove redundant `--extra-experimental-features nix-command` in later `nix shell` invocations, it's already configured in `/etc/nix/nix.conf` - - - - - e684c406 by Cheng Shao at 2024-11-25T14:01:57-05:00 ci: avoid depending on stack job for test-bootstrap jobs This patch makes test-bootstrap related ci jobs only depend on hadrian-ghc-in-ghci job to finish, consistent with other jobs in the full-build stage generated by gen_ci.hs. This allows the jobs to be spawned earlier and improve overall pipeline parallelism. - - - - - caaf5388 by Simon Hengel at 2024-11-25T14:02:41-05:00 Refactoring: Remove `pSupportedExts` from `ParserOpts` This is never used for lexing / parsing. It is only used by `GHC.Parser.Header.getOptions`. - - - - - 41f8365c by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Add test for #25515 - - - - - 9279619f by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Desugar record notation with correct multiplicities Simply uses the multiplicity as stored in the field. As I'm writing this commit, the only possible multiplicity is 1, but !13525 is changing this. It's actually easier to take !13525 into account. Fixes #25515. - - - - - fcc3ae6e by Andreas Klebinger at 2024-11-26T08:24:58-05:00 Clarify INLINE unfolding optimization docs. Fixes #24660 - - - - - 88c4fe1d by Cheng Shao at 2024-11-26T08:25:34-05:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. - - - - - 53f978c0 by doyougnu at 2024-11-26T16:07:26-05:00 ghc-experimental: expose GHC.RTS.Flags, GHC.Stats See this CLC proposal: - https://github.com/haskell/core-libraries-committee/issues/289 and this CLC proposal for background: - https://github.com/haskell/core-libraries-committee/issues/288 Metric Decrease: MultiLayerModulesTH_OneShot - - - - - e70d4140 by Wang Xin at 2024-11-26T16:08:10-05:00 Add -mcmodel=medium moduleflag to generated LLVM IR on LoongArch platform With the Medium code model, the jump range of the generated jump instruction is larger than that of the Small code model. It's a temporary fix of the problem descriped in https://gitlab.haskell .org/ghc/ghc/-/issues/25495. This commit requires that the LLVM used contains the code of commit 9dd1d451d9719aa91b3bdd59c0c6679 83e1baf05, i.e., version 8.0 and later. Actually we should not rely on LLVM, so the only way to solve this problem is to implement the LoongArch backend. Add new type for codemodel - - - - - df42ba16 by Andreas Klebinger at 2024-11-27T11:40:49-05:00 Cmm constant folding: Narrow results to operations bitwidth. When constant folding ensure the result is still within bounds for the given type by explicitly narrowing the results. Not doing so results in a lot of spurious assembler warnings especially when testing primops. - - - - - bf3db97e by Ben Gamari at 2024-11-27T11:41:26-05:00 ghc-toolchain: Introduce basic flag validation We verify that required flags (currently `--output` and `--triple`) are provided. The implementation is truly awful, but so is getopt. Begins to address #25500. - - - - - a104508d by Ben Gamari at 2024-11-27T11:42:03-05:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. - - - - - c3fc9b86 by Ben Gamari at 2024-11-27T11:42:39-05:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. - - - - - a362b943 by sheaf at 2024-11-27T23:44:28-05:00 Add checkExact to toolTargets This change means that the Hadrian multi target will include exactprint. In particular, this means that HLS will work on exactprint inside the GHC tree. - - - - - e6c957e4 by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Add test for #25428 - - - - - 52d97f4e by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Don't bypass MonoLocalBind in empty patterns Fixes #25428 - - - - - 7890f2d8 by Ben Gamari at 2024-11-28T10:26:46-05:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. - - - - - 0fd43ea6 by Adam Sandberg Ericsson at 2024-11-28T10:27:22-05:00 mention -Iw in +RTS -? - - - - - 6cf579b9 by Ben Gamari at 2024-11-28T10:27:59-05:00 gitlab-ci: Set GIT_SUBMODULE_FORCE_HTTPS GitLab recommends using `https://` to clone submodules and provides the `GIT_SUBMODULE_FORCE_HTTPS` variable to force this. Fixes #25528. - - - - - 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - f0269c46 by Adriaan Leijnse at 2025-01-14T12:07:24+00:00 HsHole constructor for unbound variables, parse errors, holes - - - - - 26 changed files: - .gitattributes - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/hello.hs - .gitlab/jobs.yaml - .gitlab/merge_request_templates/Default.md - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/upload.sh - .gitmodules - boot - compile_flags.txt - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/Format.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bdaba97fe7dd32561402ac76a47775940ebb0bb0...f0269c46f54f1da867d2897d5ab67a4744bc9246 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bdaba97fe7dd32561402ac76a47775940ebb0bb0...f0269c46f54f1da867d2897d5ab67a4744bc9246 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 12:12:35 2025 From: gitlab at gitlab.haskell.org (Adriaan Leijnse (@aidylns)) Date: Tue, 14 Jan 2025 07:12:35 -0500 Subject: [Git][ghc/ghc][wip/aidylns/ttg-remove-hsunboundvar-via-hshole] HsHole constructor for unbound variables, parse errors, holes Message-ID: <678654b3e11de_29c19d1747f247057a@gitlab.mail> Adriaan Leijnse pushed to branch wip/aidylns/ttg-remove-hsunboundvar-via-hshole at Glasgow Haskell Compiler / GHC Commits: 7b0d3835 by Adriaan Leijnse at 2025-01-14T12:12:10+00:00 HsHole constructor for unbound variables, parse errors, holes - - - - - 25 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Syn/Type.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Ticks.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/Language/Haskell/Syntax/Expr.hs - compiler/Language/Haskell/Syntax/Extension.hs - testsuite/tests/perf/compiler/hard_hole_fits.hs - testsuite/tests/perf/compiler/hard_hole_fits.stderr - testsuite/tests/plugins/T20803-plugin/FixErrorsPlugin.hs - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -11,6 +11,7 @@ {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilyDependencies #-} +{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] -- in module Language.Haskell.Syntax.Extension @@ -220,9 +221,9 @@ data EpAnnLam = EpAnnLam instance NoAnn EpAnnLam where noAnn = EpAnnLam noAnn noAnn -data EpAnnUnboundVar = EpAnnUnboundVar - { hsUnboundBackquotes :: (EpToken "`", EpToken "`") - , hsUnboundHole :: EpToken "_" +data EpAnnHole = EpAnnHole + { hsHoleBackquotes :: (EpToken "`", EpToken "`") + , hsHoleHole :: EpToken "_" } deriving Data -- Record selectors at parse time are HsVar; they convert to HsRecSel @@ -241,14 +242,6 @@ type instance XOverLabel GhcTc = DataConCantHappen type instance XVar (GhcPass _) = NoExtField -type instance XUnboundVar GhcPs = Maybe EpAnnUnboundVar -type instance XUnboundVar GhcRn = NoExtField -type instance XUnboundVar GhcTc = HoleExprRef - -- We really don't need the whole HoleExprRef; just the IORef EvTerm - -- would be enough. But then deriving a Data instance becomes impossible. - -- Much, much easier just to define HoleExprRef with a Data instance and - -- store the whole structure. - type instance XIPVar GhcPs = NoExtField type instance XIPVar GhcRn = NoExtField type instance XIPVar GhcTc = DataConCantHappen @@ -394,6 +387,63 @@ type instance XEmbTy GhcTc = DataConCantHappen -- A free-standing HsEmbTy is an error. -- Valid usages are immediately desugared into Type. + +-- | Expression Hole. +-- +-- Parser: produced on encountering an anonymous +-- expression hole ("_"), or a parse error. +-- +-- Renamer: produced from 'HsVar' when encountering out-of-scope variables +-- (which can also be named expression holes, i.e. "_hole"). The 'ParseError' +-- case is unhandled in this and the type checking phase. +-- +-- Type checker: the HoleExprRef is where the erroring expression will be written after +-- solving. See Note [Holes in expressions] in GHC.Tc.Types.Constraint. +-- +-- We really don't need the whole HoleExprRef; just the IORef EvTerm would +-- be enough. But then deriving a Data instance becomes impossible. Much, +-- much easier just to define HoleExprRef with a Data instance and store +-- the whole structure. +type instance XHole (GhcPass p) = + (HoleKind (XHoleVar (GhcPass p)) (XHoleParseError (GhcPass p)), XHoleShared (GhcPass p)) + +data HoleKind unboundVarInfo parseErrorInfo + = HoleVar unboundVarInfo + | HoleParseError parseErrorInfo + deriving Data + +-- | HsHole extensions for (named) holes and unbound variables. +type family XHoleVar x +type instance XHoleVar GhcPs = Maybe EpAnnHole +type instance XHoleVar GhcRn = RdrName +type instance XHoleVar GhcTc = RdrName + +-- | HsHole extension for parse errors. Unused for now except to encode that +-- these cannot occur after the renamer. +type family XHoleParseError p +type instance XHoleParseError GhcPs = NoExtField +type instance XHoleParseError GhcRn = DataConCantHappen +type instance XHoleParseError GhcTc = DataConCantHappen + +-- | HsHole extension shared between all types of holes. +type family XHoleShared p +type instance XHoleShared GhcPs = NoExtField +type instance XHoleShared GhcRn = NoExtField +type instance XHoleShared GhcTc = HoleExprRef + +-- | The RdrName for an unnamed hole ("_"). +unnamedHoleRdrName :: RdrName +unnamedHoleRdrName = mkUnqual varName (fsLit "_") + +-- | The RdrName for an unnamed ("_") hole or named hole/unbound variable +-- ("_hole"). +holeVarRdrName :: forall p. IsPass p => XHoleVar (GhcPass p) -> RdrName +holeVarRdrName hv = case (ghcPass @p, hv) of + (GhcPs, _) -> unnamedHoleRdrName + (GhcRn, r) -> r + (GhcTc, r) -> r + + type instance XForAll GhcPs = NoExtField type instance XForAll GhcRn = NoExtField type instance XForAll GhcTc = DataConCantHappen @@ -698,7 +748,11 @@ ppr_lexpr e = ppr_expr (unLoc e) ppr_expr :: forall p. (OutputableBndrId p) => HsExpr (GhcPass p) -> SDoc ppr_expr (HsVar _ (L _ v)) = pprPrefixOcc v -ppr_expr (HsUnboundVar _ uv) = pprPrefixOcc uv +ppr_expr (HsHole (HoleVar v, _)) = pprPrefixOcc (holeVarRdrName @p v) +ppr_expr (HsHole (HoleParseError x, _)) = case ghcPass @p of + GhcPs -> pprPrefixOcc unnamedHoleRdrName + GhcRn -> dataConCantHappen x + GhcTc -> dataConCantHappen x ppr_expr (HsIPVar _ v) = ppr v ppr_expr (HsOverLabel s l) = case ghcPass @p of GhcPs -> helper s @@ -954,10 +1008,13 @@ instance Outputable XXExprGhcTc where ppr exp, text ")"] ppr (HsRecSelTc f) = pprPrefixOcc f - ppr_infix_expr :: forall p. (OutputableBndrId p) => HsExpr (GhcPass p) -> Maybe SDoc ppr_infix_expr (HsVar _ (L _ v)) = Just (pprInfixOcc v) -ppr_infix_expr (HsUnboundVar _ occ) = Just (pprInfixOcc occ) +ppr_infix_expr (HsHole (HoleVar hv, _)) = Just (pprInfixOcc (holeVarRdrName @p hv)) +ppr_infix_expr (HsHole (HoleParseError x, _)) = case ghcPass @p of + GhcPs -> Just (pprInfixOcc unnamedHoleRdrName) -- TODO: Why not print the actual source text in case of a parse error? + GhcRn -> dataConCantHappen x + GhcTc -> dataConCantHappen x ppr_infix_expr (XExpr x) = case ghcPass @p of GhcRn -> ppr_infix_expr_rn x GhcTc -> ppr_infix_expr_tc x @@ -976,7 +1033,6 @@ ppr_infix_expr_tc (HsTick {}) = Nothing ppr_infix_expr_tc (HsBinTick {}) = Nothing ppr_infix_expr_tc (HsRecSelTc f) = Just (pprInfixOcc f) - ppr_infix_hs_expansion :: HsThingRn -> Maybe SDoc ppr_infix_hs_expansion (OrigExpr e) = ppr_infix_expr e ppr_infix_hs_expansion _ = Nothing @@ -1023,7 +1079,6 @@ hsExprNeedsParens prec = go where go :: HsExpr (GhcPass p) -> Bool go (HsVar{}) = False - go (HsUnboundVar{}) = False go (HsIPVar{}) = False go (HsOverLabel{}) = False go (HsLit _ l) = hsLitNeedsParens prec l @@ -1065,6 +1120,7 @@ hsExprNeedsParens prec = go go (HsProjection{}) = True go (HsGetField{}) = False go (HsEmbTy{}) = prec > topPrec + go (HsHole{}) = False go (HsForAll{}) = prec >= funPrec go (HsQual{}) = prec >= funPrec go (HsFunArr{}) = prec >= funPrec @@ -1120,7 +1176,7 @@ isAtomicHsExpr (HsLit {}) = True isAtomicHsExpr (HsOverLit {}) = True isAtomicHsExpr (HsIPVar {}) = True isAtomicHsExpr (HsOverLabel {}) = True -isAtomicHsExpr (HsUnboundVar {}) = True +isAtomicHsExpr (HsHole{}) = True isAtomicHsExpr (XExpr x) | GhcTc <- ghcPass @p = go_x_tc x | GhcRn <- ghcPass @p = go_x_rn x ===================================== compiler/GHC/Hs/Syn/Type.hs ===================================== @@ -103,7 +103,6 @@ lhsExprType (L _ e) = hsExprType e -- | Compute the 'Type' of an @'HsExpr' 'GhcTc'@ in a pure fashion. hsExprType :: HsExpr GhcTc -> Type hsExprType (HsVar _ (L _ id)) = idType id -hsExprType (HsUnboundVar (HER _ ty _) _) = ty hsExprType (HsOverLabel v _) = dataConCantHappen v hsExprType (HsIPVar v _) = dataConCantHappen v hsExprType (HsOverLit _ lit) = overLitType lit @@ -146,6 +145,8 @@ hsExprType (HsProc _ _ lcmd_top) = lhsCmdTopType lcmd_top hsExprType (HsStatic (_, ty) _s) = ty hsExprType (HsPragE _ _ e) = lhsExprType e hsExprType (HsEmbTy x _) = dataConCantHappen x +hsExprType (HsHole (HoleVar _, HER _ ty _)) = ty +hsExprType (HsHole (HoleParseError x, _)) = dataConCantHappen x hsExprType (HsQual x _ _) = dataConCantHappen x hsExprType (HsForAll x _ _) = dataConCantHappen x hsExprType (HsFunArr x _ _ _) = dataConCantHappen x ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -273,8 +273,9 @@ dsExpr e@(HsVar {}) = dsApp e dsExpr e@(HsApp {}) = dsApp e dsExpr e@(HsAppType {}) = dsApp e -dsExpr (HsUnboundVar (HER ref _ _) _) = dsEvTerm =<< readMutVar ref - -- See Note [Holes] in GHC.Tc.Types.Constraint +dsExpr (HsHole (HoleVar _, HER ref _ _)) = dsEvTerm =<< readMutVar ref + -- See Note [Holes in expressions] in GHC.Tc.Types.Constraint. +dsExpr (HsHole (HoleParseError x, _)) = dataConCantHappen x dsExpr (HsPar _ e) = dsLExpr e dsExpr (ExprWithTySig _ e _) = dsLExpr e @@ -316,6 +317,7 @@ dsExpr e@(XExpr ext_expr_tc) } + -- Strip ticks due to #21701, need to be invariant about warnings we produce whether -- this is enabled or not. dsExpr (NegApp _ (L loc ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1541,6 +1541,10 @@ repE (HsVar _ (L _ x)) = Just (DsBound y) -> repVarOrCon x (coreVar y) Just (DsSplice e) -> do { e' <- lift $ dsExpr e ; return (MkC e') } } +repE (HsHole (HoleVar uv, NoExtField)) = do + name <- repRdrName uv + repUnboundVar name +repE (HsHole (HoleParseError x, NoExtField)) = dataConCantHappen x repE (HsIPVar _ n) = rep_implicit_param_name n >>= repImplicitParamVar repE (HsOverLabel _ s) = repOverLabel s @@ -1679,9 +1683,6 @@ repE (HsTypedSplice n _) = rep_splice n repE (HsUntypedSplice (HsUntypedSpliceNested n) _) = rep_splice n repE e@(HsUntypedSplice (HsUntypedSpliceTop _ _) _) = pprPanic "repE: top level splice" (ppr e) repE (HsStatic _ e) = repLE e >>= rep2 staticEName . (:[]) . unC -repE (HsUnboundVar _ uv) = do - name <- repRdrName uv - repUnboundVar name repE (HsGetField _ e (L _ (DotFieldOcc _ (L _ (FieldLabelString f))))) = do e1 <- repLE e repGetField e1 f @@ -1716,10 +1717,8 @@ repE e@(XExpr (ExpandedThingRn o x)) else repE e } | otherwise = notHandled (ThExpressionForm e) - repE (XExpr (PopErrCtxt (L _ e))) = repE e repE (XExpr (HsRecSelRn (FieldOcc _ (L _ x)))) = repE (HsVar noExtField (noLocA x)) - repE e@(HsPragE _ (HsPragSCC {}) _) = notHandled (ThCostCentres e) repE e@(HsTypedBracket{}) = notHandled (ThExpressionForm e) repE e@(HsUntypedBracket{}) = notHandled (ThExpressionForm e) ===================================== compiler/GHC/HsToCore/Ticks.hs ===================================== @@ -470,13 +470,12 @@ addBinTickLHsExpr boxLabel e@(L pos e0) addTickHsExpr :: HsExpr GhcTc -> TM (HsExpr GhcTc) addTickHsExpr e@(HsVar _ (L _ id)) = do freeVar id; return e -addTickHsExpr e@(HsUnboundVar {}) = return e - addTickHsExpr e@(HsIPVar {}) = return e addTickHsExpr e@(HsOverLit {}) = return e addTickHsExpr e@(HsOverLabel{}) = return e addTickHsExpr e@(HsLit {}) = return e addTickHsExpr e@(HsEmbTy {}) = return e +addTickHsExpr e@(HsHole {}) = return e addTickHsExpr e@(HsQual {}) = return e addTickHsExpr e@(HsForAll {}) = return e addTickHsExpr e@(HsFunArr {}) = return e ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1203,7 +1203,6 @@ instance HiePass p => ToHie (LocatedA (HsExpr (GhcPass p))) where [ toHie $ C Use (L mspan var) -- Patch up var location since typechecker removes it ] - HsUnboundVar _ _ -> [] -- there is an unbound name here, but that causes trouble HsOverLabel {} -> [] HsIPVar _ _ -> [] HsOverLit _ o -> @@ -1351,6 +1350,7 @@ instance HiePass p => ToHie (LocatedA (HsExpr (GhcPass p))) where ] HsGetField {} -> [] HsProjection {} -> [] + HsHole _ -> [] -- there is a hole here, but that causes trouble XExpr x -> case hiePass @p of HieTc -> case x of WrapExpr w a ===================================== compiler/GHC/Parser.y ===================================== @@ -3926,7 +3926,7 @@ qopm :: { forall b. DisambInfixOp b => PV (LocatedN b) } -- used in section | hole_op { mkHsInfixHolePV $1 } hole_op :: { LocatedN (HsExpr GhcPs) } -- used in sections -hole_op : '`' '_' '`' { sLLa $1 $> (hsHoleExpr (Just $ EpAnnUnboundVar (epTok $1, epTok $3) (epTok $2))) } +hole_op : '`' '_' '`' { sLLa $1 $> (HsHole (HoleVar (Just $ EpAnnHole (epTok $1, epTok $3) (epTok $2)), NoExtField)) } qvarop :: { LocatedN RdrName } : qvarsym { $1 } ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -108,7 +108,6 @@ module GHC.Parser.PostProcess ( withArrowParsingMode, withArrowParsingMode', setTelescopeBndrsNameSpace, PatBuilder, - hsHoleExpr, -- Type/datacon ambiguity resolution DisambTD(..), @@ -1897,11 +1896,11 @@ instance DisambECP (HsExpr GhcPs) where type Body (HsExpr GhcPs) = HsExpr ecpFromCmd' (L l c) = do addError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrArrowCmdInExpr c - return (L l (hsHoleExpr noAnn)) + return (L l parseError) ecpFromExp' = return ecpFromPat' p@(L l _) = do addError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrOrPatInExpr p - return (L l (hsHoleExpr noAnn)) + return (L l parseError) mkHsProjUpdatePV l fields arg isPun anns = do !cs <- getCommentsFor l return $ mkRdrProjUpdate (EpAnn (spanAsAnchor l) noAnn cs) fields arg isPun anns @@ -1950,7 +1949,7 @@ instance DisambECP (HsExpr GhcPs) where mkHsOverLitPV (L (EpAnn l an csIn) a) = do !cs <- getCommentsFor (locA l) return $ L (EpAnn l an (cs Semi.<> csIn)) (HsOverLit NoExtField a) - mkHsWildCardPV l = return $ L (noAnnSrcSpan l) (hsHoleExpr noAnn) + mkHsWildCardPV l = return $ L (noAnnSrcSpan l) (HsHole (HoleVar noAnn, NoExtField)) mkHsTySigPV l@(EpAnn anc an csIn) a sig anns = do !cs <- getCommentsFor (locA l) return $ L (EpAnn anc an (csIn Semi.<> cs)) (ExprWithTySig anns a (hsTypeToHsSigWcType sig)) @@ -1971,11 +1970,11 @@ instance DisambECP (HsExpr GhcPs) where !cs <- getCommentsFor l return $ L (EpAnn (spanAsAnchor l) noAnn cs) (SectionR noExtField op e) mkHsAsPatPV l v _ e = addError (mkPlainErrorMsgEnvelope l $ PsErrTypeAppWithoutSpace (unLoc v) e) - >> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn)) + >> return (L (noAnnSrcSpan l) parseError) mkHsLazyPatPV l e _ = addError (mkPlainErrorMsgEnvelope l $ PsErrLazyPatWithoutSpace e) - >> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn)) + >> return (L (noAnnSrcSpan l) parseError) mkHsBangPatPV l e _ = addError (mkPlainErrorMsgEnvelope l $ PsErrBangPatWithoutSpace e) - >> return (L (noAnnSrcSpan l) (hsHoleExpr noAnn)) + >> return (L (noAnnSrcSpan l) parseError) mkSumOrTuplePV = mkSumOrTupleExpr mkHsEmbTyPV l toktype ty = return $ L (noAnnSrcSpan l) $ @@ -2002,9 +2001,6 @@ instance DisambECP (HsExpr GhcPs) where (PsErrUnallowedPragma prag) rejectPragmaPV _ = return () -hsHoleExpr :: Maybe EpAnnUnboundVar -> HsExpr GhcPs -hsHoleExpr anns = HsUnboundVar anns (mkRdrUnqual (mkVarOccFS (fsLit "_"))) - instance DisambECP (PatBuilder GhcPs) where type Body (PatBuilder GhcPs) = PatBuilder ecpFromCmd' (L l c) = addFatalError $ mkPlainErrorMsgEnvelope (locA l) $ PsErrArrowCmdInPat c @@ -3678,3 +3674,6 @@ mkListSyntaxTy1 brkOpen t brkClose = annsKeyword = (NoEpTok, brkOpen, brkClose) annParen = AnnParensSquare brkOpen brkClose + +parseError :: HsExpr GhcPs +parseError = HsHole (HoleParseError NoExtField, NoExtField) ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -318,7 +318,7 @@ rnUnboundVar v = do deferOutofScopeVariables <- goptM Opt_DeferOutOfScopeVariables -- See Note [Reporting unbound names] for difference between qualified and unqualified names. unless (isUnqual v || deferOutofScopeVariables) (reportUnboundName v >> return ()) - return (HsUnboundVar noExtField v, emptyFVs) + return (HsHole (HoleVar v, NoExtField), emptyFVs) rnExpr (HsVar _ (L l v)) = do { dflags <- getDynFlags @@ -353,8 +353,10 @@ rnExpr (HsVar _ (L l v)) rnExpr (HsIPVar x v) = return (HsIPVar x v, emptyFVs) -rnExpr (HsUnboundVar _ v) - = return (HsUnboundVar noExtField v, emptyFVs) +rnExpr (HsHole (HoleVar _, NoExtField)) + = return (HsHole (HoleVar unnamedHoleRdrName, NoExtField), emptyFVs) +rnExpr (HsHole (HoleParseError NoExtField, NoExtField)) + = panic "rnExpr tried to rename a HoleParseError" -- HsOverLabel: see Note [Handling overloaded and rebindable constructs] rnExpr (HsOverLabel src v) @@ -859,8 +861,8 @@ See #18151. Note [Reporting unbound names] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Faced with an out-of-scope `RdrName` there are two courses of action -A. Report an error immediately (and return a HsUnboundVar). This will halt GHC after the renamer is complete -B. Return a HsUnboundVar without reporting an error. That will allow the typechecker to run, which in turn +A. Report an error immediately (and return a `HsHole (HoleVar ...)`). This will halt GHC after the renamer is complete +B. Return a `HsHole (HoleVar ...)` without reporting an error. That will allow the typechecker to run, which in turn can give a better error message, notably giving the type of the variable via the "typed holes" mechanism. When `-fdefer-out-of-scope-variables` is on we follow plan B. ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -1466,10 +1466,10 @@ data NegationHandling = ReassociateNegation | KeepNegationIntact ---------------------------- get_op :: LHsExpr GhcRn -> OpName --- An unbound name could be either HsVar or HsUnboundVar +-- An unbound name could be either HsVar or (HsHole (HoleVar _, _)) -- See GHC.Rename.Expr.rnUnboundVar get_op (L _ (HsVar _ n)) = NormalOp (unLoc n) -get_op (L _ (HsUnboundVar _ uv)) = UnboundOp uv +get_op (L _ (HsHole (HoleVar uv, NoExtField))) = UnboundOp uv get_op (L _ (XExpr (HsRecSelRn fld))) = RecFldOp fld get_op other = pprPanic "get_op" (ppr other) ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1298,7 +1298,7 @@ badRuleLhsErr name lhs bad_e = TcRnIllegalRuleLhs errReason name lhs bad_e where errReason = case bad_e of - HsUnboundVar _ uv -> + HsHole (HoleVar uv, NoExtField) -> UnboundVariable uv $ notInScopeErr WL_Global uv _ -> IllegalExpression ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -1526,7 +1526,7 @@ maybeAddDeferredBindings hole report = do when (deferringAnyBindings ctxt) $ do err_tm <- mkErrorTerm (hole_loc hole) ref_ty report -- NB: ref_ty, not hole_ty. hole_ty might be rewritten. - -- See Note [Holes] in GHC.Tc.Types.Constraint + -- See Note [Holes in expressions] in GHC.Tc.Types.Constraint writeMutVar ref err_tm _ -> pure () where ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -221,7 +221,7 @@ A "head" has three special cases (for which we can infer a polytype using tcInferAppHead_maybe); otherwise is just any old expression (for which we can infer a rho-type (via tcInfer). -There is no special treatment for HsUnboundVar, HsOverLit etc, because +There is no special treatment for HsHole (HsVar ...), HsOverLit, etc, because we can't get a polytype from them. Left and right sections (e.g. (x +) and (+ x)) are not yet supported. @@ -680,7 +680,7 @@ tcInstFun do_ql inst_final (tc_fun, fun_ctxt) fun_sigma rn_args fun_is_out_of_scope -- See Note [VTA for out-of-scope functions] = case tc_fun of - HsUnboundVar {} -> True + HsHole (HoleVar {}, _) -> True _ -> False inst_fun :: [HsExprArg 'TcpRn] -> ForAllTyFlag -> Bool @@ -1056,7 +1056,7 @@ expr_to_type earg = = do { t <- go (L l e) ; let splice_result' = HsUntypedSpliceTop finalizers t ; return (L l (HsSpliceTy splice_result' splice)) } - go (L l (HsUnboundVar _ rdr)) + go (L l (HsHole (HoleVar rdr, NoExtField))) | isUnderscore occ = return (L l (HsWildCardTy noExtField)) | startsWithUnderscore occ = -- See Note [Wildcards in the T2T translation] @@ -1128,7 +1128,7 @@ This conversion is in the TcM monad because vfun [x | x <- xs] Can't convert list comprehension to a type vfun (\x -> x) Can't convert a lambda to a type * It needs to check for LangExt.NamedWildCards to generate an appropriate - error message for HsUnboundVar. + error message for HsHole (HsVar ...). vfun _a Not in scope: ‘_a’ (NamedWildCards disabled) vfun _a Illegal named wildcard in a required type argument: ‘_a’ @@ -1479,7 +1479,7 @@ Note [VTA for out-of-scope functions] Suppose 'wurble' is not in scope, and we have (wurble @Int @Bool True 'x') -Then the renamer will make (HsUnboundVar "wurble") for 'wurble', +Then the renamer will make (HsHole (HsVar "wurble", NoExtField)) for 'wurble', and the typechecker will typecheck it with tcUnboundId, giving it a type 'alpha', and emitting a deferred Hole constraint, to be reported later. @@ -1494,7 +1494,7 @@ tcUnboundId. It later reports 'wurble' as out of scope, and tries to give its type. Fortunately in tcInstFun we still have access to the function, so we -can check if it is a HsUnboundVar. We use this info to simply skip +can check if it is a HsHole. We use this info to simply skip over any visible type arguments. We'll /already/ have emitted a Hole constraint; failing preserves that constraint. ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -298,13 +298,15 @@ tcExpr (XExpr e) res_ty = tcXExpr e res_ty -- Typecheck an occurrence of an unbound Id -- -- Some of these started life as a true expression hole "_". --- Others might simply be variables that accidentally have no binding site -tcExpr (HsUnboundVar _ occ) res_ty +-- Others might simply be variables that accidentally have no binding site. +tcExpr (HsHole (HoleVar occ, NoExtField)) res_ty = do { ty <- expTypeToType res_ty -- Allow Int# etc (#12531) ; her <- emitNewExprHole occ ty ; tcEmitBindingUsage bottomUE -- Holes fit any usage environment -- (#18491) - ; return (HsUnboundVar her occ) } + ; return (HsHole (HoleVar occ, her)) + } +tcExpr (HsHole (HoleParseError x, NoExtField)) _ = dataConCantHappen x tcExpr e@(HsLit x lit) res_ty = do { let lit_ty = hsLitType lit @@ -765,6 +767,7 @@ tcXExpr xe@(ExpandedThingRn o e') res_ty | OrigStmt ls@(L loc _) <- o = setSrcSpanA loc $ mkExpandedStmtTc ls <$> tcApp (XExpr xe) res_ty + tcXExpr xe res_ty = tcApp (XExpr xe) res_ty {- ===================================== compiler/GHC/Tc/Gen/Head.hs ===================================== @@ -1271,10 +1271,9 @@ addStmtCtxt stmt = addExprCtxt :: HsExpr GhcRn -> TcRn a -> TcRn a addExprCtxt e thing_inside = case e of - HsUnboundVar {} -> thing_inside + HsHole (HoleVar {}, NoExtField) -> thing_inside _ -> addErrCtxt (ExprCtxt e) thing_inside - -- The HsUnboundVar special case addresses situations like + -- The HsHole special case addresses situations like -- f x = _ -- when we don't want to say "In the expression: _", -- because it is mentioned in the error message itself - ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -361,7 +361,7 @@ data DelayedError = DE_Hole Hole -- ^ A hole (in a type or in a term). -- - -- See Note [Holes]. + -- See Note [Holes in expressions]. | DE_NotConcrete NotConcreteError -- ^ A type could not be ensured to be concrete. -- @@ -380,7 +380,7 @@ instance Outputable DelayedError where -- | A hole stores the information needed to report diagnostics -- about holes in terms (unbound identifiers or underscores) or -- in types (also called wildcards, as used in partial type --- signatures). See Note [Holes]. +-- signatures). See Note [Holes in expressions] for holes in terms. data Hole = Hole { hole_sort :: HoleSort -- ^ What flavour of hole is this? , hole_occ :: RdrName -- ^ The name of this hole @@ -670,43 +670,78 @@ of the rhs. This is necessary because these constraints are used for substitutio during solving. If the kinds differed, then the substitution would take a well-kinded type to an ill-kinded one. -Note [Holes] -~~~~~~~~~~~~ -This Note explains how GHC tracks *holes*. - -A hole represents one of two conditions: - - A missing bit of an expression. Example: foo x = x + _ - - A missing bit of a type. Example: bar :: Int -> _ - -What these have in common is that both cause GHC to emit a diagnostic to the -user describing the bit that is left out. - -When a hole is encountered, a new entry of type Hole is added to the ambient -WantedConstraints. The type (hole_ty) of the hole is then simplified during -solving (with respect to any Givens in surrounding implications). It is -reported with all the other errors in GHC.Tc.Errors. - -For expression holes, the user has the option of deferring errors until runtime -with -fdefer-type-errors. In this case, the hole actually has evidence: this -evidence is an erroring expression that prints an error and crashes at runtime. -The ExprHole variant of holes stores an IORef EvTerm that will contain this evidence; -during constraint generation, this IORef was stored in the HsUnboundVar extension -field by the type checker. The desugarer simply dereferences to get the CoreExpr. - -Prior to fixing #17812, we used to invent an Id to hold the erroring -expression, and then bind it during type-checking. But this does not support -representation-polymorphic out-of-scope identifiers. See -typecheck/should_compile/T17812. We thus use the mutable-CoreExpr approach -described above. - -You might think that the type in the HoleExprRef is the same as the type of the -hole. However, because the hole type (hole_ty) is rewritten with respect to -givens, this might not be the case. That is, the hole_ty is always (~) to the -type of the HoleExprRef, but they might not be `eqType`. We need the type of the generated -evidence to match what is expected in the context of the hole, and so we must -store these types separately. - -Type-level holes have no evidence at all. +Note [Holes in expressions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This Note explains how GHC tracks "holes" in expressions. It does not +deal with holes in types, nor with partial type signatures. + +A hole represents a missing bit of an expression. Example: + foo x = x && _ +GHC then emits a diagnostic, describing the bit that is left out: + Foo.hs:5:14: error: [GHC-88464] + • Found hole: _ :: Bool + • In the second argument of ‘(&&)’, namely ‘_’ + In the expression: x && _ + +GHC uses the same mechanism is used to give diagnostics for out-of-scope +variables: + foo x = x && y +gives diagnostic + Foo.hs:5:14: error: [GHC-88464] + Variable not in scope: y :: Bool + +Here is how holes are represented in expressions: + +* If the user wrote "_": + Parser HsHole (HoleVar (EpAnnHole ...), NoExtField) + Renamer HsHole (HoleVar "_", NoExtField) + Typechecker HsHole (HoleVar "_", ref) + +* If the user wrote "x", where `x` is not in scope + Parser HsVar "x" + Renamer HsHole (HoleVar "x", NoExtField) + Typechecker HsHole (HoleVar "x", ref) + +In both cases (ref::HoleExprRef) contains + - The type of the hole. + - A ref-cell that is filled in (by the typechecker) with an + error thunk. With -fdefer-type errors we use this as the + value of the hole. + - A Unique (see Note [Uniques and tags]). + +Typechecking holes + +* When the typechecker encounters a `HsHole`, it returns one with the + HoleExprRef, but also emits a `DelayedError` into the `WantedConstraints`. + +* This DelayedError later triggers the error reporting, and the filling-in of + the error thunk, in GHC.Tc.Errors. + +* The user has the option of deferring errors until runtime with + `-fdefer-type-errors`. In this case, the hole carries evidence in its + `HoleExprRef`. This evidence is an erroring expression that prints an error + and crashes at runtime. + +Desugaring holes + +* During desugaring, the `(HsHole (HoleVar "x", ref))` is desugared by + reading the ref-cell to find the error thunk evidence term, put there by the + constraint solver. + +Wrinkles: + +* Prior to fixing #17812, we used to invent an Id to hold the erroring + expression, and then bind it during type-checking. But this does not support + representation-polymorphic out-of-scope identifiers. See + typecheck/should_compile/T17812. We thus use the mutable-CoreExpr approach + described above. + +* You might think that the type in the HoleExprRef is the same as the type of the + hole. However, because the hole type (hole_ty) is rewritten with respect to + givens, this might not be the case. That is, the hole_ty is always (~) to the + type of the HoleExprRef, but they might not be `eqType`. We need the type of the generated + evidence to match what is expected in the context of the hole, and so we must + store these types separately. -} mkNonCanonical :: CtEvidence -> Ct ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -585,7 +585,7 @@ data EvCallStack -} -- | Where to store evidence for expression holes --- See Note [Holes] in GHC.Tc.Types.Constraint +-- See Note [Holes in expressions] in GHC.Tc.Types.Constraint data HoleExprRef = HER (IORef EvTerm) -- ^ where to write the erroring expression TcType -- ^ expected type of that expression Unique -- ^ for debug output only ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -717,7 +717,6 @@ lexprCtOrigin (L _ e) = exprCtOrigin e exprCtOrigin :: HsExpr GhcRn -> CtOrigin exprCtOrigin (HsVar _ (L _ name)) = OccurrenceOf name exprCtOrigin (HsGetField _ _ (L _ f)) = GetFieldOrigin (field_label $ unLoc $ dfoLabel f) -exprCtOrigin (HsUnboundVar {}) = Shouldn'tHappenOrigin "unbound variable" exprCtOrigin (HsOverLabel _ l) = OverLabelOrigin l exprCtOrigin (ExplicitList {}) = ListOrigin exprCtOrigin (HsIPVar _ ip) = IPOccOrigin ip @@ -751,6 +750,8 @@ exprCtOrigin (HsUntypedSplice {}) = Shouldn'tHappenOrigin "TH untyped splice" exprCtOrigin (HsProc {}) = Shouldn'tHappenOrigin "proc" exprCtOrigin (HsStatic {}) = Shouldn'tHappenOrigin "static expression" exprCtOrigin (HsEmbTy {}) = Shouldn'tHappenOrigin "type expression" +exprCtOrigin (HsHole (HoleVar _, _)) = Shouldn'tHappenOrigin "(named) hole expression" +exprCtOrigin (HsHole (HoleParseError x, _)) = dataConCantHappen x exprCtOrigin (HsForAll {}) = Shouldn'tHappenOrigin "forall telescope" -- See Note [Types in terms] exprCtOrigin (HsQual {}) = Shouldn'tHappenOrigin "constraint context" -- See Note [Types in terms] exprCtOrigin (HsFunArr {}) = Shouldn'tHappenOrigin "function arrow" -- See Note [Types in terms] ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -925,15 +925,16 @@ zonkExpr (HsVar x (L l id)) do { id' <- zonkIdOcc id ; return (HsVar x (L l id')) } -zonkExpr (HsUnboundVar her occ) +zonkExpr (HsHole (HoleVar occ, her)) = do her' <- zonk_her her - return (HsUnboundVar her' occ) + return (HsHole (HoleVar occ, her')) where zonk_her :: HoleExprRef -> ZonkTcM HoleExprRef zonk_her (HER ref ty u) = do updTcRefM ref zonkEvTerm ty' <- zonkTcTypeToTypeX ty return (HER ref ty' u) +zonkExpr (HsHole (HoleParseError x, _)) = dataConCantHappen x zonkExpr (HsIPVar x _) = dataConCantHappen x ===================================== compiler/Language/Haskell/Syntax/Expr.hs ===================================== @@ -41,7 +41,6 @@ import Data.Bool import Data.Eq import Data.Maybe import Data.List.NonEmpty ( NonEmpty ) -import GHC.Types.Name.Reader {- Note [RecordDotSyntax field updates] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -335,19 +334,6 @@ data HsExpr p (LIdP p) -- ^ Variable -- See Note [Located RdrNames] - | HsUnboundVar (XUnboundVar p) - RdrName -- ^ Unbound variable; also used for "holes" - -- (_ or _x). - -- Turned from HsVar to HsUnboundVar by the - -- renamer, when it finds an out-of-scope - -- variable or hole. - -- The (XUnboundVar p) field becomes an HoleExprRef - -- after typechecking; this is where the - -- erroring expression will be written after - -- solving. See Note [Holes] in GHC.Tc.Types.Constraint. - - - | HsOverLabel (XOverLabel p) FastString -- ^ Overloaded label (Note [Overloaded labels] in GHC.OverloadedLabels) @@ -380,7 +366,7 @@ data HsExpr p -- NB Bracketed ops such as (+) come out as Vars. -- NB Sadly, we need an expr for the operator in an OpApp/Section since - -- the renamer may turn a HsVar into HsRecSel or HsUnboundVar + -- the renamer may turn a HsVar into HsRecSel or HsHole. | OpApp (XOpApp p) (LHsExpr p) -- left operand @@ -529,6 +515,10 @@ data HsExpr p | HsEmbTy (XEmbTy p) (LHsWcType (NoGhcTc p)) + -- | Holes in expressions, i.e. '_'. + -- See Note [Holes in expressions] in GHC.Tc.Types.Constraint. + | HsHole (XHole p) + -- | Forall-types @forall tvs. t@ and @forall tvs -> t at . -- Used with @RequiredTypeArguments@, e.g. @fn (forall a. Proxy a)@. -- See Note [Types in terms] ===================================== compiler/Language/Haskell/Syntax/Extension.hs ===================================== @@ -445,6 +445,7 @@ type family XTick x type family XBinTick x type family XPragE x type family XEmbTy x +type family XHole x type family XForAll x type family XQual x type family XFunArr x ===================================== testsuite/tests/perf/compiler/hard_hole_fits.hs ===================================== @@ -12,7 +12,7 @@ import GHC (GhcPs) testMe :: HsExpr GhcPs -> Int testMe (HsVar a b) = _ -testMe (HsUnboundVar xuv uv) = _ +testMe (HsHole a) = _ testMe (HsOverLabel xol m_ip) = _ testMe (HsIPVar xv hin) = _ testMe (HsOverLit xole hol) = _ ===================================== testsuite/tests/perf/compiler/hard_hole_fits.stderr ===================================== @@ -17,14 +17,12 @@ hard_hole_fits.hs:14:22: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] (imported from ‘Prelude’ at hard_hole_fits.hs:8:8-20 (and originally defined in ‘GHC.Internal.Enum’)) -hard_hole_fits.hs:15:32: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] - • Found hole: _ :: Int - • In an equation for ‘testMe’: testMe (HsUnboundVar xuv uv) = _ - • Relevant bindings include - uv :: GHC.Types.Name.Reader.RdrName - (bound at hard_hole_fits.hs:15:26) - xuv :: Language.Haskell.Syntax.Extension.XUnboundVar GhcPs - (bound at hard_hole_fits.hs:15:22) +hard_hole_fits.hs:15:21: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] + Found hole: _ :: Int + In an equation for ‘testMe’: testMe (HsHole a) = _ + Relevant bindings include + a :: Language.Haskell.Syntax.Extension.XHole GhcPs + (bound at hard_hole_fits.hs:15:16) testMe :: HsExpr GhcPs -> Int (bound at hard_hole_fits.hs:14:1) Valid hole fits include maxBound :: forall a. Bounded a => a ===================================== testsuite/tests/plugins/T20803-plugin/FixErrorsPlugin.hs ===================================== @@ -20,15 +20,15 @@ import Data.Maybe plugin :: Plugin plugin = defaultPlugin {parsedResultAction = parsedAction} --- Replace every hole (and other unbound vars) with the given expression +-- Replace every hole with the given expression replaceHoles :: forall a . Data a => HsExpr GhcPs -> a -> a replaceHoles new = gmapT \case (d :: d) -> replaceHoles new d `fromMaybe` tryHole where tryHole :: Maybe d tryHole = eqT @d @(HsExpr GhcPs) >>= \case - Eq.Refl | HsUnboundVar _ _ <- d -> Just new - _ -> Nothing + Eq.Refl | HsHole _ <- d -> Just new + _ -> Nothing parsedAction :: [CommandLineOption] -> ModSummary -> ParsedResult -> Hsc ParsedResult ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -314,7 +314,7 @@ instance HasTrailing AnnExplicitSum where trailing _ = [] setTrailing a _ = a -instance HasTrailing (Maybe EpAnnUnboundVar) where +instance HasTrailing (Maybe EpAnnHole) where trailing _ = [] setTrailing a _ = a @@ -2879,16 +2879,17 @@ instance ExactPrint (HsExpr GhcPs) where then markAnnotated n else return n return (HsVar x n') - exact (HsUnboundVar an n) = do + exact (HsHole (HoleVar an, NoExtField)) = do case an of - Just (EpAnnUnboundVar (ob,cb) l) -> do + Just (EpAnnHole (ob,cb) l) -> do ob' <- markEpToken ob l' <- markEpToken l cb' <- markEpToken cb - return (HsUnboundVar (Just (EpAnnUnboundVar (ob',cb') l')) n) - _ -> do + return (HsHole (HoleVar (Just (EpAnnHole (ob',cb') l')), NoExtField)) + Nothing -> do printStringAdvanceA "_" >> return () - return (HsUnboundVar an n) + return (HsHole (HoleVar an, NoExtField)) + exact (HsHole (HoleParseError NoExtField, NoExtField)) = error "Cannot exact print HoleParseError" exact x@(HsOverLabel src l) = do printStringAdvanceA "#" >> return () case src of View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b0d3835532299357d8b1c29c69a68b1693de4af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b0d3835532299357d8b1c29c69a68b1693de4af You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 13:02:42 2025 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Tue, 14 Jan 2025 08:02:42 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25651 Message-ID: <678660725b962_386f504c41e03326@gitlab.mail> Ryan Scott pushed new branch wip/T25651 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25651 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 14 23:26:34 2025 From: gitlab at gitlab.haskell.org (Apoorv Ingle (@ani)) Date: Tue, 14 Jan 2025 18:26:34 -0500 Subject: [Git][ghc/ghc][wip/spj-apporv-Oct24] ignore OrigStmt in addArgCtx Message-ID: <6786f2aaa951_1a44e874084c14437@gitlab.mail> Apoorv Ingle pushed to branch wip/spj-apporv-Oct24 at Glasgow Haskell Compiler / GHC Commits: 04661ec1 by Apoorv Ingle at 2025-01-14T17:26:05-06:00 ignore OrigStmt in addArgCtx - - - - - 1 changed file: - compiler/GHC/Tc/Gen/App.hs Changes: ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -915,6 +915,8 @@ addArgCtxt ctxt (L arg_loc arg) thing_inside addErrCtxt (funAppCtxt fun arg arg_no) $ thing_inside + VAExpansion (OrigStmt{}) _ _ -> setSrcSpanA arg_loc $ + thing_inside -- Do nothing as we have pushed it already _ -> setSrcSpanA arg_loc $ addExprCtxt arg $ -- Auto-suppressed if arg_loc is generated thing_inside } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04661ec18c2f735ea1993da9e2f69958e65327cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04661ec18c2f735ea1993da9e2f69958e65327cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 15 01:38:53 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Tue, 14 Jan 2025 20:38:53 -0500 Subject: [Git][ghc/ghc][wip/T25623] Fix for alex-3.5.2 Message-ID: <678711ad4fcb9_1a44e8175d7e818375@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: dd942479 by Brandon Chinn at 2025-01-14T17:38:44-08:00 Fix for alex-3.5.2 - - - - - 1 changed file: - compiler/GHC/Parser/Lexer.x Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3467,10 +3468,12 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#if MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. {-# INLINE alexScanUser #-} +#endif lexToken :: P (PsLocated Token) lexToken = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dd942479a0a13cb8745061c35bff19a28da05fa7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dd942479a0a13cb8745061c35bff19a28da05fa7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 15 10:06:57 2025 From: gitlab at gitlab.haskell.org (=?UTF-8?B?TWF0ZXVzeiBHb8WbbGlub3dza2kgKEBTd29yZGxhc2gp?=) Date: Wed, 15 Jan 2025 05:06:57 -0500 Subject: [Git][ghc/ghc][wip/swordlash/allow_multiline_strings_in_js_ffi] 6 commits: Remove SDocs from ErrCtxt & ErrInfo Message-ID: <678788c1dfd7d_3e6e975105187539e@gitlab.mail> Mateusz Goślinowski pushed to branch wip/swordlash/allow_multiline_strings_in_js_ffi at Glasgow Haskell Compiler / GHC Commits: 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 1e39cb9a by Mateusz Goślinowski at 2025-01-15T10:06:51+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 9bcc95c2 by Mateusz Goślinowski at 2025-01-15T10:06:51+00:00 Add test for multiline imports - - - - - 9019f6da by Mateusz Goślinowski at 2025-01-15T10:06:51+00:00 Make tests actually multiline - - - - - 30 changed files: - compiler/GHC/Core/TyCon.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Infer.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Errors/Types/PromotionErr.hs - compiler/GHC/Tc/Gen/Annotation.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Export.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Gen/HsType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9788796542928716fc3c0186190080dbf5aa6bf9...9019f6da8e7ad1979238c8d33d3265ec849564e8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9788796542928716fc3c0186190080dbf5aa6bf9...9019f6da8e7ad1979238c8d33d3265ec849564e8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 15 10:08:52 2025 From: gitlab at gitlab.haskell.org (=?UTF-8?B?TWF0ZXVzeiBHb8WbbGlub3dza2kgKEBTd29yZGxhc2gp?=) Date: Wed, 15 Jan 2025 05:08:52 -0500 Subject: [Git][ghc/ghc][wip/swordlash/allow_multiline_strings_in_js_ffi] Allow multiline strings in JS FFI (#25633) Message-ID: <67878934afd36_3e6e974b46c87556@gitlab.mail> Mateusz Goślinowski pushed to branch wip/swordlash/allow_multiline_strings_in_js_ffi at Glasgow Haskell Compiler / GHC Commits: 4162ad45 by Mateusz Goślinowski at 2025-01-15T11:08:29+01:00 Allow multiline strings in JS FFI (#25633) - - - - - 5 changed files: - compiler/GHC/Parser.y - docs/users_guide/9.14.1-notes.rst - + testsuite/tests/javascript/T25633.hs - + testsuite/tests/javascript/T25633.stdout - testsuite/tests/javascript/all.T Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -2148,6 +2148,9 @@ fspec :: { Located (TokDcolon : STRING var '::' sigtype { sLL $1 $> (epUniTok $3 ,(L (getLoc $1) (getStringLiteral $1), $2, $4)) } + | STRING_MULTI var '::' sigtype { sLL $1 $> (epUniTok $3 + ,(L (getLoc $1) + (getStringMultiLiteral $1), $2, $4)) } | var '::' sigtype { sLL $1 $> (epUniTok $2 ,(noLoc (StringLiteral NoSourceText nilFS Nothing), $1, $3)) } -- if the entity string is missing, it defaults to the empty string; @@ -4247,6 +4250,7 @@ getINCOHERENT_PRAGs (L _ (ITincoherent_prag src)) = src getCTYPEs (L _ (ITctype src)) = src getStringLiteral l = StringLiteral (getSTRINGs l) (getSTRING l) Nothing +getStringMultiLiteral l = StringLiteral (getSTRINGMULTIs l) (getSTRINGMULTI l) Nothing isUnicode :: Located Token -> Bool isUnicode (L _ (ITforall iu)) = iu == UnicodeSyntax ===================================== docs/users_guide/9.14.1-notes.rst ===================================== @@ -38,6 +38,8 @@ Language That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`. +* Multiline strings are now accepted in foreign imports. (#25157) + Compiler ~~~~~~~~ ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE MultilineStrings #-} +module Main where + +import GHC.Prim +import GHC.JS.Prim +import Foreign.C +import System.IO + +foreign import javascript + """ + ((x) => x) + """ + toJSDouble :: Double -> JSVal + +foreign import javascript + """ + (function (x) { + console.log(x); + }) + """ + multiLog :: JSVal -> IO () + +foreign import javascript + """ + ((x) => + x + "" + ) + """ + jsToString :: JSVal -> JSVal + +foreign import ccall + """ + cos + """ mycos :: CDouble -> CDouble + +main :: IO () +main = do + hSetBuffering stdout NoBuffering + + multiLog $ toJSInt 5 + multiLog $ toJSString "Hello" + putStrLn $ fromJSString $ jsToString $ toJSInt (- 5) + multiLog $ jsToString $ toJSDouble 3.0 + print $ mycos 0 == 1 \ No newline at end of file ===================================== testsuite/tests/javascript/T25633.stdout ===================================== @@ -0,0 +1,5 @@ +5 +Hello +-5 +3 +True \ No newline at end of file ===================================== testsuite/tests/javascript/all.T ===================================== @@ -25,3 +25,5 @@ test('T24495', normal, makefile_test, ['T24495']) test('T23479', normal, makefile_test, ['T23479']) test('T24744', normal, makefile_test, ['T24744']) + +test('T25633', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4162ad45ce1f573efd468b605ceea8e922f6b5d3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4162ad45ce1f573efd468b605ceea8e922f6b5d3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 15 17:29:32 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Wed, 15 Jan 2025 12:29:32 -0500 Subject: [Git][ghc/ghc][wip/T25623] Fix for alex-3.5.2 Message-ID: <6787f07c30482_deff7aa55a0130fe@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 878974d3 by Brandon Chinn at 2025-01-15T09:29:22-08:00 Fix for alex-3.5.2 - - - - - 1 changed file: - compiler/GHC/Parser/Lexer.x Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3467,10 +3468,12 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. {-# INLINE alexScanUser #-} +#endif lexToken :: P (PsLocated Token) lexToken = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/878974d3ba379f346e397cc1871914e6cec6c5ee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/878974d3ba379f346e397cc1871914e6cec6c5ee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 15 18:26:36 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 15 Jan 2025 13:26:36 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Re CLC #300 - Specify fmap for NonEmpty as map Message-ID: <6787fddc3af80_133b29568efc2125f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 1f2c72de by amesgen at 2025-01-15T13:26:30-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 30 changed files: - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - docs/users_guide/using-optimisation.rst - libraries/base/changelog.md - libraries/base/src/Data/List/NonEmpty.hs - libraries/base/src/Data/Semigroup.hs - libraries/base/src/GHC/Base.hs - libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/src/GHC/Internal/Base.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Fix.hs - libraries/ghc-internal/src/GHC/Internal/Control/Monad/Zip.hs - libraries/ghc-internal/src/GHC/Internal/Data/Data.hs - libraries/ghc-internal/src/GHC/Internal/Data/Foldable.hs - libraries/ghc-internal/src/GHC/Internal/Data/List/NonEmpty.hs - + libraries/ghc-internal/src/GHC/Internal/Data/NonEmpty.hs - libraries/ghc-internal/src/GHC/Internal/Data/Traversable.hs - libraries/ghc-internal/src/GHC/Internal/Generics.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs - libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs - libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs - libraries/ghc-internal/src/GHC/Internal/Text/ParserCombinators/ReadP.hs - + testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs - + testsuite/tests/indexed-types/should_compile/T25611a.hs - + testsuite/tests/indexed-types/should_compile/T25611b.hs - testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.hs → testsuite/tests/indexed-types/should_compile/T25611c.hs - + testsuite/tests/indexed-types/should_compile/T25611d.hs - testsuite/tests/indexed-types/should_compile/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/810bb35119a7ae69007e7f0e83810180541f0ce8...1f2c72de016016a10ecd85e8a1df3fa0d84d24cd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/810bb35119a7ae69007e7f0e83810180541f0ce8...1f2c72de016016a10ecd85e8a1df3fa0d84d24cd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 15 23:47:08 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 15 Jan 2025 18:47:08 -0500 Subject: [Git][ghc/ghc][master] Enhance kind inference for data family instances Message-ID: <678848fc6a091_1ee1dc75fe54681bd@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - 13 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - + testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs - + testsuite/tests/indexed-types/should_compile/T25611a.hs - + testsuite/tests/indexed-types/should_compile/T25611b.hs - testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.hs → testsuite/tests/indexed-types/should_compile/T25611c.hs - + testsuite/tests/indexed-types/should_compile/T25611d.hs - testsuite/tests/indexed-types/should_compile/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2468,7 +2469,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3921,14 +3922,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1140,7 +1140,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1257,7 +1257,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2128,7 +2128,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2223,14 +2223,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -715,7 +716,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env ; skol_info <- mkSkolemInfo FamInstSkol ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -740,8 +741,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -919,8 +919,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -928,7 +927,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -944,16 +943,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1005,9 +1005,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1033,6 +1040,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1187,31 +1209,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_compile/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/indexed-types/should_compile/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.hs → testsuite/tests/indexed-types/should_compile/T25611c.hs ===================================== @@ -6,7 +6,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE GADTs #-} -module UnliftedNewtypesUnassociatedFamily where +module T25611c where import GHC.Int (Int(I#)) import GHC.Word (Word(W#)) @@ -15,9 +15,15 @@ import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) data family DF :: TYPE (r :: RuntimeRep) --- All these fail: see #18891 and !4419 +-- it used to be failed: see #18891 and !4419 -- See Note [Kind inference for data family instances] -- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 newtype instance DF = MkDF1a Int# newtype instance DF = MkDF2a Word# newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/indexed-types/should_compile/T25611d.hs ===================================== @@ -0,0 +1,38 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,8 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype family instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,8 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • In the associated newtype family instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the associated newtype family instance declaration for ‘Bar’ ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype family instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype family instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype family instance declaration for ‘DF’ - ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d9cacd5b09019c4ce2ccea9a509220bb44e36a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d9cacd5b09019c4ce2ccea9a509220bb44e36a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 15 23:47:48 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 15 Jan 2025 18:47:48 -0500 Subject: [Git][ghc/ghc][master] wasm: prevent bundlers from resolving import("node:timers") Message-ID: <67884924205f8_1ee1dc6e797c71120@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 1 changed file: - utils/jsffi/prelude.mjs Changes: ===================================== utils/jsffi/prelude.mjs ===================================== @@ -63,7 +63,9 @@ const setImmediate = await (async () => { // deno if (globalThis.Deno) { - return (await import("node:timers")).setImmediate; + try { + return (await import("node:timers")).setImmediate; + } catch {} } // https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f6493dbccc7bf95dcdf946b978e262f739e3e15a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f6493dbccc7bf95dcdf946b978e262f739e3e15a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 16 08:26:21 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 16 Jan 2025 03:26:21 -0500 Subject: [Git][ghc/ghc][wip/T24359] WIP on a different approach [skip ci] Message-ID: <6788c2ad4aac4_39ee436a3f4c5628b@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 61d8ab31 by Simon Peyton Jones at 2025-01-16T08:25:49+00:00 WIP on a different approach [skip ci] - - - - - 1 changed file: - compiler/GHC/Tc/Solver/Monad.hs Changes: ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -824,6 +824,8 @@ added. This is initialised from the innermost implication constraint. data TcSEnv = TcSEnv { + tcs_mode :: TcSMode, + tcs_ev_binds :: EvBindsVar, tcs_unified :: IORef Int, @@ -841,15 +843,25 @@ data TcSEnv tcs_inerts :: IORef InertSet, -- Current inert set - -- Whether to throw an exception if we come across an insoluble constraint. - -- Used to fail-fast when checking for hole-fits. See Note [Speeding up - -- valid hole-fits]. - tcs_abort_on_insoluble :: Bool, - -- See Note [WorkList priorities] in GHC.Tc.Solver.InertSet tcs_worklist :: IORef WorkList -- Current worklist } +data TcSMode + = TcSVanilla + + | TcSHoleFits -- See Note [Speeding up valid hole-fits]. + -- In this moe we throw an exception if we come across an + -- insoluble constraint, to fail-fast when checking for hole-fits. + + | TcSSpecPrag -- Don't use instance declarations or upack forall constraints + -- when simplifying a SPECIALISE pragma + +instance Outputable TcSMode where + ppr TcSVanilla = text "TcSVanilla" + ppr TcSHoleFits = text "TcSHoleFits" + ppr TcSSpecPrag = text "TcSSpecPrag" + --------------- newtype TcS a = TcS { unTcS :: TcSEnv -> TcM a } deriving (Functor) @@ -917,10 +929,8 @@ warnTcS msg = wrapTcS (TcM.addDiagnostic msg) addErrTcS = wrapTcS . TcM.addErr panicTcS doc = pprPanic "GHC.Tc.Solver.Monad" doc -tryEarlyAbortTcS :: TcS () --- Abort (fail in the monad) if the abort_on_insoluble flag is on -tryEarlyAbortTcS - = mkTcS (\env -> when (tcs_abort_on_insoluble env) TcM.failM) +getModeTcS :: TcS TcSMode +getModeTcS = mkTcS (\env -> return (tcs_mode env)) -- | Emit a warning within the 'TcS' monad at the location given by the 'CtLoc'. ctLocWarnTcS :: CtLoc -> TcRnMessage -> TcS () @@ -990,7 +1000,7 @@ runTcS tcs runTcSEarlyAbort :: TcS a -> TcM a runTcSEarlyAbort tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; runTcSWithEvBinds' True True ev_binds_var tcs } + ; runTcSWithEvBinds' True TcSHoleFits ev_binds_var tcs } -- | This can deal only with equality constraints. runTcSEqualities :: TcS a -> TcM a @@ -1012,29 +1022,29 @@ runTcSInerts inerts tcs = do runTcSWithEvBinds :: EvBindsVar -> TcS a -> TcM a -runTcSWithEvBinds = runTcSWithEvBinds' True False +runTcSWithEvBinds = runTcSWithEvBinds' True TcSVanilla runTcSWithEvBinds' :: Bool -- ^ Restore type variable cycles afterwards? -- Don't if you want to reuse the InertSet. -- See also Note [Type equality cycles] -- in GHC.Tc.Solver.Equality - -> Bool + -> TcSMode -> EvBindsVar -> TcS a -> TcM a -runTcSWithEvBinds' restore_cycles abort_on_insoluble ev_binds_var tcs +runTcSWithEvBinds' restore_cycles mode ev_binds_var tcs = do { unified_var <- TcM.newTcRef 0 ; step_count <- TcM.newTcRef 0 ; inert_var <- TcM.newTcRef emptyInert ; wl_var <- TcM.newTcRef emptyWorkList ; unif_lvl_var <- TcM.newTcRef Nothing - ; let env = TcSEnv { tcs_ev_binds = ev_binds_var - , tcs_unified = unified_var - , tcs_unif_lvl = unif_lvl_var - , tcs_count = step_count - , tcs_inerts = inert_var - , tcs_abort_on_insoluble = abort_on_insoluble - , tcs_worklist = wl_var } + ; let env = TcSEnv { tcs_mode = mode + , tcs_ev_binds = ev_binds_var + , tcs_unified = unified_var + , tcs_unif_lvl = unif_lvl_var + , tcs_count = step_count + , tcs_inerts = inert_var + , tcs_worklist = wl_var } -- Run the computation ; res <- unTcS tcs env @@ -1091,12 +1101,7 @@ nestImplicTcS :: EvBindsVar -> TcLevel -> TcS a -> TcS a nestImplicTcS ref inner_tclvl (TcS thing_inside) - = TcS $ \ TcSEnv { tcs_unified = unified_var - , tcs_inerts = old_inert_var - , tcs_count = count - , tcs_unif_lvl = unif_lvl - , tcs_abort_on_insoluble = abort_on_insoluble - } -> + = TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var } -> do { inerts <- TcM.readTcRef old_inert_var ; let nest_inert = inerts { inert_cycle_breakers = pushCycleBreakerVarStack (inert_cycle_breakers inerts) @@ -1105,13 +1110,9 @@ nestImplicTcS ref inner_tclvl (TcS thing_inside) -- All other InertSet fields are inherited ; new_inert_var <- TcM.newTcRef nest_inert ; new_wl_var <- TcM.newTcRef emptyWorkList - ; let nest_env = TcSEnv { tcs_count = count -- Inherited - , tcs_unif_lvl = unif_lvl -- Inherited - , tcs_ev_binds = ref - , tcs_unified = unified_var - , tcs_inerts = new_inert_var - , tcs_abort_on_insoluble = abort_on_insoluble - , tcs_worklist = new_wl_var } + ; let nest_env = env { tcs_ev_binds = ref + , tcs_inerts = new_inert_var + , tcs_worklist = new_wl_var } ; res <- TcM.setTcLevel inner_tclvl $ thing_inside nest_env View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61d8ab31312dfbefde1ccce3032749d5fb29872c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/61d8ab31312dfbefde1ccce3032749d5fb29872c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 16 10:11:42 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 16 Jan 2025 05:11:42 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] 2 commits: wasm: prevent bundlers from resolving import("node:timers") Message-ID: <6788db5e40ddd_1ce44416781052fb@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - faeda39e by Patrick at 2025-01-16T18:10:43+08:00 update kcConDecl to also consider the result type in newtype GADT instance - - - - - 2 changed files: - compiler/GHC/Tc/TyCl.hs - utils/jsffi/prelude.mjs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1865,7 +1865,7 @@ kcConDecl new_or_data tc_res_kind -- because that's done in tcConDecl } -kcConDecl new_or_data _tc_res_kind +kcConDecl new_or_data tc_res_kind -- NB: _tc_res_kind is unused. See (KCD3) in -- Note [kcConDecls: kind-checking data type decls] (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs @@ -1878,9 +1878,10 @@ kcConDecl new_or_data _tc_res_kind -- Why "_Tv"? See Note [Using TyVarTvs for kind-checking GADTs] do { _ <- tcHsContext cxt ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) - ; con_res_kind <- newOpenTypeKind - ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - + ; con_res_kind <- if NewType == new_or_data + then return tc_res_kind + else newOpenTypeKind + ; _ <- tcCheckLHsTypeInContext res_ty $ (TheKind con_res_kind) ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind -- getArgExpKind: for newtypes, check that the argument kind -- is the same the kind of `res_ty`, the data con's return type @@ -4685,6 +4686,7 @@ checkValidDataCon dflags existential_ok tc con res_ty_tmpl = mkFamilyTyConApp tc (mkTyVarTys tc_tvs) arg_tys = dataConOrigArgTys con orig_res_ty = dataConOrigResTy con + -- dc_eq_spec = dcEqSpec con ; traceTc "checkValidDataCon" (vcat [ ppr con, ppr tc, ppr tc_tvs @@ -4853,7 +4855,9 @@ checkNewDataCon con ; checkNoErrs $ -- Fail here if the newtype is invalid: subsequent code in -- checkValidDataCon can fall over if it comes across an invalid newtype. - do { case arg_tys of + do { + traceTc "checkNewDataCon > eq_spec:" (ppr eq_spec) + ; case arg_tys of [Scaled arg_mult _] -> unless (ok_mult arg_mult) $ addErrTc $ ===================================== utils/jsffi/prelude.mjs ===================================== @@ -63,7 +63,9 @@ const setImmediate = await (async () => { // deno if (globalThis.Deno) { - return (await import("node:timers")).setImmediate; + try { + return (await import("node:timers")).setImmediate; + } catch {} } // https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fcdf16e591743af1a358bbcc5727662102a4f653...faeda39ee025550473f077b32edca36c8c763d89 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fcdf16e591743af1a358bbcc5727662102a4f653...faeda39ee025550473f077b32edca36c8c763d89 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 16 13:08:04 2025 From: gitlab at gitlab.haskell.org (Ryan Scott (@RyanGlScott)) Date: Thu, 16 Jan 2025 08:08:04 -0500 Subject: [Git][ghc/ghc][wip/T25651] 3 commits: Enhance kind inference for data family instances Message-ID: <678904b444f56_9d4a23f3fe080830@gitlab.mail> Ryan Scott pushed to branch wip/T25651 at Glasgow Haskell Compiler / GHC Commits: 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 50940a2f by Ryan Scott at 2025-01-16T08:07:53-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 15 changed files: - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - testsuite/tests/backpack/should_fail/T19244a.stderr - testsuite/tests/ghci/scripts/T9881.stdout - + testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs - + testsuite/tests/indexed-types/should_compile/T25611a.hs - + testsuite/tests/indexed-types/should_compile/T25611b.hs - testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.hs → testsuite/tests/indexed-types/should_compile/T25611c.hs - + testsuite/tests/indexed-types/should_compile/T25611d.hs - testsuite/tests/indexed-types/should_compile/all.T - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c9920431542503cc9746f0c7923dada4ad418f96...50940a2f01654cb6a29f2064f2333fdc157824cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c9920431542503cc9746f0c7923dada4ad418f96...50940a2f01654cb6a29f2064f2333fdc157824cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 16 16:35:31 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Thu, 16 Jan 2025 11:35:31 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] peek at the result kind Message-ID: <6789355393b53_1058139550b03924e@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 726e509f by Patrick at 2025-01-17T00:35:16+08:00 peek at the result kind - - - - - 2 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -75,6 +75,7 @@ module GHC.Tc.Gen.HsType ( -- Utils tyLitFromLit, tyLitFromOverloadedLit, + getTyConResultKind ) where @@ -3947,6 +3948,12 @@ needsEtaExpansion DataTypeFlavour = True needsEtaExpansion ClassFlavour = True needsEtaExpansion _ = False +getTyConResultKind :: Kind -> TcKind +getTyConResultKind kind + = case splitPiTy_maybe kind of + Just (_, kind') -> getTyConResultKind kind' + Nothing -> kind + splitTyConKind :: SkolemInfo -> InScopeSet -> [OccName] -- Avoid these OccNames ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1877,9 +1877,9 @@ kcConDecl new_or_data tc_res_kind bindOuterSigTKBndrs_Tv outer_bndrs $ -- Why "_Tv"? See Note [Using TyVarTvs for kind-checking GADTs] do { _ <- tcHsContext cxt - ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) + ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty $$ ppr tc_res_kind) ; con_res_kind <- if NewType == new_or_data - then return tc_res_kind + then return $ getTyConResultKind tc_res_kind else newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty $ (TheKind con_res_kind) ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/726e509fab32d4bee45742b1596e30bfff47354c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/726e509fab32d4bee45742b1596e30bfff47354c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 16 21:39:05 2025 From: gitlab at gitlab.haskell.org (=?UTF-8?B?TWF0ZXVzeiBHb8WbbGlub3dza2kgKEBTd29yZGxhc2gp?=) Date: Thu, 16 Jan 2025 16:39:05 -0500 Subject: [Git][ghc/ghc][wip/swordlash/allow_multiline_strings_in_js_ffi] 3 commits: Enhance kind inference for data family instances Message-ID: <67897c7955cef_1bd0e44e02781051a5@gitlab.mail> Mateusz Goślinowski pushed to branch wip/swordlash/allow_multiline_strings_in_js_ffi at Glasgow Haskell Compiler / GHC Commits: 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 7b65a352 by Mateusz Goślinowski at 2025-01-16T21:38:54+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 19 changed files: - compiler/GHC/Parser.y - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - docs/users_guide/9.14.1-notes.rst - + testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs - + testsuite/tests/indexed-types/should_compile/T25611a.hs - + testsuite/tests/indexed-types/should_compile/T25611b.hs - testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.hs → testsuite/tests/indexed-types/should_compile/T25611c.hs - + testsuite/tests/indexed-types/should_compile/T25611d.hs - testsuite/tests/indexed-types/should_compile/all.T - + testsuite/tests/javascript/T25633.hs - + testsuite/tests/javascript/T25633.stdout - testsuite/tests/javascript/all.T - testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr - testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr - − testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr - testsuite/tests/typecheck/should_fail/all.T - utils/jsffi/prelude.mjs Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -2148,6 +2148,9 @@ fspec :: { Located (TokDcolon : STRING var '::' sigtype { sLL $1 $> (epUniTok $3 ,(L (getLoc $1) (getStringLiteral $1), $2, $4)) } + | STRING_MULTI var '::' sigtype { sLL $1 $> (epUniTok $3 + ,(L (getLoc $1) + (getStringMultiLiteral $1), $2, $4)) } | var '::' sigtype { sLL $1 $> (epUniTok $2 ,(noLoc (StringLiteral NoSourceText nilFS Nothing), $1, $3)) } -- if the entity string is missing, it defaults to the empty string; @@ -4247,6 +4250,7 @@ getINCOHERENT_PRAGs (L _ (ITincoherent_prag src)) = src getCTYPEs (L _ (ITctype src)) = src getStringLiteral l = StringLiteral (getSTRINGs l) (getSTRING l) Nothing +getStringMultiLiteral l = StringLiteral (getSTRINGMULTIs l) (getSTRINGMULTI l) Nothing isUnicode :: Located Token -> Bool isUnicode (L _ (ITforall iu)) = iu == UnicodeSyntax ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -42,7 +42,8 @@ module GHC.Tc.Gen.HsType ( -- Type checking type and class decls, and instances thereof bindTyClTyVars, bindTyClTyVarsAndZonk, tcFamTyPats, - etaExpandAlgTyCon, tcbVisibilities, + maybeEtaExpandAlgTyCon, tcbVisibilities, + etaExpandAlgTyCon, -- tyvars zonkAndScopedSort, @@ -2468,7 +2469,7 @@ kcCheckDeclHeader_cusk name flav ++ map (mkExplicitTyConBinder mentioned_kv_set) tc_bndrs -- Eta expand if necessary; we are building a PolyTyCon - ; (eta_tcbs, res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs res_kind + ; (eta_tcbs, res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs res_kind ; let all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ binderVars tc_bndrs) final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -3921,14 +3922,20 @@ Hence using zonked_kinds when forming tvs'. -} ----------------------------------- -etaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo +maybeEtaExpandAlgTyCon :: TyConFlavour tc -> SkolemInfo -> [TcTyConBinder] -> Kind -> TcM ([TcTyConBinder], Kind) -etaExpandAlgTyCon flav skol_info tcbs res_kind +maybeEtaExpandAlgTyCon flav skol_info tcbs res_kind | needsEtaExpansion flav - = splitTyConKind skol_info in_scope avoid_occs res_kind + = etaExpandAlgTyCon skol_info tcbs res_kind | otherwise = return ([], res_kind) + +etaExpandAlgTyCon :: SkolemInfo + -> [TcTyConBinder] -> Kind + -> TcM ([TcTyConBinder], Kind) +etaExpandAlgTyCon skol_info tcbs res_kind + = splitTyConKind skol_info in_scope avoid_occs res_kind where tyvars = binderVars tcbs in_scope = mkInScopeSetList tyvars ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1140,7 +1140,7 @@ generaliseTcTyCon (tc, skol_info, scoped_prs, tc_res_kind) flav = tyConFlavour tc -- Eta expand - ; (eta_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind + ; (eta_tcbs, tc_res_kind) <- maybeEtaExpandAlgTyCon flav skol_info all_tcbs tc_res_kind -- Step 6: Make the result TcTyCon ; let final_tcbs = all_tcbs `chkAppend` eta_tcbs @@ -1257,7 +1257,7 @@ paths for Note that neither code path worries about point (4) above, as this is nicely handled by not mangling the res_kind. (Mangling res_kinds is done -*after* all this stuff, in tcDataDefn's call to etaExpandAlgTyCon.) +*after* all this stuff, in tcDataDefn's call to maybeEtaExpandAlgTyCon.) We can tell Inferred apart from Specified by looking at the scoped tyvars; Specified are always included there. @@ -2128,7 +2128,7 @@ DT3 Eta-expansion: Any forall-bound variables and function arguments in a result data T a :: Type -> Type where ... we really mean for T to have two parameters. The second parameter - is produced by processing the return kind in etaExpandAlgTyCon, + is produced by processing the return kind in maybeEtaExpandAlgTyCon, called in tcDataDefn. See also Note [splitTyConKind] in GHC.Tc.Gen.HsType. @@ -2223,14 +2223,20 @@ DF0 Where these kinds come from: Type. This assumption is in getInitialKind for CUSKs or get_fam_decl_initial_kind for non-signature & non-CUSK cases. - Instances: The data family already has a known kind. The return kind - of an instance is then calculated by applying the data family tycon - to the patterns provided, as computed by the typeKind lhs_ty in the - end of tcDataFamInstHeader. In the case of an instance written in GADT - syntax, there are potentially *two* return kinds: the one computed from - applying the data family tycon to the patterns, and the one given by - the user. This second kind is checked by the tc_kind_sig function within - tcDataFamInstHeader. See also DF3, below. + Instances: There are potentially *two* return kinds: + * Master kind: + The data family already has a known kind. The return kind of an instance + is then calculated by applying the data family tycon to the patterns + provided, as computed by the `tcFamTyPats fam_tc hs_pats` in the + tcDataFamInstHeader. + * Instance kind: + The kind specified by the user in GADT syntax. If H98 syntax is used, + with UnliftedNewtypes/UnliftedDatatypes, it defaults to newOpenTypeKind + for newtypes/datatypes, otherwise it defaults to liftedTypeKind. + This is checked or defaulted by the tc_kind_sig function within + tcDataFamInstHeader. Defaulting can be tricky for some cases, + See Note [Defaulting result kind of newtype/data family instance]. + See also DF3, below. DF1 In a data/newtype instance, we treat the kind of the /data family/, once instantiated, as the "master kind" for the representation ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -715,7 +716,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env ; skol_info <- mkSkolemInfo FamInstSkol ; (qtvs, non_user_tvs, pats, tc_res_kind, stupid_theta) <- tcDataFamInstHeader mb_clsinfo skol_info fam_tc outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons -- Eta-reduce the axiom if possible -- Quite tricky: see Note [Implementing eta reduction for data families] @@ -740,8 +741,7 @@ tcDataFamInstDecl mb_clsinfo tv_skol_env -- we did it before the "extra" tvs from etaExpandAlgTyCon -- would always be eta-reduced -- - ; let flav = newOrDataToFlavour new_or_data - ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon flav skol_info full_tcbs tc_res_kind + ; (extra_tcbs, tc_res_kind) <- etaExpandAlgTyCon skol_info full_tcbs tc_res_kind -- Check the result kind; it may come from a user-written signature. -- See Note [Datatype return kinds] in GHC.Tc.TyCl point 4(a) @@ -919,8 +919,7 @@ TyVarEnv will simply be empty, and there is nothing to worry about. tcDataFamInstHeader :: AssocInstInfo -> SkolemInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> Maybe (LHsContext GhcRn) - -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) - -> NewOrData + -> HsFamEqnPats GhcRn -> Maybe (LHsKind GhcRn) -> DataDefnCons (LConDecl GhcRn) -> TcM ([TcTyVar], TyVarSet, [TcType], TcKind, TcThetaType) -- All skolem TcTyVars, all zonked so it's clear what the free vars are -- The "header" of a data family instance is the part other than @@ -928,7 +927,7 @@ tcDataFamInstHeader -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where" tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity - hs_ctxt hs_pats m_ksig new_or_data + hs_ctxt hs_pats m_ksig hs_cons = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats) ; (tclvl, wanted, (outer_bndrs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $ @@ -944,16 +943,17 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- with its parent class ; addConsistencyConstraints mb_clsinfo lhs_ty - -- Add constraints from the result signature - ; res_kind <- tc_kind_sig m_ksig - - -- Do not add constraints from the data constructors - -- See Note [Kind inference for data family instances] + -- Add constraints from the data constructors + -- Fix #25611 + -- See DESIGN CHOICE in Note [Kind inference for data family instances] + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there -- is none) ; let hs_lhs = nlHsTyConApp NotPromoted fixity (getName fam_tc) hs_pats + -- Add constraints from the result signature + ; res_kind <- tc_kind_sig m_ksig ; _ <- unifyKind (Just . HsTypeRnThing $ unLoc hs_lhs) lhs_applied_kind res_kind ; traceTc "tcDataFamInstHeader" $ @@ -1005,9 +1005,16 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity where fam_name = tyConName fam_tc data_ctxt = DataKindCtxt fam_name + new_or_data = dataDefnConsNewOrData hs_cons + is_H98_or_newtype = case hs_cons of + NewTypeCon{} -> True + DataTypeCons _ cons -> all isH98 cons + isH98 (L _ (ConDeclH98 {})) = True + isH98 _ = False -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, families (2), - -- and Note [Implementation of UnliftedDatatypes]. + -- Note [Implementation of UnliftedDatatypes] + -- and Note [Defaulting result kind of newtype/data family instance]. tc_kind_sig Nothing = do { unlifted_newtypes <- xoptM LangExt.UnliftedNewtypes ; unlifted_datatypes <- xoptM LangExt.UnliftedDatatypes @@ -1033,6 +1040,21 @@ we actually have a place to put the regeneralised variables. Thus: skolemise away. cf. GHC.Tc.Utils.Unify.tcTopSkolemise Examples in indexed-types/should_compile/T12369 +Note [Defaulting result kind of newtype/data family instance] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is tempting to let `tc_kind_sig` just return `newOpenTypeKind` +even without `-XUnliftedNewtypes`, but we rely on `tc_kind_sig` to +constrain the result kind of a newtype instance to `Type`. +Consider the following example: + + -- no UnliftedNewtypes + data family D :: k -> k + newtype instance D a = MkIntD a + +`tc_kind_sig` defaulting to `newOpenTypeKind` would result in `D a` +having kind `forall r. TYPE r` instead of `Type`, which would be +rejected validity checking. The same applies to Data Instances. + Note [Implementing eta reduction for data families] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider @@ -1187,31 +1209,48 @@ kind -- that came from the family declaration, and is not influenced by the data instances -- and hence we /can/ specialise T's kind differently in different GADT data constructors. -SHORT SUMMARY: in a data instance decl, it's not clear whether kind +SHORT SUMMARY: In a data instance decl, it's not clear whether kind constraints arising from the data constructors should be considered local to the (GADT) data /constructor/ or should apply to the entire data instance. -DESIGN CHOICE: in data/newtype family instance declarations, we ignore -the /data constructor/ declarations altogether, looking only at the -data instance /header/. +DESIGN CHOICE: In a data/newtype family instance declaration: +* We take account of the data constructors (via `kcConDecls`) for: + * Haskell-98 style data instance declarations + * All newtype instance declarations + For Haskell-98 style declarations, there is no GADT refinement. And for + GADT-style newtype declarations, no GADT matching is allowed anyway, + so it's just a syntactic difference from Haskell-98. -Observations: -* This choice is simple to describe, as well as simple to implement. - For a data/newtype instance decl, the instance kinds are influenced - /only/ by the header. - -* We could treat Haskell-98 style data-instance decls differently, by - taking the data constructors into account, since there are no GADT - issues. But we don't, for simplicity, and because it means you can - understand the data type instance by looking only at the header. +* We /ignore/ the data constructors for: + * GADT-style data instance declarations + Here, the instance kinds are influenced only by the header. -* Newtypes can be declared in GADT syntax, but they can't do GADT-style - specialisation, so like Haskell-98 definitions we could take the - data constructors into account. Again we don't, for the same reason. +This choice is implemented by the guarded call to `kcConDecls` in +`tcDataFamInstHeader`. -So for now at least, we keep the simplest choice. See #18891 and !4419 -for more discussion of this issue. +Observations: +* With `UnliftedNewtypes` or `UnliftedDatatypes`, looking at the data + constructors is necessary to infer the kind of the result type for + certain cases. Otherwise, additional kind signatures are required. + Consider the following example in #25611: + + data family Fix :: (k -> Type) -> k + newtype instance Fix f = In { out :: f (Fix f) } + + If we are not looking at the data constructors: + * Without `UnliftedNewtypes`, it is accepted since `Fix f` is defaulted + to `Type`. + * But with `UnliftedNewtypes`, `Fix f` is defaulted to `TYPE r` where + `r` is not scoped over the data constructor. Then the header `Fix f :: TYPE r` + will fail to kind unify with `f (Fix f) :: Type`. + + Hence, we need to look at the data constructor to infer `Fix f :: Type` + for this newtype instance. + +This DESIGN CHOICE strikes a balance between well-rounded kind inference +and implementation simplicity. See #25611, #18891, and !4419 for more +discussion of this issue. Kind inference for data types (Xie et al) https://arxiv.org/abs/1911.06153 takes a slightly different approach. ===================================== docs/users_guide/9.14.1-notes.rst ===================================== @@ -38,6 +38,8 @@ Language That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`. +* Multiline strings are now accepted in foreign imports. (#25157) + Compiler ~~~~~~~~ ===================================== testsuite/tests/indexed-types/should_compile/DataInstanceKindsDefaults.hs ===================================== @@ -0,0 +1,26 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds #-} + +module DataInstanceKindsDefaults where + +import Data.Kind + +-- This test checks if we default the kind of the data instance correctly without UnliftedNewtypes +-- or UnliftedDatatypes. +-- Assumptions: +-- If we default the result kind of the data instance to `TYPE r`, +-- then `checkNewDataCon` would through the error since the result kind of the data instance +-- should be `Type` without UnliftedNewtypes or UnliftedDatatypes. + +data family A :: k -> k +newtype instance A a = MkA a + +data family B :: k -> k +data instance B a = MkB a + +data family C :: k -> k +data instance C a where MkC :: a -> C a + +data family D :: k -> k +newtype instance D a where MkD :: a -> D a + ===================================== testsuite/tests/indexed-types/should_compile/T25611a.hs ===================================== @@ -0,0 +1,17 @@ +{-# language DataKinds, PolyKinds, GADTs, TypeFamilies, RankNTypes, + TypeOperators, ConstraintKinds, UnliftedNewtypes #-} + +module T25611a where + +import Data.Kind + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 newtype instance case + +data family Fix0 :: (k -> Type) -> k +newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } + +-- This is the GADT newtype instance case +-- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` +-- data family Fix2 :: (k -> Type) -> k +-- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/indexed-types/should_compile/T25611b.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE UnliftedDatatypes #-} + +module T25611b where + +import GHC.Base (Type, TYPE, RuntimeRep (IntRep, BoxedRep), Levity (Unlifted)) + + +-- Enhanced kind inference for data family instance in !13767 +-- this is the h98 data instance case + +data family V :: (k -> Type) -> k +data instance V f = MkV (f (TYPE (BoxedRep 'Unlifted))) ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.hs → testsuite/tests/indexed-types/should_compile/T25611c.hs ===================================== @@ -6,7 +6,7 @@ {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE GADTs #-} -module UnliftedNewtypesUnassociatedFamily where +module T25611c where import GHC.Int (Int(I#)) import GHC.Word (Word(W#)) @@ -15,9 +15,15 @@ import GHC.Exts (TYPE,RuntimeRep(IntRep,WordRep,TupleRep)) data family DF :: TYPE (r :: RuntimeRep) --- All these fail: see #18891 and !4419 +-- it used to be failed: see #18891 and !4419 -- See Note [Kind inference for data family instances] -- in GHC.Tc.TyCl.Instance +-- but succ now see #25611 newtype instance DF = MkDF1a Int# newtype instance DF = MkDF2a Word# newtype instance DF = MkDF3a (# Int#, Word# #) + +go = 1 + where + x :: DF @IntRep + x = MkDF1a 3# ===================================== testsuite/tests/indexed-types/should_compile/T25611d.hs ===================================== @@ -0,0 +1,38 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE UnliftedNewtypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE MagicHash #-} + +module T25611d where + +import GHC.Int (Int(I#)) +import GHC.Word (Word(W#)) +import GHC.Exts (Int#,Word#) +import GHC.Types + +-- | A data family with a kind signature +data family T :: forall k. (k->v) -> k -> v +-- ensure the kind specialization is correctly handled in the GADT-style data instance +-- see Note [Kind inference for data family instances] +-- p will specialize differently in the two constructors +data instance T p q where + MkkT :: forall r. r Int -> T r Int + MkkV :: forall l. l Int# -> T l Int# + +type N :: TYPE r -> TYPE r +newtype N a = MkN a + +f :: Int# -> N Int# +f x = MkN x + +g :: Int -> N Int +g x = MkN x + +data family D :: Type -> k -> k +newtype instance D Int a = MkD a + +f1 :: Int# -> D Int Int# +f1 x = MkD x + +g1 :: Int -> D Int Int +g1 x = MkD x ===================================== testsuite/tests/indexed-types/should_compile/all.T ===================================== @@ -310,3 +310,8 @@ test('T22717', normal, makefile_test, ['T22717']) test('T22717_fam_orph', normal, multimod_compile, ['T22717_fam_orph', '-v0']) test('T23408', normal, compile, ['']) test('T24134', normal, compile, ['']) +test('DataInstanceKindsDefaults', normal, compile, ['']) +test('T25611a', normal, compile, ['']) +test('T25611b', normal, compile, ['']) +test('T25611c', normal, compile, ['']) +test('T25611d', normal, compile, ['']) ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE MultilineStrings #-} +module Main where + +import GHC.Prim +import GHC.JS.Prim +import Foreign.C +import System.IO + +foreign import javascript + """ + ((x) => x) + """ + toJSDouble :: Double -> JSVal + +foreign import javascript + """ + (function (x) { + console.log(x); + }) + """ + multiLog :: JSVal -> IO () + +foreign import javascript + """ + ((x) => + x + "" + ) + """ + jsToString :: JSVal -> JSVal + +foreign import ccall + """ + cos + """ mycos :: CDouble -> CDouble + +main :: IO () +main = do + hSetBuffering stdout NoBuffering + + multiLog $ toJSInt 5 + multiLog $ toJSString "Hello" + putStrLn $ fromJSString $ jsToString $ toJSInt (- 5) + multiLog $ jsToString $ toJSDouble 3.0 + print $ mycos 0 == 1 \ No newline at end of file ===================================== testsuite/tests/javascript/T25633.stdout ===================================== @@ -0,0 +1,5 @@ +5 +Hello +-5 +3 +True \ No newline at end of file ===================================== testsuite/tests/javascript/all.T ===================================== @@ -25,3 +25,5 @@ test('T24495', normal, makefile_test, ['T24495']) test('T23479', normal, makefile_test, ['T23479']) test('T24744', normal, makefile_test, ['T24744']) + +test('T25633', normal, compile_and_run, ['']) ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesFamilyKindFail2.stderr ===================================== @@ -5,3 +5,11 @@ UnliftedNewtypesFamilyKindFail2.hs:12:20: error: [GHC-83865] • In the first argument of ‘F’, namely ‘5’ In the newtype family instance declaration for ‘F’ +UnliftedNewtypesFamilyKindFail2.hs:12:31: [GHC-83865] + Expected a type, + but ‘5’ has kind + ‘GHC.Internal.Bignum.Natural.Natural’ + In the first argument of ‘F’, namely ‘5’ + In the type ‘(F 5)’ + In the definition of data constructor ‘MkF’ + ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesInstanceFail.stderr ===================================== @@ -3,3 +3,8 @@ UnliftedNewtypesInstanceFail.hs:13:3: error: [GHC-83865] • In the associated newtype family instance declaration for ‘Bar’ In the instance declaration for ‘Foo Bool’ +UnliftedNewtypesInstanceFail.hs:14:17: [GHC-83865] + Expected an IntRep type, but ‘Word#’ is a WordRep type + In the type ‘Word#’ + In the definition of data constructor ‘BarBoolC’ + In the associated newtype family instance declaration for ‘Bar’ ===================================== testsuite/tests/typecheck/should_fail/UnliftedNewtypesUnassociatedFamilyFail.stderr deleted ===================================== @@ -1,32 +0,0 @@ -UnliftedNewtypesUnassociatedFamilyFail.hs:21:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘IntRep’ - Expected a type, but ‘Int#’ has kind ‘TYPE IntRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:21:1-33 - • In the type ‘Int#’ - In the definition of data constructor ‘MkDF1a’ - In the newtype family instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:22:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘WordRep’ - Expected a type, but ‘Word#’ has kind ‘TYPE WordRep’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:22:1-34 - • In the type ‘Word#’ - In the definition of data constructor ‘MkDF2a’ - In the newtype family instance declaration for ‘DF’ - -UnliftedNewtypesUnassociatedFamilyFail.hs:23:30: error: [GHC-25897] - • Couldn't match kind ‘t’ with ‘TupleRep [IntRep, WordRep]’ - Expected a type, - but ‘(# Int#, Word# #)’ has kind ‘TYPE - (TupleRep [IntRep, WordRep])’ - ‘t’ is a rigid type variable bound by - a family instance declaration - at UnliftedNewtypesUnassociatedFamilyFail.hs:23:1-46 - • In the type ‘(# Int#, Word# #)’ - In the definition of data constructor ‘MkDF3a’ - In the newtype family instance declaration for ‘DF’ - ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -552,7 +552,6 @@ test('UnliftedNewtypesConstraintFamily', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKind', normal, compile_fail, ['']) test('UnliftedNewtypesMismatchedKindRecord', normal, compile_fail, ['']) test('UnliftedNewtypesMultiFieldGadt', normal, compile_fail, ['']) -test('UnliftedNewtypesUnassociatedFamilyFail', normal, compile_fail, ['']) test('T13834', normal, compile_fail, ['']) test('T17077', normal, compile_fail, ['']) test('T16512a', normal, compile_fail, ['']) ===================================== utils/jsffi/prelude.mjs ===================================== @@ -63,7 +63,9 @@ const setImmediate = await (async () => { // deno if (globalThis.Deno) { - return (await import("node:timers")).setImmediate; + try { + return (await import("node:timers")).setImmediate; + } catch {} } // https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4162ad45ce1f573efd468b605ceea8e922f6b5d3...7b65a3524e6d874bb4a25718b11d2c6810425f14 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4162ad45ce1f573efd468b605ceea8e922f6b5d3...7b65a3524e6d874bb4a25718b11d2c6810425f14 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 16 21:50:53 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 16 Jan 2025 16:50:53 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25654 Message-ID: <67897f3d1ed2e_1bd0e45e6e2410735@gitlab.mail> Ben Gamari pushed new branch wip/T25654 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25654 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 16 22:20:38 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 16 Jan 2025 17:20:38 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25653-9.12 Message-ID: <678986366e193_1dd6c41b9b4491813@gitlab.mail> Ben Gamari pushed new branch wip/T25653-9.12 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25653-9.12 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 16 22:20:41 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 16 Jan 2025 17:20:41 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25653 Message-ID: <67898639300a9_1dd6c42502ec92086@gitlab.mail> Ben Gamari pushed new branch wip/T25653 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25653 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 00:23:27 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Thu, 16 Jan 2025 19:23:27 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/ghc-9.12 Message-ID: <6789a2ff474f3_20ad119474d8722fb@gitlab.mail> Cheng Shao pushed new branch wip/ghc-9.12 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghc-9.12 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 00:23:55 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Thu, 16 Jan 2025 19:23:55 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/ghc-9.12 Message-ID: <6789a31be320_20ad119474d8724de@gitlab.mail> Cheng Shao deleted branch wip/ghc-9.12 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 07:11:10 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 17 Jan 2025 02:11:10 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] test if gadt has UserSuppliedResultKind in lhs, we let tc_res_kind to unify... Message-ID: <678a028ec9cba_33ee041ef7bc30683@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 58225725 by Patrick at 2025-01-17T15:10:56+08:00 test if gadt has UserSuppliedResultKind in lhs, we let tc_res_kind to unify with rhs result kind if not to gain more inference - - - - - 2 changed files: - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -14,8 +14,8 @@ -- | Typecheck type and class declarations module GHC.Tc.TyCl ( + UserSuppliedResultKind(..), tcTyAndClassDecls, - -- Functions used by GHC.Tc.TyCl.Instance to check -- data/type family instance declarations kcConDecls, tcConDecls, DataDeclInfo(..), @@ -1765,7 +1765,7 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) kcTyClDecl (DataDecl { tcdLName = (L _ _name) - , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons, dd_kindSig = kindSig } }) tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no @@ -1774,7 +1774,9 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name) -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) (if (isJust kindSig) + then UserSuppliedResultKind + else NoUserSuppliedResultKind) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1834,12 +1836,15 @@ kcConGADTArgs exp_kind con_args = case con_args of RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds +data UserSuppliedResultKind = UserSuppliedResultKind | NoUserSuppliedResultKind deriving Eq + kcConDecls :: TcKind -- Result kind of tycon -- Used only in H98 case + -> UserSuppliedResultKind -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls tc_res_kind cons - = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons +kcConDecls tc_res_kind usrk cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data usrk tc_res_kind)) cons where new_or_data = dataDefnConsNewOrData cons @@ -1848,8 +1853,8 @@ kcConDecls tc_res_kind cons -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () -kcConDecl new_or_data tc_res_kind +kcConDecl :: NewOrData -> UserSuppliedResultKind -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data _usrk tc_res_kind (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (DataConDefCtxt (NE.singleton name)) $ @@ -1865,7 +1870,7 @@ kcConDecl new_or_data tc_res_kind -- because that's done in tcConDecl } -kcConDecl new_or_data tc_res_kind +kcConDecl new_or_data usrk tc_res_kind -- NB: _tc_res_kind is unused. See (KCD3) in -- Note [kcConDecls: kind-checking data type decls] (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs @@ -1877,8 +1882,9 @@ kcConDecl new_or_data tc_res_kind bindOuterSigTKBndrs_Tv outer_bndrs $ -- Why "_Tv"? See Note [Using TyVarTvs for kind-checking GADTs] do { _ <- tcHsContext cxt + -- find the lhs signature ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty $$ ppr tc_res_kind) - ; con_res_kind <- if NewType == new_or_data + ; con_res_kind <- if NewType == new_or_data && NoUserSuppliedResultKind == usrk then return $ getTyConResultKind tc_res_kind else newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty $ (TheKind con_res_kind) ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -946,7 +946,11 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Add constraints from the data constructors -- Fix #25611 -- See DESIGN CHOICE in Note [Kind inference for data family instances] - ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind (if (isJust m_ksig) + then UserSuppliedResultKind + else NoUserSuppliedResultKind) + hs_cons + -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/582257252649275b0913da09170b63add693b8cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/582257252649275b0913da09170b63add693b8cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 11:02:13 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 17 Jan 2025 06:02:13 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] format and remove getTyConResultKind Message-ID: <678a38b5d4145_3e5967c08c82209f@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 97e3a4d4 by Patrick at 2025-01-17T19:02:03+08:00 format and remove getTyConResultKind - - - - - 3 changed files: - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -75,8 +75,6 @@ module GHC.Tc.Gen.HsType ( -- Utils tyLitFromLit, tyLitFromOverloadedLit, - getTyConResultKind - ) where import GHC.Prelude hiding ( head, init, last, tail ) @@ -3948,12 +3946,6 @@ needsEtaExpansion DataTypeFlavour = True needsEtaExpansion ClassFlavour = True needsEtaExpansion _ = False -getTyConResultKind :: Kind -> TcKind -getTyConResultKind kind - = case splitPiTy_maybe kind of - Just (_, kind') -> getTyConResultKind kind' - Nothing -> kind - splitTyConKind :: SkolemInfo -> InScopeSet -> [OccName] -- Avoid these OccNames ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -14,7 +14,7 @@ -- | Typecheck type and class declarations module GHC.Tc.TyCl ( - UserSuppliedResultKind(..), + LHSUserSuppliedResultKind(..), tcTyAndClassDecls, -- Functions used by GHC.Tc.TyCl.Instance to check -- data/type family instance declarations @@ -1775,8 +1775,8 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name) do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt ; kcConDecls (tyConResKind tycon) (if (isJust kindSig) - then UserSuppliedResultKind - else NoUserSuppliedResultKind) cons + then LHSUserSuppliedResultKind + else NoLHSUserSuppliedResultKind) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1836,11 +1836,11 @@ kcConGADTArgs exp_kind con_args = case con_args of RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds -data UserSuppliedResultKind = UserSuppliedResultKind | NoUserSuppliedResultKind deriving Eq +data LHSUserSuppliedResultKind = LHSUserSuppliedResultKind | NoLHSUserSuppliedResultKind deriving Eq kcConDecls :: TcKind -- Result kind of tycon -- Used only in H98 case - -> UserSuppliedResultKind + -> LHSUserSuppliedResultKind -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] kcConDecls tc_res_kind usrk cons @@ -1853,7 +1853,7 @@ kcConDecls tc_res_kind usrk cons -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData -> UserSuppliedResultKind -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl :: NewOrData -> LHSUserSuppliedResultKind -> TcKind -> ConDecl GhcRn -> TcM () kcConDecl new_or_data _usrk tc_res_kind (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs , con_mb_cxt = ex_ctxt, con_args = args }) @@ -1884,8 +1884,8 @@ kcConDecl new_or_data usrk tc_res_kind do { _ <- tcHsContext cxt -- find the lhs signature ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty $$ ppr tc_res_kind) - ; con_res_kind <- if NewType == new_or_data && NoUserSuppliedResultKind == usrk - then return $ getTyConResultKind tc_res_kind + ; con_res_kind <- if NewType == new_or_data && NoLHSUserSuppliedResultKind == usrk + then return tc_res_kind else newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty $ (TheKind con_res_kind) ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -947,8 +947,8 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Fix #25611 -- See DESIGN CHOICE in Note [Kind inference for data family instances] ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind (if (isJust m_ksig) - then UserSuppliedResultKind - else NoUserSuppliedResultKind) + then LHSUserSuppliedResultKind + else NoLHSUserSuppliedResultKind) hs_cons View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/97e3a4d4977dc80897d84049c46260b36826061d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/97e3a4d4977dc80897d84049c46260b36826061d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 11:03:52 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 17 Jan 2025 06:03:52 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] format Message-ID: <678a3918b3f07_3e59672d1b3022320@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 965ae767 by Patrick at 2025-01-17T19:03:45+08:00 format - - - - - 1 changed file: - compiler/GHC/Tc/Gen/HsType.hs Changes: ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -75,6 +75,7 @@ module GHC.Tc.Gen.HsType ( -- Utils tyLitFromLit, tyLitFromOverloadedLit, + ) where import GHC.Prelude hiding ( head, init, last, tail ) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/965ae7675257870b74f1c51f24ffa933f4bcd0e4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/965ae7675257870b74f1c51f24ffa933f4bcd0e4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 11:06:55 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 17 Jan 2025 06:06:55 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] add comment Message-ID: <678a39cf87a87_3e596753a2a022635@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 37617910 by Patrick at 2025-01-17T19:06:47+08:00 add comment - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1836,6 +1836,9 @@ kcConGADTArgs exp_kind con_args = case con_args of RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds +-- Specifically for GADT style declarations +-- do we have lhs user supplied kind signature? +-- as in `data xxx :: UserSuppliedKind where ...` data LHSUserSuppliedResultKind = LHSUserSuppliedResultKind | NoLHSUserSuppliedResultKind deriving Eq kcConDecls :: TcKind -- Result kind of tycon View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/37617910bb931c80f82d2473caed24f51b074637 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/37617910bb931c80f82d2473caed24f51b074637 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 11:07:41 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 17 Jan 2025 06:07:41 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] cleanup Message-ID: <678a39fdd2921_3e59673a627c2298e@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 8c22eaaf by Patrick at 2025-01-17T19:07:35+08:00 cleanup - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -4695,7 +4695,6 @@ checkValidDataCon dflags existential_ok tc con res_ty_tmpl = mkFamilyTyConApp tc (mkTyVarTys tc_tvs) arg_tys = dataConOrigArgTys con orig_res_ty = dataConOrigResTy con - -- dc_eq_spec = dcEqSpec con ; traceTc "checkValidDataCon" (vcat [ ppr con, ppr tc, ppr tc_tvs @@ -4864,9 +4863,7 @@ checkNewDataCon con ; checkNoErrs $ -- Fail here if the newtype is invalid: subsequent code in -- checkValidDataCon can fall over if it comes across an invalid newtype. - do { - traceTc "checkNewDataCon > eq_spec:" (ppr eq_spec) - ; case arg_tys of + do { case arg_tys of [Scaled arg_mult _] -> unless (ok_mult arg_mult) $ addErrTc $ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c22eaaf78ff33e004e1db0ab11c84f503ec62f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c22eaaf78ff33e004e1db0ab11c84f503ec62f8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 11:08:05 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 17 Jan 2025 06:08:05 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] cleanup Message-ID: <678a3a155b8fb_3e596733d7b8232e9@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 2ebb04e8 by Patrick at 2025-01-17T19:07:58+08:00 cleanup - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1885,7 +1885,6 @@ kcConDecl new_or_data usrk tc_res_kind bindOuterSigTKBndrs_Tv outer_bndrs $ -- Why "_Tv"? See Note [Using TyVarTvs for kind-checking GADTs] do { _ <- tcHsContext cxt - -- find the lhs signature ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty $$ ppr tc_res_kind) ; con_res_kind <- if NewType == new_or_data && NoLHSUserSuppliedResultKind == usrk then return tc_res_kind View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ebb04e8480b7368a87dad4338590864cb45ca99 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ebb04e8480b7368a87dad4338590864cb45ca99 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 11:17:24 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 17 Jan 2025 06:17:24 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] update T25611a Message-ID: <678a3c4426b04_761c104a50953ba@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: c20734e6 by Patrick at 2025-01-17T19:16:21+08:00 update T25611a - - - - - 1 changed file: - testsuite/tests/indexed-types/should_compile/T25611a.hs Changes: ===================================== testsuite/tests/indexed-types/should_compile/T25611a.hs ===================================== @@ -12,6 +12,6 @@ data family Fix0 :: (k -> Type) -> k newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } -- This is the GADT newtype instance case --- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` --- data family Fix2 :: (k -> Type) -> k --- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f +-- enabled since !13809 +data family Fix2 :: (k -> Type) -> k +newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c20734e6dbeda89d7ed3337be3764fdbbce3c9f3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c20734e6dbeda89d7ed3337be3764fdbbce3c9f3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 13:37:26 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 17 Jan 2025 08:37:26 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: wasm: prevent bundlers from resolving import("node:timers") Message-ID: <678a5d1645910_6a0ea14f6b84837e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - a97d2615 by ARATA Mizuki at 2025-01-17T08:36:55-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 22 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Unify.hs-boot - hie.yaml - testsuite/tests/rep-poly/RepPolyInferPatBind.stderr - testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr - testsuite/tests/rep-poly/RepPolyTuple3.stderr - testsuite/tests/rep-poly/T23153.stderr - testsuite/tests/rep-poly/T23154.stderr - + testsuite/tests/simd/should_run/T25658.hs - + testsuite/tests/simd/should_run/T25658.stdout - testsuite/tests/simd/should_run/all.T - utils/jsffi/prelude.mjs Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD II64 (OpReg r) (OpReg dst)) + (MOVD FF64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD II64 (OpReg tmp) (OpReg dst)) + (MOVD FF64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -235,7 +235,8 @@ module GHC.Core.Type ( -- * Kinds isTYPEorCONSTRAINT, - isConcreteType, isFixedRuntimeRepKind, + isConcreteType, + isFixedRuntimeRepKind ) where import GHC.Prelude @@ -2869,12 +2870,14 @@ isFixedRuntimeRepKind k isConcreteType :: Type -> Bool isConcreteType = isConcreteTypeWith emptyVarSet -isConcreteTypeWith :: TyVarSet -> Type -> Bool +-- | Like 'isConcreteType', but allows passing in a set of 'TyVar's that +-- should be considered concrete. +-- -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. --- For this "With" version we pass in a set of TyVars to be considered --- concrete. This supports mkSynonymTyCon, which needs to test the RHS --- for concreteness, under the assumption that the binders are instantiated --- to concrete types +isConcreteTypeWith :: TyVarSet -> Type -> Bool +-- This version, with a 'TyVarSet' argument, supports 'mkSynonymTyCon', +-- which needs to test the RHS for concreteness, under the assumption that +-- the binders are instantiated to concrete types isConcreteTypeWith conc_tvs = go where go (TyVarTy tv) = isConcreteTyVar tv || tv `elemVarSet` conc_tvs @@ -2888,6 +2891,7 @@ isConcreteTypeWith conc_tvs = go go CastTy{} = False go CoercionTy{} = False + go_tc :: TyCon -> [Type] -> Bool go_tc tc tys | isForgetfulSynTyCon tc -- E.g. type S a = Int -- Then (S x) is concrete even if x isn't @@ -2903,7 +2907,6 @@ isConcreteTypeWith conc_tvs = go | otherwise -- E.g. type families = False - {- %************************************************************************ %* * ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -1048,8 +1048,7 @@ reportNotConcreteErrs ctxt errs@(err0:_) | frr_errs <- go frr_errs errs = case err of NCE_FRR - { nce_frr_origin = frr_orig - , nce_reasons = _not_conc } -> + { nce_frr_origin = frr_orig } -> FRR_Info { frr_info_origin = frr_orig , frr_info_not_concrete = Nothing } ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -1202,8 +1202,7 @@ tc_inst_forall_arg conc_tvs (tvb, inner_ty) hs_ty -> -- Example: user wrote e.g. (#,#) @(F Bool) for a type family F. -- Emit [W] F Bool ~ kappa[conc] and pretend the user wrote (#,#) @kappa. - do { mco <- unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0 - ; return $ case mco of { MRefl -> ty_arg0; MCo co -> coercionRKind co } } + coercionRKind <$> unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0 ; let fun_ty = mkForAllTy tvb inner_ty in_scope = mkInScopeSet (tyCoVarsOfTypes [fun_ty, ty_arg]) ===================================== compiler/GHC/Tc/Solver/Default.hs ===================================== @@ -440,7 +440,7 @@ defaultEquality ct where try_default_tv lhs_tv rhs_ty - | MetaTv { mtv_info = info, mtv_tclvl = lvl } <- tcTyVarDetails lhs_tv + | MetaTv { mtv_info = info } <- tcTyVarDetails lhs_tv , tyVarKind lhs_tv `tcEqType` typeKind rhs_ty , checkTopShape info rhs_ty -- Do not test for touchability of lhs_tv; that is the whole point! @@ -449,14 +449,13 @@ defaultEquality ct -- checkTyEqRhs: check that we can in fact unify lhs_tv := rhs_ty -- See Note [Defaulting equalities] - -- LC_Promote: promote deeper unification variables (DE4) - -- LC_Promote True: ...including under type families (DE5) - ; let flags :: TyEqFlags () - flags = TEF { tef_foralls = False - , tef_fam_app = TEFA_Recurse - , tef_lhs = TyVarLHS lhs_tv - , tef_unifying = Unifying info lvl (LC_Promote True) - , tef_occurs = cteInsolubleOccurs } + ; let task :: TEFTask + task = unifyingLHSMetaTyVar_TEFTask lhs_tv (LC_Promote True) + -- LC_Promote: promote deeper unification variables (DE4) + -- LC_Promote True: ...including under type families (DE5) + flags :: TyEqFlags () + flags = TEF { tef_task = task + , tef_fam_app = TEFA_Recurse } ; res :: PuResult () Reduction <- wrapTcS (checkTyEqRhs flags rhs_ty) ; case res of ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -201,6 +201,7 @@ import GHC.Exts (oneShot) import Control.Monad import Data.IORef import Data.List ( mapAccumL ) +import Data.Maybe ( isJust ) import Data.Foldable import qualified Data.Semigroup as S import GHC.Types.SrcLoc @@ -2122,7 +2123,7 @@ checkTouchableTyVarEq ev lhs_tv rhs _ -> pprPanic "checkTouchableTyVarEq" (ppr lhs_tv) -- lhs_tv should be a meta-tyvar - is_concrete_lhs_tv = isConcreteInfo lhs_tv_info + is_concrete_lhs_tv = isJust $ concreteInfo_maybe lhs_tv_info check_rhs rhs -- Crucial special case for alpha ~ F tys @@ -2134,11 +2135,9 @@ checkTouchableTyVarEq ev lhs_tv rhs | otherwise = checkTyEqRhs flags rhs - flags = TEF { tef_foralls = False -- isRuntimeUnkSkol lhs_tv - , tef_fam_app = mkTEFA_Break ev NomEq break_wanted - , tef_unifying = Unifying lhs_tv_info lhs_tv_lvl (LC_Promote False) - , tef_lhs = TyVarLHS lhs_tv - , tef_occurs = cteInsolubleOccurs } + flags = TEF { tef_task = unifyingLHSMetaTyVar_TEFTask lhs_tv (LC_Promote False) + , tef_fam_app = mkTEFA_Break ev NomEq break_wanted + } arg_flags = famAppArgFlags flags @@ -2147,7 +2146,8 @@ checkTouchableTyVarEq ev lhs_tv rhs -- Occurs check or skolem escape; so flatten = do { let fam_app_kind = typeKind fam_app ; reason <- checkPromoteFreeVars cteInsolubleOccurs - lhs_tv lhs_tv_lvl (tyCoVarsOfType fam_app_kind) + (tyVarName lhs_tv) lhs_tv_lvl + (tyCoVarsOfType fam_app_kind) ; if not (cterHasNoProblem reason) -- Failed to promote free vars then failCheckWith reason else @@ -2210,19 +2210,15 @@ checkTypeEq ev eq_rel lhs rhs arg_flags = famAppArgFlags given_flags given_flags :: TyEqFlags (TcTyVar,TcType) - given_flags = TEF { tef_lhs = lhs - , tef_foralls = False - , tef_unifying = NotUnifying - , tef_fam_app = mkTEFA_Break ev eq_rel break_given - , tef_occurs = occ_prob } + given_flags = TEF { tef_task = notUnifying_TEFTask occ_prob lhs + , tef_fam_app = mkTEFA_Break ev eq_rel break_given + } -- TEFA_Break used for: [G] a ~ Maybe (F a) -- or [W] F a ~ Maybe (F a) - wanted_flags = TEF { tef_lhs = lhs - , tef_foralls = False - , tef_unifying = NotUnifying - , tef_fam_app = TEFA_Recurse - , tef_occurs = occ_prob } + wanted_flags = TEF { tef_task = notUnifying_TEFTask occ_prob lhs + , tef_fam_app = TEFA_Recurse + } -- TEFA_Recurse: see Note [Don't cycle-break Wanteds when not unifying] -- occ_prob: see Note [Occurs check and representational equality] @@ -2289,7 +2285,7 @@ where both sides are TyFamLHSs. We don't want to flatten that RHS to Instead we'd like to say "occurs-check" and swap LHS and RHS, which yields a canonical constraint [G] G (...(F ty)...) ~ F ty -That tents to rewrite a big type to smaller one. This happens in T15703, +That tends to rewrite a big type to smaller one. This happens in T15703, where we had: [G] Pure g ~ From1 (To1 (Pure g)) Making a loop breaker and rewriting left to right just makes much bigger ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -52,7 +52,6 @@ module GHC.Tc.Types.Constraint ( Hole(..), HoleSort(..), isOutOfScopeHole, DelayedError(..), NotConcreteError(..), - NotConcreteReason(..), WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, @@ -132,7 +131,6 @@ import Data.Coerce import qualified Data.Semigroup as S import Control.Monad ( msum, when ) import Data.Maybe ( mapMaybe, isJust ) -import Data.List.NonEmpty ( NonEmpty ) -- these are for CheckTyEqResult import Data.Word ( Word8 ) @@ -435,30 +433,8 @@ data NotConcreteError -- ^ Where did this check take place? , nce_frr_origin :: FixedRuntimeRepOrigin -- ^ Which representation-polymorphism check did we perform? - , nce_reasons :: NonEmpty NotConcreteReason - -- ^ Why did the check fail? } --- | Why did we decide that a type was not concrete? -data NotConcreteReason - -- | The type contains a 'TyConApp' of a non-concrete 'TyCon'. - -- - -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. - = NonConcreteTyCon TyCon [TcType] - - -- | The type contains a type variable that could not be made - -- concrete (e.g. a skolem type variable). - | NonConcretisableTyVar TyVar - - -- | The type contains a cast. - | ContainsCast TcType TcCoercionN - - -- | The type contains a forall. - | ContainsForall ForAllTyBinder TcType - - -- | The type contains a 'CoercionTy'. - | ContainsCoercionTy TcCoercion - instance Outputable NotConcreteError where ppr (NCE_FRR { nce_frr_origin = frr_orig }) = text "NCE_FRR" <+> parens (ppr (frr_type frr_orig)) ===================================== compiler/GHC/Tc/Utils/Concrete.hs ===================================== @@ -19,39 +19,35 @@ module GHC.Tc.Utils.Concrete import GHC.Prelude import GHC.Builtin.Names ( unsafeCoercePrimName ) -import GHC.Builtin.Types ( liftedTypeKindTyCon, unliftedTypeKindTyCon ) +import GHC.Builtin.Types -import GHC.Core.Coercion ( coToMCo, mkCastTyMCo - , mkGReflRightMCo, mkNomReflCo ) -import GHC.Core.TyCo.Rep ( Type(..), MCoercion(..) ) -import GHC.Core.TyCon ( isConcreteTyCon ) -import GHC.Core.Type ( isConcreteType, typeKind, mkFunTy) +import GHC.Core.Coercion +import GHC.Core.TyCo.Rep +import GHC.Core.Type -import GHC.Tc.Types.Constraint ( NotConcreteError(..), NotConcreteReason(..) ) -import GHC.Tc.Types.Evidence ( Role(..), TcCoercionN, TcMCoercionN ) +import GHC.Data.Bag + +import GHC.Tc.Types.Constraint +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Origin import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType -import GHC.Tc.Utils.TcMType +import {-# SOURCE #-} GHC.Tc.Utils.Unify import GHC.Types.Basic ( TypeOrKind(KindLevel) ) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Types.Name import GHC.Types.Name.Env -import GHC.Types.Var ( tyVarKind, tyVarName ) +import GHC.Types.Var import GHC.Utils.Misc ( HasDebugCallStack ) import GHC.Utils.Outputable +import GHC.Utils.Panic import GHC.Data.FastString ( FastString, fsLit ) - import Control.Monad ( void ) import Data.Functor ( ($>) ) -import Data.List.NonEmpty ( NonEmpty((:|)) ) -import Control.Monad.Trans.Class ( lift ) -import Control.Monad.Trans.Writer.CPS ( WriterT, runWriterT, tell ) {- Note [Concrete overview] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -221,7 +217,6 @@ other type variables, a 'ConcreteTv' type variable is a type variable which can only be unified with a concrete type (in the sense of Note [Concrete types]). INVARIANT: the kind of a concrete metavariable is concrete. - This invariant is upheld at the time of creation of a new concrete metavariable. Concrete metavariables are useful for representation-polymorphism checks: @@ -632,7 +627,7 @@ hasFixedRuntimeRep :: HasDebugCallStack -- That is, @ty'@ has a syntactically fixed RuntimeRep -- in the sense of Note [Fixed RuntimeRep]. hasFixedRuntimeRep frr_ctxt ty = - checkFRR_with (unifyConcrete (fsLit "cx") . ConcreteFRR) frr_ctxt ty + checkFRR_with (fmap (fmap coToMCo) . unifyConcrete_kind (fsLit "cx") . ConcreteFRR) frr_ctxt ty -- | Like 'hasFixedRuntimeRep', but we perform an eager syntactic check. -- @@ -700,226 +695,86 @@ checkFRR_with check_kind frr_ctxt ty frr_orig :: FixedRuntimeRepOrigin frr_orig = FixedRuntimeRepOrigin { frr_type = ty, frr_context = frr_ctxt } --- | Ensure that the given type @ty@ can unify with a concrete type, +-- | Ensure that the given kind @ki@ can unify with a concrete type, -- in the sense of Note [Concrete types]. -- --- Returns a coercion @co :: ty ~# conc_ty@, where @conc_ty@ is +-- Returns a coercion @co :: ki ~# conc_ki@, where @conc_ki@ is -- concrete. -- --- If the type is already syntactically concrete, this +-- If the kind is already syntactically concrete, this -- immediately returns a reflexive coercion. Otherwise, -- it creates a new concrete metavariable @concrete_tv@ --- and emits an equality constraint @ty ~# concrete_tv@, +-- and emits an equality constraint @ki ~# concrete_tv@, -- to be handled by the constraint solver. -- +-- Precondition: @ki@ must be of the form @TYPE rep@ or @CONSTRAINT rep at . +unifyConcrete_kind :: HasDebugCallStack + => FastString -- ^ name to use when creating concrete metavariables + -> ConcreteTvOrigin + -> TcKind + -> TcM TcCoercionN +unifyConcrete_kind occ_fs conc_orig ki + | Just (torc, rep) <- sORTKind_maybe ki + = do { let tc = case torc of + TypeLike -> tYPETyCon + ConstraintLike -> cONSTRAINTTyCon + ; rep_co <- unifyConcrete occ_fs conc_orig rep + ; return $ mkTyConAppCo Nominal tc [rep_co] } + | otherwise + = pprPanic "unifyConcrete_kind: kind is not of the form 'TYPE rep' or 'CONSTRAINT rep'" $ + ppr ki <+> dcolon <+> ppr (typeKind ki) + + +-- | Ensure the given type can be unified with +-- a concrete type, in the sense of Note [Concrete types]. +-- +-- Returns a coercion @co :: ty ~# conc_ty@, where @conc_ty@ is +-- concrete. +-- +-- If the type is already syntactically concrete, this +-- immediately returns a reflexive coercion. +-- Otherwise, it will create new concrete metavariables and emit +-- new Wanted equality constraints, to be handled by the constraint solver. +-- -- Invariant: the kind of the supplied type must be concrete. -- -- We assume the provided type is already at the kind-level -- (this only matters for error messages). -unifyConcrete :: HasDebugCallStack - => FastString -> ConcreteTvOrigin -> TcType -> TcM TcMCoercionN +unifyConcrete :: FastString -> ConcreteTvOrigin -> TcType -> TcM TcCoercionN unifyConcrete occ_fs conc_orig ty - = do { (ty, errs) <- makeTypeConcrete conc_orig ty - ; case errs of - -- We were able to make the type fully concrete. - { [] -> return MRefl - -- The type could not be made concrete; perhaps it contains - -- a skolem type variable, a type family application, ... - -- - -- Create a new ConcreteTv metavariable @concrete_tv@ - -- and unify @ty ~# concrete_tv at . - ; _ -> - do { conc_tv <- newConcreteTyVar conc_orig occ_fs ki - -- NB: newConcreteTyVar asserts that 'ki' is concrete. - ; coToMCo <$> emitWantedEq orig KindLevel Nominal ty (mkTyVarTy conc_tv) } } } - where - ki :: TcKind - ki = typeKind ty - orig :: CtOrigin - orig = case conc_orig of - ConcreteFRR frr_orig -> FRROrigin frr_orig + = do { (co, cts) <- makeTypeConcrete occ_fs conc_orig ty + ; emitSimples cts + ; return co } --- | Ensure that the given type is concrete. +-- | Ensure that the given kind @ki@ is concrete. -- -- This is an eager syntactic check, and never defers --- any work to the constraint solver. --- --- Invariant: the kind of the supplied type must be concrete. --- Invariant: the output type is equal to the input type, --- up to zonking. +-- any work to the constraint solver. However, +-- it may perform unification. -- --- We assume the provided type is already at the kind-level --- (this only matters for error messages). +-- Invariant: the output type is equal to the input type, up to zonking. ensureConcrete :: HasDebugCallStack => FixedRuntimeRepOrigin - -> TcType - -> TcM TcType -ensureConcrete frr_orig ty - = do { traceTc "ensureConcrete {" (ppr frr_orig $$ ppr ty) - ; (ty', errs) <- makeTypeConcrete conc_orig ty - ; case errs of - { err:errs -> - do { traceTc "ensureConcrete } failure" $ - vcat [ text "ty:" <+> ppr ty - , text "ty':" <+> ppr ty' ] + -> TcKind + -> TcM TcKind +ensureConcrete frr_orig ki + = do { (co, cts) <- makeTypeConcrete (fsLit "cx") conc_orig ki + ; let trace_msg = vcat [ text "ty: " <+> ppr ki + , text "co:" <+> ppr co ] + ; if isEmptyBag cts + then traceTc "ensureConcrete } success" trace_msg + else do { traceTc "ensureConcrete } failure" trace_msg ; loc <- getCtLocM (FRROrigin frr_orig) (Just KindLevel) ; emitNotConcreteError $ NCE_FRR { nce_loc = loc - , nce_frr_origin = frr_orig - , nce_reasons = err :| errs } - } - ; [] -> - traceTc "ensureConcrete } success" $ - vcat [ text "ty: " <+> ppr ty - , text "ty':" <+> ppr ty' ] } - ; return ty' } + , nce_frr_origin = frr_orig } + } + ; return $ coercionRKind co } where conc_orig :: ConcreteTvOrigin conc_orig = ConcreteFRR frr_orig -{-*********************************************************************** -%* * - Making a type concrete -%* * -%************************************************************************ - -Note [Unifying concrete metavariables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Unifying concrete metavariables (as defined in Note [ConcreteTv]) is not -an all-or-nothing affair as it is for other sorts of metavariables. - -Consider the following unification problem in which all metavariables -are unfilled (and ignoring any TcLevel considerations): - - alpha[conc] ~# TYPE (TupleRep '[ beta[conc], IntRep, gamma[tau] ]) - -We can't immediately unify `alpha` with the RHS, because the RHS is not -a concrete type (in the sense of Note [Concrete types]). Instead, we -proceed as follows: - - - create a fresh concrete metavariable variable `gamma'[conc]`, - - write gamma[tau] := gamma'[conc], - - write alpha[conc] := TYPE (TupleRep '[ beta[conc], IntRep, gamma'[conc] ]). - -Thus, in general, to unify `alpha[conc] ~# rhs`, we first try to turn -`rhs` into a concrete type (see the 'makeTypeConcrete' function). -If this succeeds, resulting in a concrete type `rhs'`, we simply fill -`alpha[conc] := rhs'`. If it fails, then syntactic unification fails. - -Example 1: - - alpha[conc] ~# TYPE (TupleRep '[ beta[conc], IntRep, gamma[tau] ]) - - We proceed by filling metavariables: - - gamma[tau] := gamma[conc] - alpha[conc] := TYPE (TupleRep '[ beta[conc], IntRep, gamma[conc] ]) - - This successfully unifies alpha. - -Example 2: - - For a type family `F :: Type -> Type`: - - delta[conc] ~# TYPE (SumRep '[ zeta[tau], a[sk], F omega[tau] ]) - - We write zeta[tau] := zeta[conc], and then fail, providing the following - two reasons: - - - `a[sk]` is not a concrete type variable, so the overall type - cannot be concrete - - `F` is not a concrete type constructor, in the sense of - Note [Concrete types]. So we keep it as is; in particular, - we /should not/ try to make its argument `omega[tau]` into - a ConcreteTv. - - Note that making zeta concrete allows us to propagate information. - For example, after more typechecking, we might try to unify - `zeta ~# rr[sk]`. If we made zeta a ConcreteTv, we will report - this unsolved equality using the 'ConcreteTvOrigin' stored in zeta[conc]. - This allows us to report ALL the problems in a representation-polymorphism - check (instead of only a non-empty subset). --} - --- | Try to turn the provided type into a concrete type, by ensuring --- unfilled metavariables are appropriately marked as concrete. --- --- Returns a zonked type which is "as concrete as possible", and --- a list of problems encountered when trying to make it concrete. --- --- INVARIANT: the returned type is equal to the input type, up to zonking. --- INVARIANT: if this function returns an empty list of 'NotConcreteReasons', --- then the returned type is concrete, in the sense of Note [Concrete types]. -makeTypeConcrete :: ConcreteTvOrigin -> TcType -> TcM (TcType, [NotConcreteReason]) --- TODO: it could be worthwhile to return enough information to continue solving. --- Consider unifying `alpha[conc] ~# TupleRep '[ beta[tau], F Int ]` for --- a type family 'F'. --- This function will concretise `beta[tau] := beta[conc]` and return --- that `TupleRep '[ beta[conc], F Int ]` is not concrete because of the --- type family application `F Int`. But we could decompose by setting --- alpha := TupleRep '[ beta, gamma[conc] ] and emitting `[W] gamma[conc] ~ F Int`. -makeTypeConcrete conc_orig ty = - do { res@(ty', _) <- runWriterT $ go ty - ; traceTc "makeTypeConcrete" $ - vcat [ text "ty:" <+> ppr ty - , text "ty':" <+> ppr ty' ] - ; return res } - where - go :: TcType -> WriterT [NotConcreteReason] TcM TcType - go ty - | Just ty <- coreView ty - = go ty - | isConcreteType ty - = pure ty - go ty@(TyVarTy tv) -- not a ConcreteTv (already handled above) - = do { mb_filled <- lift $ isFilledMetaTyVar_maybe tv - ; case mb_filled of - { Just ty -> go ty - ; Nothing - | isMetaTyVar tv - , TauTv <- metaTyVarInfo tv - -> -- Change the MetaInfo to ConcreteTv, but retain the TcLevel - do { kind <- go (tyVarKind tv) - ; let occ_fs = occNameFS (getOccName tv) - -- occ_fs: preserve the occurrence name of the original tyvar - -- This helps in error messages - ; lift $ - do { conc_tv <- setTcLevel (tcTyVarLevel tv) $ - newConcreteTyVar conc_orig occ_fs kind - ; let conc_ty = mkTyVarTy conc_tv - ; liftZonkM $ writeMetaTyVar tv conc_ty - ; return conc_ty } } - | otherwise - -- Don't attempt to make other type variables concrete - -- (e.g. SkolemTv, TyVarTv, CycleBreakerTv, RuntimeUnkTv). - -> bale_out ty (NonConcretisableTyVar tv) } } - go ty@(TyConApp tc tys) - | isConcreteTyCon tc - = mkTyConApp tc <$> mapM go tys - | otherwise - = bale_out ty (NonConcreteTyCon tc tys) - go (FunTy af w ty1 ty2) - = do { w <- go w - ; ty1 <- go ty1 - ; ty2 <- go ty2 - ; return $ mkFunTy af w ty1 ty2 } - go (AppTy ty1 ty2) - = do { ty1 <- go ty1 - ; ty2 <- go ty2 - ; return $ mkAppTy ty1 ty2 } - go ty@(LitTy {}) - = return ty - go ty@(CastTy cast_ty kco) - = bale_out ty (ContainsCast cast_ty kco) - go ty@(ForAllTy tcv body) - = bale_out ty (ContainsForall tcv body) - go ty@(CoercionTy co) - = bale_out ty (ContainsCoercionTy co) - - bale_out :: TcType -> NotConcreteReason -> WriterT [NotConcreteReason] TcM TcType - bale_out ty reason = do { tell [reason]; return ty } - {-*********************************************************************** %* * Concrete type variables of Ids ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -755,7 +755,7 @@ newNamedAnonMetaTyVar tyvar_name meta_info kind = do { name <- newMetaTyVarName tyvar_name ; details <- newMetaDetails meta_info ; let tyvar = mkTcTyVar name kind details - ; traceTc "newAnonMetaTyVar" (ppr tyvar) + ; traceTc "newAnonMetaTyVar" (ppr tyvar <+> dcolon <+> ppr kind) ; return tyvar } -- makes a new skolem tv ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -53,7 +53,7 @@ module GHC.Tc.Utils.TcType ( isImmutableTyVar, isSkolemTyVar, isMetaTyVar, isMetaTyVarTy, isTyVarTy, tcIsTcTyVar, isTyVarTyVar, isOverlappableTyVar, isTyConableTyVar, ConcreteTvOrigin(..), isConcreteTyVar_maybe, isConcreteTyVar, - isConcreteTyVarTy, isConcreteTyVarTy_maybe, isConcreteInfo, + isConcreteTyVarTy, isConcreteTyVarTy_maybe, concreteInfo_maybe, ConcreteTyVars, noConcreteTyVars, isAmbiguousTyVar, isCycleBreakerTyVar, metaTyVarRef, metaTyVarInfo, isFlexi, isIndirect, isRuntimeUnkSkol, @@ -1266,9 +1266,9 @@ isConcreteTyVar_maybe tv | otherwise = Nothing -isConcreteInfo :: MetaInfo -> Bool -isConcreteInfo (ConcreteTv {}) = True -isConcreteInfo _ = False +concreteInfo_maybe :: MetaInfo -> Maybe ConcreteTvOrigin +concreteInfo_maybe (ConcreteTv conc_orig) = Just conc_orig +concreteInfo_maybe _ = Nothing -- | Is this type variable a concrete type variable, i.e. -- it is a metavariable with 'ConcreteTv' 'MetaInfo'? ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1,8 +1,13 @@ +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeApplications #-} + {- (c) The University of Glasgow 2006 @@ -28,6 +33,7 @@ module GHC.Tc.Utils.Unify ( swapOverTyVars, touchabilityAndShapeTest, checkTopShape, lhsPriority, UnifyEnv(..), updUEnvLoc, setUEnvRole, uType, + makeTypeConcrete, -------------------------------- -- Holes @@ -41,8 +47,11 @@ module GHC.Tc.Utils.Unify ( checkTyEqRhs, recurseIntoTyConApp, PuResult(..), failCheckWith, okCheckRefl, mapCheck, - TyEqFlags(..), TyEqFamApp(..), AreUnifying(..), LevelCheck(..), FamAppBreaker, + TyEqFlags(..), TEFTask(..), + notUnifying_TEFTask, unifyingLHSMetaTyVar_TEFTask, + LevelCheck(..), TyEqFamApp(..), FamAppBreaker, famAppArgFlags, checkPromoteFreeVars, + simpleUnifyCheck, UnifyCheckCaller(..), fillInferResult, @@ -54,7 +63,7 @@ import GHC.Hs import GHC.Tc.Errors.Types ( ErrCtxtMsg(..) ) import GHC.Tc.Errors.Ppr ( pprErrCtxtMsg ) -import GHC.Tc.Utils.Concrete ( hasFixedRuntimeRep, hasFixedRuntimeRep_syntactic ) +import GHC.Tc.Utils.Concrete import GHC.Tc.Utils.Env import GHC.Tc.Utils.Instantiate import GHC.Tc.Utils.Monad @@ -94,11 +103,13 @@ import GHC.Utils.Panic import GHC.Driver.DynFlags import GHC.Data.Bag -import GHC.Data.FastString( fsLit ) +import GHC.Data.FastString import Control.Monad +import Data.Maybe (maybeToList, isJust) import Data.Monoid as DM ( Any(..) ) import qualified Data.Semigroup as S ( (<>) ) +import Data.Traversable (for) {- ********************************************************************* * * @@ -2927,7 +2938,7 @@ simpleUnifyCheck caller lhs_tv rhs = go rhs where - !(occ_in_ty, occ_in_co) = mkOccFolders lhs_tv + !(occ_in_ty, occ_in_co) = mkOccFolders (tyVarName lhs_tv) lhs_tv_lvl = tcTyVarLevel lhs_tv lhs_tv_is_concrete = isConcreteTyVar lhs_tv @@ -2974,7 +2985,7 @@ simpleUnifyCheck caller lhs_tv rhs go (LitTy {}) = True -mkOccFolders :: TcTyVar -> (TcType -> Bool, TcCoercion -> Bool) +mkOccFolders :: Name -> (TcType -> Bool, TcCoercion -> Bool) -- These functions return True -- * if lhs_tv occurs (incl deeply, in the kind of variable) -- * if there is a coercion hole @@ -2987,7 +2998,7 @@ mkOccFolders lhs_tv = (getAny . check_ty, getAny . check_co) , tcf_hole = do_hole , tcf_tycobinder = do_bndr } - do_tcv is v = Any (not (v `elemVarSet` is) && v == lhs_tv) + do_tcv is v = Any (not (v `elemVarSet` is) && tyVarName v == lhs_tv) `mappend` check_ty (varType v) do_bndr is tcv _faf = extendVarSet is tcv @@ -3058,10 +3069,7 @@ reductionCoercion is Refl. See `canEqCanLHSFinish_no_unification`. data PuResult a b = PuFail CheckTyEqResult | PuOK (Bag a) b - -instance Functor (PuResult a) where - fmap _ (PuFail prob) = PuFail prob - fmap f (PuOK cts x) = PuOK cts (f x) + deriving stock (Functor, Foldable, Traversable) instance Applicative (PuResult a) where pure x = PuOK emptyBag x @@ -3100,82 +3108,192 @@ mapCheck f xs -- | Options describing how to deal with a type equality -- in the pure unifier. See 'checkTyEqRhs' data TyEqFlags a - = TEF { tef_foralls :: Bool -- Allow foralls - , tef_lhs :: CanEqLHS -- LHS of the constraint - , tef_unifying :: AreUnifying -- Always NotUnifying if tef_lhs is TyFamLHS + = TEF { tef_task :: TEFTask + -- ^ LHS structure, and which checks to perform on the RHS , tef_fam_app :: TyEqFamApp a - , tef_occurs :: CheckTyEqProblem } -- Soluble or insoluble occurs check + -- ^ How to deal with type family applications + } + +-- | The structure of the LHS and which checks to perform in 'checkTyEqRhs', +-- for an equality @lhs ~# rhs at . +-- +-- See Note [TEFTask]. +data TEFTask + -- | LHS is a type family application; we are not unifying. + = TEFTyFam + { tefTyFam_occursCheck :: CheckTyEqProblem + -- ^ The 'CheckTyEqProblem' to report for occurs-check failures + -- (soluble or insoluble) + , tefTyFam_tyCon :: TyCon + , tefTyFam_args :: [Type] + } + -- | LHS is a 'TyVar'. + | TEFTyVar + { tefTyVar_occursCheck :: Maybe (Name, CheckTyEqProblem) + -- ^ Occurs check: LHS 'TyVar' 'Name', + -- and which 'CheckTyEqProblem' to report for occurs-check failures + -- (soluble or insoluble) + , tefTyVar_levelCheck :: Maybe (TcLevel, LevelCheck) + -- ^ Level check: LHS 'TyVar' 'TcLevel', + -- and which 'LevelCheck' to perform + , tefTyVar_concreteCheck :: Maybe ConcreteTvOrigin + -- ^ Concreteness check: LHS 'TyVar' 'ConcreteTvOrigin' + -- to use for the check + } + +{- Note [TEFTask] +~~~~~~~~~~~~~~~~~ +When we call the pure unifier, e.g. through 'checkTyEqRhs', we can decide what +kind of checks the unifier performs via the 'TyEqFlags' argument. In particular, +when the LHS type in a unification is a type variable, we might want to perform +different checks; this is achieved using the 'TEFTyVar' constructor to 'TEFTask': + + 1. LHS is a skolem tyvar, or an untouchable meta-tyvar. + We are not unifying; we only want to perform occurs-checks. + + TEFTyVar + { tefTyVar_occursCheck = Just ... + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Nothing + } + + 2. LHS is a touchable meta-tyvar. + We are unifying; we want to perform an occurs check, a level check, + and a concreteness check (when the meta-tyvar is a ConcreteTv). + + TEFTyVar + { tefTyVar_occursCheck = Just ... + , tefTyVar_levelCheck = Just ... + , tefTyVar_concreteCheck = isConcreteTyVar_maybe lhs_tv + } + + 3. LHS is a fresh ConcreteTv meta-tyvar (see call to 'checkTyEqRhs' in + 'makeTypeConcrete'). We are unifying; we only want to perform + a concreteness check. + + TEFTyVar + { tefTyVar_occursCheck = Nothing + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Just ... + } +-} + +-- | Create a "not unifying" 'TEFTask' from a 'CanEqLHS'. +-- +-- See use-case (1) in Note [TEFTask]. +notUnifying_TEFTask :: CheckTyEqProblem -> CanEqLHS -> TEFTask +notUnifying_TEFTask occ_prob = \case + TyFamLHS tc tys -> + TEFTyFam occ_prob tc tys + TyVarLHS tv -> + TEFTyVar + { tefTyVar_occursCheck = Just (tyVarName tv, occ_prob) + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Nothing + } + -- We need an occurs-check here, but no level check. + -- See Note [Promotion and level-checking] wrinkle (W1) + +-- | Create "unifying" 'TEFTask' from a 'TyVarLHS'. +-- +-- Invariant: the argument 'TyVar' is a 'MetaTv'. +unifyingLHSMetaTyVar_TEFTask :: TyVar -> LevelCheck -> TEFTask +unifyingLHSMetaTyVar_TEFTask lhs_tv lc = + TEFTyVar + { tefTyVar_occursCheck = Just (tyVarName lhs_tv, cteInsolubleOccurs) + , tefTyVar_levelCheck = Just (tcTyVarLevel lhs_tv, lc) + , tefTyVar_concreteCheck = isConcreteTyVar_maybe lhs_tv + } + +-- | Do we want to perform a concreteness check in 'checkTyEqRhs'? +tefTaskConcrete_maybe :: TEFTask -> Maybe ConcreteTvOrigin +tefTaskConcrete_maybe (TEFTyFam {}) = Nothing +tefTaskConcrete_maybe (TEFTyVar { tefTyVar_concreteCheck = conc }) = conc + +instance Outputable TEFTask where + ppr = \case + TEFTyFam occ tc tys -> + text "TEFTyFam" <+> ppr occ <+> ppr (mkTyConApp tc tys) + TEFTyVar mb_occ mb_lc mb_conc -> + text "TEFTyVar" <+> hcat (punctuate comma fields) + where + fields = [ text "OccursCheck:" <+> ppr tv | (tv, _) <- maybeToList mb_occ ] + ++ + [ text "LevelCheck:" <+> ppr lc | lc <- maybeToList mb_lc ] + ++ + [ text "ConcreteCheck" | isJust mb_conc ] -- | What to do when encountering a type-family application while processing -- a type equality in the pure unifier. -- -- See Note [Family applications in canonical constraints] data TyEqFamApp a - = TEFA_Fail -- Always fail - | TEFA_Recurse -- Just recurse - | TEFA_Break (FamAppBreaker a) -- Recurse, but replace with cycle breaker if fails, - -- using the FamAppBreaker - -data AreUnifying - = Unifying - MetaInfo -- MetaInfo of the LHS tyvar (which is a meta-tyvar) - TcLevel -- Level of the LHS tyvar - LevelCheck - - | NotUnifying -- Not attempting to unify + = TEFA_Fail -- ^ Always fail + | TEFA_Recurse -- ^ Just recurse + | TEFA_Break (FamAppBreaker a) -- ^ Recurse, but replace with cycle breaker if fails, + -- using the FamAppBreaker +-- | What level check to perform, in a call to the pure unifier? data LevelCheck - = LC_None -- Level check not needed: we should never encounter - -- a tyvar at deeper level than the LHS - - | LC_Check -- Do a level check between the LHS tyvar and the occurrence tyvar - -- Fail if the level check fails - - | LC_Promote -- Do a level check between the LHS tyvar and the occurrence tyvar - -- If the level check fails, and the occurrence is a unification - -- variable, promote it - Bool -- False <=> don't promote under type families (the common case) - -- True <=> promote even under type families - -- see Note [Defaulting equalities] in GHC.Tc.Solver + = LC_Check -- ^ Do a level check between the LHS tyvar and the occurrence tyvar. + -- + -- Fail if the level check fails. + + | LC_Promote Bool + -- ^ Do a level check between the LHS tyvar and the occurrence tyvar. + -- + -- If the level check fails, and the occurrence is a unification + -- variable, promote it. + -- + -- - False <=> don't promote under type families (the common case) + -- - True <=> promote even under type families + -- (see Note [Defaulting equalities] in GHC.Tc.Solver) instance Outputable (TyEqFlags a) where ppr (TEF { .. }) = text "TEF" <> braces ( - vcat [ text "tef_foralls =" <+> ppr tef_foralls - , text "tef_lhs =" <+> ppr tef_lhs - , text "tef_unifying =" <+> ppr tef_unifying - , text "tef_fam_app =" <+> ppr tef_fam_app - , text "tef_occurs =" <+> ppr tef_occurs ]) + vcat [ text "tef_task =" <+> ppr tef_task + , text "tef_fam_app =" <+> ppr tef_fam_app ]) instance Outputable (TyEqFamApp a) where ppr TEFA_Fail = text "TEFA_Fail" ppr TEFA_Recurse = text "TEFA_Recurse" ppr (TEFA_Break {}) = text "TEFA_Break" -instance Outputable AreUnifying where - ppr NotUnifying = text "NotUnifying" - ppr (Unifying mi lvl lc) = text "Unifying" <+> - braces (ppr mi <> comma <+> ppr lvl <> comma <+> ppr lc) - instance Outputable LevelCheck where - ppr LC_None = text "LC_None" ppr LC_Check = text "LC_Check" ppr (LC_Promote b) = text "LC_Promote" <> ppWhen b (text "(deep)") +-- | Adjust the 'TyEqFlags' when going undter a type family: +-- +-- 1. Only the outer family application gets the loop-breaker treatment +-- 2. Weaken level checks for tyvar promotion. For example, in @[W] alpha[2] ~ Maybe (F beta[3])@, +-- do not promote @beta[3]@, instead promote @(F beta[3])@. +-- 3. Occurs checks become potentially soluble (after additional type family +-- reductions). famAppArgFlags :: TyEqFlags a -> TyEqFlags a --- Adjust the flags when going undter a type family --- Only the outer family application gets the loop-breaker treatment --- Ditto tyvar promotion. E.g. --- [W] alpha[2] ~ Maybe (F beta[3]) --- Do not promote beta[3]; instead promote (F beta[3]) -famAppArgFlags flags@(TEF { tef_unifying = unifying }) - = flags { tef_fam_app = TEFA_Recurse - , tef_unifying = zap_promotion unifying - , tef_occurs = cteSolubleOccurs } - -- tef_occurs: under a type family, an occurs check is not definitely-insoluble +famAppArgFlags flags@(TEF { tef_task = task }) + = flags { tef_fam_app = TEFA_Recurse -- (1) + , tef_task = fam_app_task task + } where - zap_promotion (Unifying info lvl (LC_Promote deeply)) - | not deeply = Unifying info lvl LC_Check - zap_promotion unifying = unifying + fam_app_task :: TEFTask -> TEFTask + fam_app_task task = case task of + TEFTyFam {} -> + task + { tefTyFam_occursCheck = cteSolubleOccurs -- (3) + } + TEFTyVar { tefTyVar_occursCheck = mb_occ, tefTyVar_levelCheck = mb_lc } -> + task + { tefTyVar_occursCheck = + fmap (\ (tv, _old_occ_prob) -> (tv, cteSolubleOccurs)) mb_occ -- (3) + , tefTyVar_levelCheck = + fmap (\ (lvl, lc) -> (lvl, zap_lc lc)) mb_lc -- (2) + } + zap_lc = \case + LC_Promote deeply + | not deeply + -> LC_Check + lc -> lc type FamAppBreaker a = TcType -> TcM (PuResult a Reduction) -- Given a family-application ty, return a Reduction :: ty ~ cvb @@ -3196,7 +3314,6 @@ checkTyEqRhs flags ty FunTy {ft_af = af, ft_mult = w, ft_arg = a, ft_res = r} | isInvisibleFunArg af -- e.g. Num a => blah - , not (tef_foralls flags) -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) | otherwise -> do { w_res <- checkTyEqRhs flags w @@ -3215,38 +3332,48 @@ checkTyEqRhs flags ty CoercionTy co -> do { co_res <- checkCo flags co ; return (mkReflCoRedn Nominal <$> co_res) } - ForAllTy {} - | tef_foralls flags -> okCheckRefl ty - | otherwise -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) - + ForAllTy {} -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) ------------------- checkCo :: TyEqFlags a -> Coercion -> TcM (PuResult a Coercion) -- See Note [checkCo] -checkCo (TEF { tef_lhs = TyFamLHS {} }) co - = return (pure co) - -checkCo (TEF { tef_lhs = TyVarLHS lhs_tv - , tef_unifying = unifying - , tef_occurs = occ_prob }) co - -- Check for coercion holes, if unifying - -- See (COERCION-HOLE) in Note [Unification preconditions] - | hasCoercionHoleCo co - = failCheckWith (cteProblem cteCoercionHole) - - -- Occurs check (can promote) - | Unifying _ lhs_tv_lvl (LC_Promote {}) <- unifying - = do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co) - ; if cterHasNoProblem reason - then return (pure co) - else failCheckWith reason } - - -- Occurs check (no promotion) - | lhs_tv `elemVarSet` tyCoVarsOfCo co - = failCheckWith (cteProblem occ_prob) +checkCo (TEF { tef_task = task }) co = + case task of + TEFTyFam {} -> + -- NB: 'TEFTyFam' case means we are not unifying. + return (pure co) + TEFTyVar + { tefTyVar_concreteCheck = mb_conc + , tefTyVar_levelCheck = mb_lc + , tefTyVar_occursCheck = mb_occ + } + -- Coercions cannot appear in concrete types. + -- + -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. + | Just {} <- mb_conc + -> failCheckWith (cteProblem cteConcrete) + + -- Check for coercion holes, if unifying. + -- See (COERCION-HOLE) in Note [Unification preconditions] + | Just {} <- mb_lc -- equivalent to "we are unifying"; see Note [TEFTask] + , hasCoercionHoleCo co + -> failCheckWith (cteProblem cteCoercionHole) + + -- Occurs check (can promote) + | Just (lhs_tv, occ_prob) <- mb_occ + , Just (lhs_tv_lvl, LC_Promote {}) <- mb_lc + -> do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co) + ; if cterHasNoProblem reason + then return (pure co) + else failCheckWith reason } + + -- Occurs check (no promotion) + | Just (lhs_tv, occ_prob) <- mb_occ + , nameUnique lhs_tv `elemVarSetByKey` tyCoVarsOfCo co + -> failCheckWith (cteProblem occ_prob) - | otherwise - = return (pure co) + | otherwise + -> return (pure co) {- Note [checkCo] ~~~~~~~~~~~~~~~~~ @@ -3364,7 +3491,7 @@ If we have [W] alpha ~ Maybe (F (G alpha)) checkTyConApp :: TyEqFlags a -> TcType -> TyCon -> [TcType] -> TcM (PuResult a Reduction) -checkTyConApp flags@(TEF { tef_unifying = unifying, tef_foralls = foralls_ok }) +checkTyConApp flags@(TEF { tef_task = task }) tc_app tc tys | isTypeFamilyTyCon tc , let arity = tyConArity tc @@ -3383,11 +3510,10 @@ checkTyConApp flags@(TEF { tef_unifying = unifying, tef_foralls = foralls_ok }) -- See Note [Forgetful synonyms in checkTyConApp] = checkTyEqRhs flags ty' - | not (isTauTyCon tc || foralls_ok) + | not (isTauTyCon tc) = failCheckWith impredicativeProblem - | Unifying info _ _ <- unifying - , isConcreteInfo info + | Just {} <- tefTaskConcrete_maybe task , not (isConcreteTyCon tc) = failCheckWith (cteProblem cteConcrete) @@ -3404,21 +3530,19 @@ checkFamApp :: TyEqFlags a -> TcType -> TyCon -> [TcType] -- Saturated family application -> TcM (PuResult a Reduction) -- See Note [Family applications in canonical constraints] -checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob - , tef_fam_app = fam_app_flag, tef_lhs = lhs }) +checkFamApp flags@(TEF { tef_task = task, tef_fam_app = fam_app_flag }) fam_app tc tys = case fam_app_flag of TEFA_Fail -> failCheckWith (cteProblem cteTypeFamily) -- Occurs check: F ty ~ ...(F ty)... - _ | TyFamLHS lhs_tc lhs_tys <- lhs + _ | TEFTyFam occ_prob lhs_tc lhs_tys <- task , tcEqTyConApps lhs_tc lhs_tys tc tys -> case fam_app_flag of TEFA_Recurse -> failCheckWith (cteProblem occ_prob) TEFA_Break breaker -> breaker fam_app - _ | Unifying lhs_info _ _ <- unifying - , isConcreteInfo lhs_info + _ | Just {} <- tefTaskConcrete_maybe task -> case fam_app_flag of TEFA_Recurse -> failCheckWith (cteProblem cteConcrete) TEFA_Break breaker -> breaker fam_app @@ -3441,22 +3565,55 @@ checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob arg_flags = famAppArgFlags flags ------------------- + +-- | The result of a single check in 'checkTyVar', such as a concreteness check +-- or a level check. +data TyVarCheckResult + -- | Check succeded; nothing else to do. + = TyVarCheck_Success + -- | Check succeeded, but requires an additional promotion. + -- + -- Invariant: at least one of the fields is not 'Nothing'. + | TyVarCheck_Promote + (Maybe TcLevel) + -- ^ @Just lvl@ <=> 'TyVar' needs to be promoted to @lvl@ + (Maybe ConcreteTvOrigin) + -- ^ @Just conc_orig@ <=> 'TyVar' needs to be make concrete + -- | Check failed with some 'CheckTyEqProblem's. + -- + -- Invariant: the 'CheckTyEqResult' is not 'cteOK'. + | TyVarCheck_Error CheckTyEqResult + +instance Semigroup TyVarCheckResult where + TyVarCheck_Success <> r = r + r <> TyVarCheck_Success = r + TyVarCheck_Error e1 <> TyVarCheck_Error e2 = + TyVarCheck_Error (e1 S.<> e2) + e@(TyVarCheck_Error {}) <> _ = e + _ <> e@(TyVarCheck_Error {}) = e + TyVarCheck_Promote l1 c1 <> TyVarCheck_Promote l2 c2 = + TyVarCheck_Promote + (combineMaybe minTcLevel l1 l2) + (combineMaybe const c1 c2) -- pick one 'ConcreteTvOrigin' arbitrarily + +combineMaybe :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a +combineMaybe _ Nothing r = r +combineMaybe _ r Nothing = r +combineMaybe f (Just a) (Just b) = Just (f a b) +instance Monoid TyVarCheckResult where + mempty = TyVarCheck_Success + checkTyVar :: forall a. TyEqFlags a -> TcTyVar -> TcM (PuResult a Reduction) -checkTyVar (TEF { tef_lhs = lhs, tef_unifying = unifying, tef_occurs = occ_prob }) occ_tv - = case lhs of - TyFamLHS {} -> success -- Nothing to do if the LHS is a type-family - TyVarLHS lhs_tv -> check_tv unifying lhs_tv +checkTyVar flags@(TEF { tef_task = task }) occ_tv + = case task of + TEFTyFam {} -> success -- Nothing to do if the LHS is a type-family + TEFTyVar mb_occ mb_lc mb_conc -> check_tv mb_occ mb_lc mb_conc where lvl_occ = tcTyVarLevel occ_tv success = okCheckRefl (mkTyVarTy occ_tv) --------------------- - check_tv NotUnifying lhs_tv - = simple_occurs_check lhs_tv - -- We need an occurs-check here, but no level check - -- See Note [Promotion and level-checking] wrinkle (W1) - - check_tv (Unifying info lvl prom) lhs_tv + check_tv mb_occ mb_lc mb_conc = do { mb_done <- isFilledMetaTyVar_maybe occ_tv ; case mb_done of Just {} -> success @@ -3466,71 +3623,94 @@ checkTyVar (TEF { tef_lhs = lhs, tef_unifying = unifying, tef_occurs = occ_prob -- a second time; we don't want to re-promote it! -- Remember, the entire process started with a fully zonked type - Nothing -> check_unif info lvl prom lhs_tv } + Nothing -> + do_rhs_checks $ + -- Occurs check + [ simple_occurs_check tv occ_prob | (tv, occ_prob) <- maybeToList mb_occ ] + ++ + -- Level check + [ lvl_check lc | lc <- maybeToList mb_lc ] + ++ + -- Concreteness check + [ conc_check conc | conc <- maybeToList mb_conc ] + } --------------------- - -- We are in the Unifying branch of AreUnifying; and occ_tv is unfilled - check_unif :: MetaInfo -> TcLevel -> LevelCheck - -> TcTyVar -> TcM (PuResult a Reduction) - check_unif lhs_tv_info lhs_tv_lvl prom lhs_tv - | isConcreteInfo lhs_tv_info - , not (isConcreteTyVar occ_tv) - = if can_make_concrete occ_tv - then promote lhs_tv lhs_tv_info lhs_tv_lvl - else failCheckWith (cteProblem cteConcrete) - + simple_occurs_check :: Name -> CheckTyEqProblem -> TyVarCheckResult + simple_occurs_check lhs_tv occ_prob + | lhs_tv == tyVarName occ_tv || check_kind (tyVarKind occ_tv) + = TyVarCheck_Error (cteProblem occ_prob) + | otherwise + = TyVarCheck_Success + where (check_kind, _) = mkOccFolders lhs_tv + conc_check :: ConcreteTvOrigin -> TyVarCheckResult + conc_check conc_orig + | not (isConcreteTyVar occ_tv) + = if isMetaTyVar occ_tv + then TyVarCheck_Promote Nothing (Just conc_orig) + else TyVarCheck_Error (cteProblem cteConcrete) + | otherwise + = TyVarCheck_Success + lvl_check :: (TcLevel, LevelCheck) -> TyVarCheckResult + lvl_check (lhs_tv_lvl, lc) | lvl_occ `strictlyDeeperThan` lhs_tv_lvl - = case prom of - LC_None -> pprPanic "check_unif" (ppr lhs_tv $$ ppr occ_tv) - LC_Check -> failCheckWith (cteProblem cteSkolemEscape) + = case lc of + LC_Check -> TyVarCheck_Error (cteProblem cteSkolemEscape) LC_Promote {} - | isSkolemTyVar occ_tv -> failCheckWith (cteProblem cteSkolemEscape) - | otherwise -> promote lhs_tv lhs_tv_info lhs_tv_lvl - - | otherwise - = simple_occurs_check lhs_tv - - --------------------- - simple_occurs_check lhs_tv - | lhs_tv == occ_tv || check_kind (tyVarKind occ_tv) - = failCheckWith (cteProblem occ_prob) + | isSkolemTyVar occ_tv -> TyVarCheck_Error (cteProblem cteSkolemEscape) + | otherwise -> TyVarCheck_Promote (Just lhs_tv_lvl) Nothing | otherwise - = success - where - (check_kind, _) = mkOccFolders lhs_tv + = TyVarCheck_Success - --------------------- - can_make_concrete occ_tv = case tcTyVarDetails occ_tv of - MetaTv { mtv_info = info } -> case info of - ConcreteTv {} -> True - TauTv {} -> True - _ -> False - _ -> False -- Don't attempt to make other type variables concrete - -- (e.g. SkolemTv, TyVarTv, CycleBreakerTv, RuntimeUnkTv). + -- Combine the results of individual checks. See 'TyVarCheckResult'. + do_rhs_checks :: [TyVarCheckResult] -> TcM (PuResult a Reduction) + do_rhs_checks checks = + case mconcat checks of + TyVarCheck_Success -> success + TyVarCheck_Promote mb_lvl mb_conc -> promote mb_lvl mb_conc + TyVarCheck_Error cte_prob -> failCheckWith cte_prob --------------------- - -- occ_tv is definitely a MetaTyVar - promote lhs_tv lhs_tv_info lhs_tv_lvl + -- occ_tv is definitely a MetaTyVar; we need to promote it/make it concrete + promote :: Maybe TcLevel -> Maybe ConcreteTvOrigin -> TcM (PuResult a Reduction) + promote mb_lhs_tv_lvl mb_conc | MetaTv { mtv_info = info_occ, mtv_tclvl = lvl_occ } <- tcTyVarDetails occ_tv - = do { let new_info | isConcreteInfo lhs_tv_info = lhs_tv_info - | otherwise = info_occ - new_lvl = lhs_tv_lvl `minTcLevel` lvl_occ - -- c[conc,3] ~ p[tau,2]: want to clone p:=p'[conc,2] - -- c[tau,2] ~ p[tau,3]: want to clone p:=p'[tau,2] + = do { let new_info | Just conc <- mb_conc = ConcreteTv conc + | otherwise = info_occ + new_lvl = + case mb_lhs_tv_lvl of + Nothing -> lvl_occ + Just lhs_tv_lvl -> lhs_tv_lvl `minTcLevel` lvl_occ + -- c[conc,3] ~ p[tau,2]: want to clone p:=p'[conc,2] + -- c[tau,2] ~ p[tau,3]: want to clone p:=p'[tau,2] -- Check the kind of occ_tv - ; reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfType (tyVarKind occ_tv)) - - ; if cterHasNoProblem reason -- Successfully promoted - then do { new_tv_ty <- promote_meta_tyvar new_info new_lvl occ_tv - ; okCheckRefl new_tv_ty } - else failCheckWith reason } + -- + -- This is important for several reasons: + -- + -- 1. To ensure there is no occurs check or skolem-escape + -- in the kind of occ_tv. + -- 2. If the LHS is a concrete type variable and the RHS is an + -- unfilled meta-tyvar, we need to ensure that the kind of + -- 'occ_tv' is concrete. Test cases: T23051, T23176. + ; let occ_kind = tyVarKind occ_tv + ; kind_result <- checkTyEqRhs flags occ_kind + ; traceTc "checkTyVar: kind check" $ + vcat [ text "occ_tv:" <+> ppr occ_tv <+> dcolon <+> ppr occ_kind + , text "checkTyEqRHS result:" <+> pprPur kind_result + ] + ; for kind_result $ \ kind_redn -> + do { let kind_co = reductionCoercion kind_redn + new_kind = reductionReducedType kind_redn + ; new_tv_ty <- promote_meta_tyvar new_info new_lvl (setTyVarKind occ_tv new_kind) + ; return $ mkGReflLeftRedn Nominal new_tv_ty (mkSymCo kind_co) + } } | otherwise = pprPanic "promote" (ppr occ_tv) ------------------------- checkPromoteFreeVars :: CheckTyEqProblem -- What occurs check problem to report - -> TcTyVar -> TcLevel + -> Name -> TcLevel -> TyCoVarSet -> TcM CheckTyEqResult -- Check this set of TyCoVars for -- (a) occurs check @@ -3540,11 +3720,11 @@ checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl vs ; return (mconcat oks) } where do_one :: TyCoVar -> TcM CheckTyEqResult - do_one v | isCoVar v = return cteOK - | lhs_tv == v = return (cteProblem occ_prob) - | no_promotion = return cteOK - | not (isMetaTyVar v) = return (cteProblem cteSkolemEscape) - | otherwise = promote_one v + do_one v | isCoVar v = return cteOK + | tyVarName v == lhs_tv = return (cteProblem occ_prob) + | no_promotion = return cteOK + | not (isMetaTyVar v) = return (cteProblem cteSkolemEscape) + | otherwise = promote_one v where no_promotion = not (tcTyVarLevel v `strictlyDeeperThan` lhs_tv_lvl) @@ -3606,3 +3786,119 @@ checkTopShape info xi _ -> False CycleBreakerTv -> False -- We never unify these _ -> True + +-------------------------------------------------------------------------------- +-- Making a type concrete. + +-- | Try to turn the provided type into a concrete type, by ensuring +-- unfilled metavariables are appropriately marked as concrete. +-- +-- Returns a coercion whose RHS is a zonked type which is "as concrete as possible", +-- and a collection of Wanted equality constraints that are necessary to make +-- the type concrete. +-- +-- For example, for an input @TYPE a[sk]@ we will return a coercion with RHS +-- @TYPE gamma[conc]@ together with the Wanted equality constraint @a ~# gamma at . +-- +-- INVARIANT: the RHS type of the returned coercion is equal to the input type, +-- up to zonking and the returned Wanted equality constraints. +-- +-- INVARIANT: if this function returns an empty list of constraints +-- then the RHS type of the returned coercion is concrete, +-- in the sense of Note [Concrete types]. +makeTypeConcrete :: FastString -> ConcreteTvOrigin + -> TcType -> TcM (TcCoercion, Cts) +makeTypeConcrete occ_fs conc_orig ty = + do { traceTc "makeTypeConcrete {" $ + vcat [ text "ty:" <+> ppr ty ] + + -- To make a type 'ty' concrete, we query what would happen were we + -- to try unifying + -- + -- alpha[conc] ~# ty + -- + -- for a fresh concrete metavariable 'alpha'. + -- + -- We do this by calling 'checkTyEqRhs' with suitable 'TyEqFlags'. + -- NB: we don't actually need to create a fresh concrete metavariable + -- in order to call 'checkTyEqRhs'. + ; let ty_eq_flags = + TEF { tef_task = + TEFTyVar + { tefTyVar_occursCheck = Nothing + -- LHS is a fresh meta-tyvar: no occurs check needed + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Just conc_orig + } + , tef_fam_app = TEFA_Fail + } + + -- NB: 'checkTyEqRhs' expects a fully zonked type as input. + ; ty' <- liftZonkM $ zonkTcType ty + ; pu_res <- checkTyEqRhs @() ty_eq_flags ty' + -- NB: 'checkTyEqRhs' will also check the kind, thus upholding the + -- invariant that the kind of a concrete type must also be a concrete type. + + ; (cts, final_co) <- + case pu_res of + PuOK _ redn -> + do { traceTc "makeTypeConcrete: unifier success" $ + vcat [ text "ty:" <+> ppr ty <+> dcolon <+> ppr (typeKind ty) + , text "redn:" <+> ppr redn + ] + ; return (emptyBag, mkSymCo $ reductionCoercion redn) + -- NB: the unifier returns a 'Reduction' with the concrete + -- type on the left, but we want a coercion with it on the + -- right; so we use 'mkSymCo'. + } + PuFail _prob -> + do { traceTc "makeTypeConcrete: unifier failure" $ + vcat [ text "ty:" <+> ppr ty <+> dcolon <+> ppr (typeKind ty) + , text "problem:" <+> ppr _prob + ] + -- We failed to make 'ty' concrete. In order to continue + -- typechecking, we proceed as follows: + -- + -- - create a new concrete metavariable alpha[conc] + -- - emit the equality @ty ~# alpha[conc]@. + -- + -- This equality will eventually get reported as insoluble + -- to the user. + + -- The kind of a concrete metavariable must itself be concrete, + -- so we need to do a concreteness check on the kind first. + ; let ki = typeKind ty + ; (kind_co, kind_cts) <- + if isConcreteType ki + then return (mkNomReflCo ki, emptyBag) + else makeTypeConcrete occ_fs conc_orig ki + + -- Now create the new concrete metavariable. + ; conc_tv <- newConcreteTyVar conc_orig occ_fs (coercionRKind kind_co) + ; let conc_ty = mkTyVarTy conc_tv + pty = mkEqPredRole Nominal ty' conc_ty + ; hole <- newCoercionHoleO orig pty + ; loc <- getCtLocM orig (Just KindLevel) + ; let ct = mkNonCanonical + $ CtWanted { ctev_pred = pty + , ctev_dest = HoleDest hole + , ctev_loc = loc + , ctev_rewriters = emptyRewriterSet } + ; return (kind_cts S.<> unitBag ct, HoleCo hole) + } + + ; traceTc "makeTypeConcrete }" $ + vcat [ text "ty :" <+> _ppr_ty ty + , text "ty':" <+> _ppr_ty ty' + , text "final_co:" <+> _ppr_co final_co ] + + ; return (final_co, cts) + } + where + + _ppr_ty ty = ppr ty <+> dcolon <+> ppr (typeKind ty) + _ppr_co co = ppr co <+> dcolon <+> parens (_ppr_ty (coercionLKind co)) <+> text "~#" <+> parens (_ppr_ty (coercionRKind co)) + + orig :: CtOrigin + orig = case conc_orig of + ConcreteFRR frr_orig -> FRROrigin frr_orig ===================================== compiler/GHC/Tc/Utils/Unify.hs-boot ===================================== @@ -1,11 +1,15 @@ module GHC.Tc.Utils.Unify where import GHC.Prelude -import GHC.Core.Type ( Mult ) -import GHC.Tc.Utils.TcType ( TcTauType ) -import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Evidence ( TcCoercion ) -import GHC.Tc.Types.Origin ( CtOrigin, TypedThing ) +import GHC.Core.Type ( Mult ) +import GHC.Tc.Utils.TcType ( TcTauType ) +import GHC.Tc.Types ( TcM ) +import GHC.Tc.Types.Constraint ( Cts ) +import GHC.Tc.Types.Evidence ( TcCoercion ) +import GHC.Tc.Types.Origin ( CtOrigin, TypedThing ) +import GHC.Tc.Utils.TcType ( TcType, ConcreteTvOrigin ) + +import GHC.Data.FastString ( FastString ) -- This boot file exists only to tie the knot between @@ -15,3 +19,6 @@ unifyType :: Maybe TypedThing -> TcTauType -> TcTauType -> TcM TcCoerci unifyInvisibleType :: TcTauType -> TcTauType -> TcM TcCoercion tcSubMult :: CtOrigin -> Mult -> Mult -> TcM () + +makeTypeConcrete :: FastString -> ConcreteTvOrigin + -> TcType -> TcM (TcCoercion, Cts) ===================================== hie.yaml ===================================== @@ -5,4 +5,4 @@ # cradle: {bios: {program: "./hadrian/hie-bios.bat"}} # # The format is documented here - https://github.com/mpickering/hie-bios -cradle: {bios: {program: "./hadrian/hie-bios"}} +cradle: {bios: {program: "./hadrian/hie-bios.bat"}} ===================================== testsuite/tests/rep-poly/RepPolyInferPatBind.stderr ===================================== @@ -1,4 +1,3 @@ - RepPolyInferPatBind.hs:21:1: error: [GHC-55287] The binder ‘x’ does not have a fixed runtime representation. Its type is: @@ -8,9 +7,8 @@ RepPolyInferPatBind.hs:21:2: error: [GHC-55287] • The pattern binding does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘c0’ - because the former is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T In the pattern: x :: T In a pattern binding: (x :: T) = x + ===================================== testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr ===================================== @@ -1,12 +1,10 @@ - RepPolyInferPatSyn.hs:22:16: error: [GHC-55287] • The pattern synonym argument pattern does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘c0’ - because the former is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T In the pattern: a :: T In the declaration for pattern synonym ‘P’ + ===================================== testsuite/tests/rep-poly/RepPolyTuple3.stderr ===================================== @@ -1,6 +1,6 @@ - RepPolyTuple3.hs:21:9: error: [GHC-18872] • Couldn't match kind ‘FloatRep’ with ‘IntRep’ arising from a representation-polymorphism check • In the expression: (#,#) @RR @RR x In an equation for ‘bar’: bar x = (#,#) @RR @RR x + ===================================== testsuite/tests/rep-poly/T23153.stderr ===================================== @@ -1,4 +1,3 @@ - T23153.hs:8:1: error: [GHC-52083] The argument ‘(h ())’ of ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. @@ -13,3 +12,4 @@ T23153.hs:8:1: error: [GHC-52083] The argument ‘(h ())’ of ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. Suggested fix: Add a type signature. + ===================================== testsuite/tests/rep-poly/T23154.stderr ===================================== @@ -1,3 +1,7 @@ +T23154.hs:7:1: error: [GHC-52083] + The first pattern in the equation for ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. T23154.hs:7:1: error: [GHC-52083] The first pattern in the equation for ‘f’ @@ -8,3 +12,4 @@ T23154.hs:7:1: error: [GHC-52083] The first pattern in the equation for ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. Suggested fix: Add a type signature. + ===================================== testsuite/tests/simd/should_run/T25658.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\a _ -> a) ===================================== testsuite/tests/simd/should_run/T25658.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (0,11) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -25,6 +25,8 @@ test('word16x8_basic_baseline', [], compile_and_run, ['']) test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) +test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation + # Ensure we set the CPU features we have available. # # This is especially important with the LLVM backend, as LLVM can otherwise ===================================== utils/jsffi/prelude.mjs ===================================== @@ -63,7 +63,9 @@ const setImmediate = await (async () => { // deno if (globalThis.Deno) { - return (await import("node:timers")).setImmediate; + try { + return (await import("node:timers")).setImmediate; + } catch {} } // https://developer.mozilla.org/en-US/docs/Web/API/Scheduler/postTask View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f2c72de016016a10ecd85e8a1df3fa0d84d24cd...a97d26156d7b894cf11c29195d2bfa419d7eea60 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f2c72de016016a10ecd85e8a1df3fa0d84d24cd...a97d26156d7b894cf11c29195d2bfa419d7eea60 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 16:18:04 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 17 Jan 2025 11:18:04 -0500 Subject: [Git][ghc/ghc][master] Use checkTyEqRhs to make types concrete Message-ID: <678a82bad46cc_c53a131ad08573ba@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 17 changed files: - compiler/GHC/Core/Type.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Unify.hs-boot - hie.yaml - testsuite/tests/rep-poly/RepPolyInferPatBind.stderr - testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr - testsuite/tests/rep-poly/RepPolyTuple3.stderr - testsuite/tests/rep-poly/T23153.stderr - testsuite/tests/rep-poly/T23154.stderr Changes: ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -235,7 +235,8 @@ module GHC.Core.Type ( -- * Kinds isTYPEorCONSTRAINT, - isConcreteType, isFixedRuntimeRepKind, + isConcreteType, + isFixedRuntimeRepKind ) where import GHC.Prelude @@ -2869,12 +2870,14 @@ isFixedRuntimeRepKind k isConcreteType :: Type -> Bool isConcreteType = isConcreteTypeWith emptyVarSet -isConcreteTypeWith :: TyVarSet -> Type -> Bool +-- | Like 'isConcreteType', but allows passing in a set of 'TyVar's that +-- should be considered concrete. +-- -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. --- For this "With" version we pass in a set of TyVars to be considered --- concrete. This supports mkSynonymTyCon, which needs to test the RHS --- for concreteness, under the assumption that the binders are instantiated --- to concrete types +isConcreteTypeWith :: TyVarSet -> Type -> Bool +-- This version, with a 'TyVarSet' argument, supports 'mkSynonymTyCon', +-- which needs to test the RHS for concreteness, under the assumption that +-- the binders are instantiated to concrete types isConcreteTypeWith conc_tvs = go where go (TyVarTy tv) = isConcreteTyVar tv || tv `elemVarSet` conc_tvs @@ -2888,6 +2891,7 @@ isConcreteTypeWith conc_tvs = go go CastTy{} = False go CoercionTy{} = False + go_tc :: TyCon -> [Type] -> Bool go_tc tc tys | isForgetfulSynTyCon tc -- E.g. type S a = Int -- Then (S x) is concrete even if x isn't @@ -2903,7 +2907,6 @@ isConcreteTypeWith conc_tvs = go | otherwise -- E.g. type families = False - {- %************************************************************************ %* * ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -1048,8 +1048,7 @@ reportNotConcreteErrs ctxt errs@(err0:_) | frr_errs <- go frr_errs errs = case err of NCE_FRR - { nce_frr_origin = frr_orig - , nce_reasons = _not_conc } -> + { nce_frr_origin = frr_orig } -> FRR_Info { frr_info_origin = frr_orig , frr_info_not_concrete = Nothing } ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -1202,8 +1202,7 @@ tc_inst_forall_arg conc_tvs (tvb, inner_ty) hs_ty -> -- Example: user wrote e.g. (#,#) @(F Bool) for a type family F. -- Emit [W] F Bool ~ kappa[conc] and pretend the user wrote (#,#) @kappa. - do { mco <- unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0 - ; return $ case mco of { MRefl -> ty_arg0; MCo co -> coercionRKind co } } + coercionRKind <$> unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0 ; let fun_ty = mkForAllTy tvb inner_ty in_scope = mkInScopeSet (tyCoVarsOfTypes [fun_ty, ty_arg]) ===================================== compiler/GHC/Tc/Solver/Default.hs ===================================== @@ -440,7 +440,7 @@ defaultEquality ct where try_default_tv lhs_tv rhs_ty - | MetaTv { mtv_info = info, mtv_tclvl = lvl } <- tcTyVarDetails lhs_tv + | MetaTv { mtv_info = info } <- tcTyVarDetails lhs_tv , tyVarKind lhs_tv `tcEqType` typeKind rhs_ty , checkTopShape info rhs_ty -- Do not test for touchability of lhs_tv; that is the whole point! @@ -449,14 +449,13 @@ defaultEquality ct -- checkTyEqRhs: check that we can in fact unify lhs_tv := rhs_ty -- See Note [Defaulting equalities] - -- LC_Promote: promote deeper unification variables (DE4) - -- LC_Promote True: ...including under type families (DE5) - ; let flags :: TyEqFlags () - flags = TEF { tef_foralls = False - , tef_fam_app = TEFA_Recurse - , tef_lhs = TyVarLHS lhs_tv - , tef_unifying = Unifying info lvl (LC_Promote True) - , tef_occurs = cteInsolubleOccurs } + ; let task :: TEFTask + task = unifyingLHSMetaTyVar_TEFTask lhs_tv (LC_Promote True) + -- LC_Promote: promote deeper unification variables (DE4) + -- LC_Promote True: ...including under type families (DE5) + flags :: TyEqFlags () + flags = TEF { tef_task = task + , tef_fam_app = TEFA_Recurse } ; res :: PuResult () Reduction <- wrapTcS (checkTyEqRhs flags rhs_ty) ; case res of ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -201,6 +201,7 @@ import GHC.Exts (oneShot) import Control.Monad import Data.IORef import Data.List ( mapAccumL ) +import Data.Maybe ( isJust ) import Data.Foldable import qualified Data.Semigroup as S import GHC.Types.SrcLoc @@ -2122,7 +2123,7 @@ checkTouchableTyVarEq ev lhs_tv rhs _ -> pprPanic "checkTouchableTyVarEq" (ppr lhs_tv) -- lhs_tv should be a meta-tyvar - is_concrete_lhs_tv = isConcreteInfo lhs_tv_info + is_concrete_lhs_tv = isJust $ concreteInfo_maybe lhs_tv_info check_rhs rhs -- Crucial special case for alpha ~ F tys @@ -2134,11 +2135,9 @@ checkTouchableTyVarEq ev lhs_tv rhs | otherwise = checkTyEqRhs flags rhs - flags = TEF { tef_foralls = False -- isRuntimeUnkSkol lhs_tv - , tef_fam_app = mkTEFA_Break ev NomEq break_wanted - , tef_unifying = Unifying lhs_tv_info lhs_tv_lvl (LC_Promote False) - , tef_lhs = TyVarLHS lhs_tv - , tef_occurs = cteInsolubleOccurs } + flags = TEF { tef_task = unifyingLHSMetaTyVar_TEFTask lhs_tv (LC_Promote False) + , tef_fam_app = mkTEFA_Break ev NomEq break_wanted + } arg_flags = famAppArgFlags flags @@ -2147,7 +2146,8 @@ checkTouchableTyVarEq ev lhs_tv rhs -- Occurs check or skolem escape; so flatten = do { let fam_app_kind = typeKind fam_app ; reason <- checkPromoteFreeVars cteInsolubleOccurs - lhs_tv lhs_tv_lvl (tyCoVarsOfType fam_app_kind) + (tyVarName lhs_tv) lhs_tv_lvl + (tyCoVarsOfType fam_app_kind) ; if not (cterHasNoProblem reason) -- Failed to promote free vars then failCheckWith reason else @@ -2210,19 +2210,15 @@ checkTypeEq ev eq_rel lhs rhs arg_flags = famAppArgFlags given_flags given_flags :: TyEqFlags (TcTyVar,TcType) - given_flags = TEF { tef_lhs = lhs - , tef_foralls = False - , tef_unifying = NotUnifying - , tef_fam_app = mkTEFA_Break ev eq_rel break_given - , tef_occurs = occ_prob } + given_flags = TEF { tef_task = notUnifying_TEFTask occ_prob lhs + , tef_fam_app = mkTEFA_Break ev eq_rel break_given + } -- TEFA_Break used for: [G] a ~ Maybe (F a) -- or [W] F a ~ Maybe (F a) - wanted_flags = TEF { tef_lhs = lhs - , tef_foralls = False - , tef_unifying = NotUnifying - , tef_fam_app = TEFA_Recurse - , tef_occurs = occ_prob } + wanted_flags = TEF { tef_task = notUnifying_TEFTask occ_prob lhs + , tef_fam_app = TEFA_Recurse + } -- TEFA_Recurse: see Note [Don't cycle-break Wanteds when not unifying] -- occ_prob: see Note [Occurs check and representational equality] @@ -2289,7 +2285,7 @@ where both sides are TyFamLHSs. We don't want to flatten that RHS to Instead we'd like to say "occurs-check" and swap LHS and RHS, which yields a canonical constraint [G] G (...(F ty)...) ~ F ty -That tents to rewrite a big type to smaller one. This happens in T15703, +That tends to rewrite a big type to smaller one. This happens in T15703, where we had: [G] Pure g ~ From1 (To1 (Pure g)) Making a loop breaker and rewriting left to right just makes much bigger ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -52,7 +52,6 @@ module GHC.Tc.Types.Constraint ( Hole(..), HoleSort(..), isOutOfScopeHole, DelayedError(..), NotConcreteError(..), - NotConcreteReason(..), WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, @@ -132,7 +131,6 @@ import Data.Coerce import qualified Data.Semigroup as S import Control.Monad ( msum, when ) import Data.Maybe ( mapMaybe, isJust ) -import Data.List.NonEmpty ( NonEmpty ) -- these are for CheckTyEqResult import Data.Word ( Word8 ) @@ -435,30 +433,8 @@ data NotConcreteError -- ^ Where did this check take place? , nce_frr_origin :: FixedRuntimeRepOrigin -- ^ Which representation-polymorphism check did we perform? - , nce_reasons :: NonEmpty NotConcreteReason - -- ^ Why did the check fail? } --- | Why did we decide that a type was not concrete? -data NotConcreteReason - -- | The type contains a 'TyConApp' of a non-concrete 'TyCon'. - -- - -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. - = NonConcreteTyCon TyCon [TcType] - - -- | The type contains a type variable that could not be made - -- concrete (e.g. a skolem type variable). - | NonConcretisableTyVar TyVar - - -- | The type contains a cast. - | ContainsCast TcType TcCoercionN - - -- | The type contains a forall. - | ContainsForall ForAllTyBinder TcType - - -- | The type contains a 'CoercionTy'. - | ContainsCoercionTy TcCoercion - instance Outputable NotConcreteError where ppr (NCE_FRR { nce_frr_origin = frr_orig }) = text "NCE_FRR" <+> parens (ppr (frr_type frr_orig)) ===================================== compiler/GHC/Tc/Utils/Concrete.hs ===================================== @@ -19,39 +19,35 @@ module GHC.Tc.Utils.Concrete import GHC.Prelude import GHC.Builtin.Names ( unsafeCoercePrimName ) -import GHC.Builtin.Types ( liftedTypeKindTyCon, unliftedTypeKindTyCon ) +import GHC.Builtin.Types -import GHC.Core.Coercion ( coToMCo, mkCastTyMCo - , mkGReflRightMCo, mkNomReflCo ) -import GHC.Core.TyCo.Rep ( Type(..), MCoercion(..) ) -import GHC.Core.TyCon ( isConcreteTyCon ) -import GHC.Core.Type ( isConcreteType, typeKind, mkFunTy) +import GHC.Core.Coercion +import GHC.Core.TyCo.Rep +import GHC.Core.Type -import GHC.Tc.Types.Constraint ( NotConcreteError(..), NotConcreteReason(..) ) -import GHC.Tc.Types.Evidence ( Role(..), TcCoercionN, TcMCoercionN ) +import GHC.Data.Bag + +import GHC.Tc.Types.Constraint +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Origin import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType -import GHC.Tc.Utils.TcMType +import {-# SOURCE #-} GHC.Tc.Utils.Unify import GHC.Types.Basic ( TypeOrKind(KindLevel) ) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Types.Name import GHC.Types.Name.Env -import GHC.Types.Var ( tyVarKind, tyVarName ) +import GHC.Types.Var import GHC.Utils.Misc ( HasDebugCallStack ) import GHC.Utils.Outputable +import GHC.Utils.Panic import GHC.Data.FastString ( FastString, fsLit ) - import Control.Monad ( void ) import Data.Functor ( ($>) ) -import Data.List.NonEmpty ( NonEmpty((:|)) ) -import Control.Monad.Trans.Class ( lift ) -import Control.Monad.Trans.Writer.CPS ( WriterT, runWriterT, tell ) {- Note [Concrete overview] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -221,7 +217,6 @@ other type variables, a 'ConcreteTv' type variable is a type variable which can only be unified with a concrete type (in the sense of Note [Concrete types]). INVARIANT: the kind of a concrete metavariable is concrete. - This invariant is upheld at the time of creation of a new concrete metavariable. Concrete metavariables are useful for representation-polymorphism checks: @@ -632,7 +627,7 @@ hasFixedRuntimeRep :: HasDebugCallStack -- That is, @ty'@ has a syntactically fixed RuntimeRep -- in the sense of Note [Fixed RuntimeRep]. hasFixedRuntimeRep frr_ctxt ty = - checkFRR_with (unifyConcrete (fsLit "cx") . ConcreteFRR) frr_ctxt ty + checkFRR_with (fmap (fmap coToMCo) . unifyConcrete_kind (fsLit "cx") . ConcreteFRR) frr_ctxt ty -- | Like 'hasFixedRuntimeRep', but we perform an eager syntactic check. -- @@ -700,226 +695,86 @@ checkFRR_with check_kind frr_ctxt ty frr_orig :: FixedRuntimeRepOrigin frr_orig = FixedRuntimeRepOrigin { frr_type = ty, frr_context = frr_ctxt } --- | Ensure that the given type @ty@ can unify with a concrete type, +-- | Ensure that the given kind @ki@ can unify with a concrete type, -- in the sense of Note [Concrete types]. -- --- Returns a coercion @co :: ty ~# conc_ty@, where @conc_ty@ is +-- Returns a coercion @co :: ki ~# conc_ki@, where @conc_ki@ is -- concrete. -- --- If the type is already syntactically concrete, this +-- If the kind is already syntactically concrete, this -- immediately returns a reflexive coercion. Otherwise, -- it creates a new concrete metavariable @concrete_tv@ --- and emits an equality constraint @ty ~# concrete_tv@, +-- and emits an equality constraint @ki ~# concrete_tv@, -- to be handled by the constraint solver. -- +-- Precondition: @ki@ must be of the form @TYPE rep@ or @CONSTRAINT rep at . +unifyConcrete_kind :: HasDebugCallStack + => FastString -- ^ name to use when creating concrete metavariables + -> ConcreteTvOrigin + -> TcKind + -> TcM TcCoercionN +unifyConcrete_kind occ_fs conc_orig ki + | Just (torc, rep) <- sORTKind_maybe ki + = do { let tc = case torc of + TypeLike -> tYPETyCon + ConstraintLike -> cONSTRAINTTyCon + ; rep_co <- unifyConcrete occ_fs conc_orig rep + ; return $ mkTyConAppCo Nominal tc [rep_co] } + | otherwise + = pprPanic "unifyConcrete_kind: kind is not of the form 'TYPE rep' or 'CONSTRAINT rep'" $ + ppr ki <+> dcolon <+> ppr (typeKind ki) + + +-- | Ensure the given type can be unified with +-- a concrete type, in the sense of Note [Concrete types]. +-- +-- Returns a coercion @co :: ty ~# conc_ty@, where @conc_ty@ is +-- concrete. +-- +-- If the type is already syntactically concrete, this +-- immediately returns a reflexive coercion. +-- Otherwise, it will create new concrete metavariables and emit +-- new Wanted equality constraints, to be handled by the constraint solver. +-- -- Invariant: the kind of the supplied type must be concrete. -- -- We assume the provided type is already at the kind-level -- (this only matters for error messages). -unifyConcrete :: HasDebugCallStack - => FastString -> ConcreteTvOrigin -> TcType -> TcM TcMCoercionN +unifyConcrete :: FastString -> ConcreteTvOrigin -> TcType -> TcM TcCoercionN unifyConcrete occ_fs conc_orig ty - = do { (ty, errs) <- makeTypeConcrete conc_orig ty - ; case errs of - -- We were able to make the type fully concrete. - { [] -> return MRefl - -- The type could not be made concrete; perhaps it contains - -- a skolem type variable, a type family application, ... - -- - -- Create a new ConcreteTv metavariable @concrete_tv@ - -- and unify @ty ~# concrete_tv at . - ; _ -> - do { conc_tv <- newConcreteTyVar conc_orig occ_fs ki - -- NB: newConcreteTyVar asserts that 'ki' is concrete. - ; coToMCo <$> emitWantedEq orig KindLevel Nominal ty (mkTyVarTy conc_tv) } } } - where - ki :: TcKind - ki = typeKind ty - orig :: CtOrigin - orig = case conc_orig of - ConcreteFRR frr_orig -> FRROrigin frr_orig + = do { (co, cts) <- makeTypeConcrete occ_fs conc_orig ty + ; emitSimples cts + ; return co } --- | Ensure that the given type is concrete. +-- | Ensure that the given kind @ki@ is concrete. -- -- This is an eager syntactic check, and never defers --- any work to the constraint solver. --- --- Invariant: the kind of the supplied type must be concrete. --- Invariant: the output type is equal to the input type, --- up to zonking. +-- any work to the constraint solver. However, +-- it may perform unification. -- --- We assume the provided type is already at the kind-level --- (this only matters for error messages). +-- Invariant: the output type is equal to the input type, up to zonking. ensureConcrete :: HasDebugCallStack => FixedRuntimeRepOrigin - -> TcType - -> TcM TcType -ensureConcrete frr_orig ty - = do { traceTc "ensureConcrete {" (ppr frr_orig $$ ppr ty) - ; (ty', errs) <- makeTypeConcrete conc_orig ty - ; case errs of - { err:errs -> - do { traceTc "ensureConcrete } failure" $ - vcat [ text "ty:" <+> ppr ty - , text "ty':" <+> ppr ty' ] + -> TcKind + -> TcM TcKind +ensureConcrete frr_orig ki + = do { (co, cts) <- makeTypeConcrete (fsLit "cx") conc_orig ki + ; let trace_msg = vcat [ text "ty: " <+> ppr ki + , text "co:" <+> ppr co ] + ; if isEmptyBag cts + then traceTc "ensureConcrete } success" trace_msg + else do { traceTc "ensureConcrete } failure" trace_msg ; loc <- getCtLocM (FRROrigin frr_orig) (Just KindLevel) ; emitNotConcreteError $ NCE_FRR { nce_loc = loc - , nce_frr_origin = frr_orig - , nce_reasons = err :| errs } - } - ; [] -> - traceTc "ensureConcrete } success" $ - vcat [ text "ty: " <+> ppr ty - , text "ty':" <+> ppr ty' ] } - ; return ty' } + , nce_frr_origin = frr_orig } + } + ; return $ coercionRKind co } where conc_orig :: ConcreteTvOrigin conc_orig = ConcreteFRR frr_orig -{-*********************************************************************** -%* * - Making a type concrete -%* * -%************************************************************************ - -Note [Unifying concrete metavariables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Unifying concrete metavariables (as defined in Note [ConcreteTv]) is not -an all-or-nothing affair as it is for other sorts of metavariables. - -Consider the following unification problem in which all metavariables -are unfilled (and ignoring any TcLevel considerations): - - alpha[conc] ~# TYPE (TupleRep '[ beta[conc], IntRep, gamma[tau] ]) - -We can't immediately unify `alpha` with the RHS, because the RHS is not -a concrete type (in the sense of Note [Concrete types]). Instead, we -proceed as follows: - - - create a fresh concrete metavariable variable `gamma'[conc]`, - - write gamma[tau] := gamma'[conc], - - write alpha[conc] := TYPE (TupleRep '[ beta[conc], IntRep, gamma'[conc] ]). - -Thus, in general, to unify `alpha[conc] ~# rhs`, we first try to turn -`rhs` into a concrete type (see the 'makeTypeConcrete' function). -If this succeeds, resulting in a concrete type `rhs'`, we simply fill -`alpha[conc] := rhs'`. If it fails, then syntactic unification fails. - -Example 1: - - alpha[conc] ~# TYPE (TupleRep '[ beta[conc], IntRep, gamma[tau] ]) - - We proceed by filling metavariables: - - gamma[tau] := gamma[conc] - alpha[conc] := TYPE (TupleRep '[ beta[conc], IntRep, gamma[conc] ]) - - This successfully unifies alpha. - -Example 2: - - For a type family `F :: Type -> Type`: - - delta[conc] ~# TYPE (SumRep '[ zeta[tau], a[sk], F omega[tau] ]) - - We write zeta[tau] := zeta[conc], and then fail, providing the following - two reasons: - - - `a[sk]` is not a concrete type variable, so the overall type - cannot be concrete - - `F` is not a concrete type constructor, in the sense of - Note [Concrete types]. So we keep it as is; in particular, - we /should not/ try to make its argument `omega[tau]` into - a ConcreteTv. - - Note that making zeta concrete allows us to propagate information. - For example, after more typechecking, we might try to unify - `zeta ~# rr[sk]`. If we made zeta a ConcreteTv, we will report - this unsolved equality using the 'ConcreteTvOrigin' stored in zeta[conc]. - This allows us to report ALL the problems in a representation-polymorphism - check (instead of only a non-empty subset). --} - --- | Try to turn the provided type into a concrete type, by ensuring --- unfilled metavariables are appropriately marked as concrete. --- --- Returns a zonked type which is "as concrete as possible", and --- a list of problems encountered when trying to make it concrete. --- --- INVARIANT: the returned type is equal to the input type, up to zonking. --- INVARIANT: if this function returns an empty list of 'NotConcreteReasons', --- then the returned type is concrete, in the sense of Note [Concrete types]. -makeTypeConcrete :: ConcreteTvOrigin -> TcType -> TcM (TcType, [NotConcreteReason]) --- TODO: it could be worthwhile to return enough information to continue solving. --- Consider unifying `alpha[conc] ~# TupleRep '[ beta[tau], F Int ]` for --- a type family 'F'. --- This function will concretise `beta[tau] := beta[conc]` and return --- that `TupleRep '[ beta[conc], F Int ]` is not concrete because of the --- type family application `F Int`. But we could decompose by setting --- alpha := TupleRep '[ beta, gamma[conc] ] and emitting `[W] gamma[conc] ~ F Int`. -makeTypeConcrete conc_orig ty = - do { res@(ty', _) <- runWriterT $ go ty - ; traceTc "makeTypeConcrete" $ - vcat [ text "ty:" <+> ppr ty - , text "ty':" <+> ppr ty' ] - ; return res } - where - go :: TcType -> WriterT [NotConcreteReason] TcM TcType - go ty - | Just ty <- coreView ty - = go ty - | isConcreteType ty - = pure ty - go ty@(TyVarTy tv) -- not a ConcreteTv (already handled above) - = do { mb_filled <- lift $ isFilledMetaTyVar_maybe tv - ; case mb_filled of - { Just ty -> go ty - ; Nothing - | isMetaTyVar tv - , TauTv <- metaTyVarInfo tv - -> -- Change the MetaInfo to ConcreteTv, but retain the TcLevel - do { kind <- go (tyVarKind tv) - ; let occ_fs = occNameFS (getOccName tv) - -- occ_fs: preserve the occurrence name of the original tyvar - -- This helps in error messages - ; lift $ - do { conc_tv <- setTcLevel (tcTyVarLevel tv) $ - newConcreteTyVar conc_orig occ_fs kind - ; let conc_ty = mkTyVarTy conc_tv - ; liftZonkM $ writeMetaTyVar tv conc_ty - ; return conc_ty } } - | otherwise - -- Don't attempt to make other type variables concrete - -- (e.g. SkolemTv, TyVarTv, CycleBreakerTv, RuntimeUnkTv). - -> bale_out ty (NonConcretisableTyVar tv) } } - go ty@(TyConApp tc tys) - | isConcreteTyCon tc - = mkTyConApp tc <$> mapM go tys - | otherwise - = bale_out ty (NonConcreteTyCon tc tys) - go (FunTy af w ty1 ty2) - = do { w <- go w - ; ty1 <- go ty1 - ; ty2 <- go ty2 - ; return $ mkFunTy af w ty1 ty2 } - go (AppTy ty1 ty2) - = do { ty1 <- go ty1 - ; ty2 <- go ty2 - ; return $ mkAppTy ty1 ty2 } - go ty@(LitTy {}) - = return ty - go ty@(CastTy cast_ty kco) - = bale_out ty (ContainsCast cast_ty kco) - go ty@(ForAllTy tcv body) - = bale_out ty (ContainsForall tcv body) - go ty@(CoercionTy co) - = bale_out ty (ContainsCoercionTy co) - - bale_out :: TcType -> NotConcreteReason -> WriterT [NotConcreteReason] TcM TcType - bale_out ty reason = do { tell [reason]; return ty } - {-*********************************************************************** %* * Concrete type variables of Ids ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -755,7 +755,7 @@ newNamedAnonMetaTyVar tyvar_name meta_info kind = do { name <- newMetaTyVarName tyvar_name ; details <- newMetaDetails meta_info ; let tyvar = mkTcTyVar name kind details - ; traceTc "newAnonMetaTyVar" (ppr tyvar) + ; traceTc "newAnonMetaTyVar" (ppr tyvar <+> dcolon <+> ppr kind) ; return tyvar } -- makes a new skolem tv ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -53,7 +53,7 @@ module GHC.Tc.Utils.TcType ( isImmutableTyVar, isSkolemTyVar, isMetaTyVar, isMetaTyVarTy, isTyVarTy, tcIsTcTyVar, isTyVarTyVar, isOverlappableTyVar, isTyConableTyVar, ConcreteTvOrigin(..), isConcreteTyVar_maybe, isConcreteTyVar, - isConcreteTyVarTy, isConcreteTyVarTy_maybe, isConcreteInfo, + isConcreteTyVarTy, isConcreteTyVarTy_maybe, concreteInfo_maybe, ConcreteTyVars, noConcreteTyVars, isAmbiguousTyVar, isCycleBreakerTyVar, metaTyVarRef, metaTyVarInfo, isFlexi, isIndirect, isRuntimeUnkSkol, @@ -1266,9 +1266,9 @@ isConcreteTyVar_maybe tv | otherwise = Nothing -isConcreteInfo :: MetaInfo -> Bool -isConcreteInfo (ConcreteTv {}) = True -isConcreteInfo _ = False +concreteInfo_maybe :: MetaInfo -> Maybe ConcreteTvOrigin +concreteInfo_maybe (ConcreteTv conc_orig) = Just conc_orig +concreteInfo_maybe _ = Nothing -- | Is this type variable a concrete type variable, i.e. -- it is a metavariable with 'ConcreteTv' 'MetaInfo'? ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1,8 +1,13 @@ +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeApplications #-} + {- (c) The University of Glasgow 2006 @@ -28,6 +33,7 @@ module GHC.Tc.Utils.Unify ( swapOverTyVars, touchabilityAndShapeTest, checkTopShape, lhsPriority, UnifyEnv(..), updUEnvLoc, setUEnvRole, uType, + makeTypeConcrete, -------------------------------- -- Holes @@ -41,8 +47,11 @@ module GHC.Tc.Utils.Unify ( checkTyEqRhs, recurseIntoTyConApp, PuResult(..), failCheckWith, okCheckRefl, mapCheck, - TyEqFlags(..), TyEqFamApp(..), AreUnifying(..), LevelCheck(..), FamAppBreaker, + TyEqFlags(..), TEFTask(..), + notUnifying_TEFTask, unifyingLHSMetaTyVar_TEFTask, + LevelCheck(..), TyEqFamApp(..), FamAppBreaker, famAppArgFlags, checkPromoteFreeVars, + simpleUnifyCheck, UnifyCheckCaller(..), fillInferResult, @@ -54,7 +63,7 @@ import GHC.Hs import GHC.Tc.Errors.Types ( ErrCtxtMsg(..) ) import GHC.Tc.Errors.Ppr ( pprErrCtxtMsg ) -import GHC.Tc.Utils.Concrete ( hasFixedRuntimeRep, hasFixedRuntimeRep_syntactic ) +import GHC.Tc.Utils.Concrete import GHC.Tc.Utils.Env import GHC.Tc.Utils.Instantiate import GHC.Tc.Utils.Monad @@ -94,11 +103,13 @@ import GHC.Utils.Panic import GHC.Driver.DynFlags import GHC.Data.Bag -import GHC.Data.FastString( fsLit ) +import GHC.Data.FastString import Control.Monad +import Data.Maybe (maybeToList, isJust) import Data.Monoid as DM ( Any(..) ) import qualified Data.Semigroup as S ( (<>) ) +import Data.Traversable (for) {- ********************************************************************* * * @@ -2927,7 +2938,7 @@ simpleUnifyCheck caller lhs_tv rhs = go rhs where - !(occ_in_ty, occ_in_co) = mkOccFolders lhs_tv + !(occ_in_ty, occ_in_co) = mkOccFolders (tyVarName lhs_tv) lhs_tv_lvl = tcTyVarLevel lhs_tv lhs_tv_is_concrete = isConcreteTyVar lhs_tv @@ -2974,7 +2985,7 @@ simpleUnifyCheck caller lhs_tv rhs go (LitTy {}) = True -mkOccFolders :: TcTyVar -> (TcType -> Bool, TcCoercion -> Bool) +mkOccFolders :: Name -> (TcType -> Bool, TcCoercion -> Bool) -- These functions return True -- * if lhs_tv occurs (incl deeply, in the kind of variable) -- * if there is a coercion hole @@ -2987,7 +2998,7 @@ mkOccFolders lhs_tv = (getAny . check_ty, getAny . check_co) , tcf_hole = do_hole , tcf_tycobinder = do_bndr } - do_tcv is v = Any (not (v `elemVarSet` is) && v == lhs_tv) + do_tcv is v = Any (not (v `elemVarSet` is) && tyVarName v == lhs_tv) `mappend` check_ty (varType v) do_bndr is tcv _faf = extendVarSet is tcv @@ -3058,10 +3069,7 @@ reductionCoercion is Refl. See `canEqCanLHSFinish_no_unification`. data PuResult a b = PuFail CheckTyEqResult | PuOK (Bag a) b - -instance Functor (PuResult a) where - fmap _ (PuFail prob) = PuFail prob - fmap f (PuOK cts x) = PuOK cts (f x) + deriving stock (Functor, Foldable, Traversable) instance Applicative (PuResult a) where pure x = PuOK emptyBag x @@ -3100,82 +3108,192 @@ mapCheck f xs -- | Options describing how to deal with a type equality -- in the pure unifier. See 'checkTyEqRhs' data TyEqFlags a - = TEF { tef_foralls :: Bool -- Allow foralls - , tef_lhs :: CanEqLHS -- LHS of the constraint - , tef_unifying :: AreUnifying -- Always NotUnifying if tef_lhs is TyFamLHS + = TEF { tef_task :: TEFTask + -- ^ LHS structure, and which checks to perform on the RHS , tef_fam_app :: TyEqFamApp a - , tef_occurs :: CheckTyEqProblem } -- Soluble or insoluble occurs check + -- ^ How to deal with type family applications + } + +-- | The structure of the LHS and which checks to perform in 'checkTyEqRhs', +-- for an equality @lhs ~# rhs at . +-- +-- See Note [TEFTask]. +data TEFTask + -- | LHS is a type family application; we are not unifying. + = TEFTyFam + { tefTyFam_occursCheck :: CheckTyEqProblem + -- ^ The 'CheckTyEqProblem' to report for occurs-check failures + -- (soluble or insoluble) + , tefTyFam_tyCon :: TyCon + , tefTyFam_args :: [Type] + } + -- | LHS is a 'TyVar'. + | TEFTyVar + { tefTyVar_occursCheck :: Maybe (Name, CheckTyEqProblem) + -- ^ Occurs check: LHS 'TyVar' 'Name', + -- and which 'CheckTyEqProblem' to report for occurs-check failures + -- (soluble or insoluble) + , tefTyVar_levelCheck :: Maybe (TcLevel, LevelCheck) + -- ^ Level check: LHS 'TyVar' 'TcLevel', + -- and which 'LevelCheck' to perform + , tefTyVar_concreteCheck :: Maybe ConcreteTvOrigin + -- ^ Concreteness check: LHS 'TyVar' 'ConcreteTvOrigin' + -- to use for the check + } + +{- Note [TEFTask] +~~~~~~~~~~~~~~~~~ +When we call the pure unifier, e.g. through 'checkTyEqRhs', we can decide what +kind of checks the unifier performs via the 'TyEqFlags' argument. In particular, +when the LHS type in a unification is a type variable, we might want to perform +different checks; this is achieved using the 'TEFTyVar' constructor to 'TEFTask': + + 1. LHS is a skolem tyvar, or an untouchable meta-tyvar. + We are not unifying; we only want to perform occurs-checks. + + TEFTyVar + { tefTyVar_occursCheck = Just ... + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Nothing + } + + 2. LHS is a touchable meta-tyvar. + We are unifying; we want to perform an occurs check, a level check, + and a concreteness check (when the meta-tyvar is a ConcreteTv). + + TEFTyVar + { tefTyVar_occursCheck = Just ... + , tefTyVar_levelCheck = Just ... + , tefTyVar_concreteCheck = isConcreteTyVar_maybe lhs_tv + } + + 3. LHS is a fresh ConcreteTv meta-tyvar (see call to 'checkTyEqRhs' in + 'makeTypeConcrete'). We are unifying; we only want to perform + a concreteness check. + + TEFTyVar + { tefTyVar_occursCheck = Nothing + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Just ... + } +-} + +-- | Create a "not unifying" 'TEFTask' from a 'CanEqLHS'. +-- +-- See use-case (1) in Note [TEFTask]. +notUnifying_TEFTask :: CheckTyEqProblem -> CanEqLHS -> TEFTask +notUnifying_TEFTask occ_prob = \case + TyFamLHS tc tys -> + TEFTyFam occ_prob tc tys + TyVarLHS tv -> + TEFTyVar + { tefTyVar_occursCheck = Just (tyVarName tv, occ_prob) + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Nothing + } + -- We need an occurs-check here, but no level check. + -- See Note [Promotion and level-checking] wrinkle (W1) + +-- | Create "unifying" 'TEFTask' from a 'TyVarLHS'. +-- +-- Invariant: the argument 'TyVar' is a 'MetaTv'. +unifyingLHSMetaTyVar_TEFTask :: TyVar -> LevelCheck -> TEFTask +unifyingLHSMetaTyVar_TEFTask lhs_tv lc = + TEFTyVar + { tefTyVar_occursCheck = Just (tyVarName lhs_tv, cteInsolubleOccurs) + , tefTyVar_levelCheck = Just (tcTyVarLevel lhs_tv, lc) + , tefTyVar_concreteCheck = isConcreteTyVar_maybe lhs_tv + } + +-- | Do we want to perform a concreteness check in 'checkTyEqRhs'? +tefTaskConcrete_maybe :: TEFTask -> Maybe ConcreteTvOrigin +tefTaskConcrete_maybe (TEFTyFam {}) = Nothing +tefTaskConcrete_maybe (TEFTyVar { tefTyVar_concreteCheck = conc }) = conc + +instance Outputable TEFTask where + ppr = \case + TEFTyFam occ tc tys -> + text "TEFTyFam" <+> ppr occ <+> ppr (mkTyConApp tc tys) + TEFTyVar mb_occ mb_lc mb_conc -> + text "TEFTyVar" <+> hcat (punctuate comma fields) + where + fields = [ text "OccursCheck:" <+> ppr tv | (tv, _) <- maybeToList mb_occ ] + ++ + [ text "LevelCheck:" <+> ppr lc | lc <- maybeToList mb_lc ] + ++ + [ text "ConcreteCheck" | isJust mb_conc ] -- | What to do when encountering a type-family application while processing -- a type equality in the pure unifier. -- -- See Note [Family applications in canonical constraints] data TyEqFamApp a - = TEFA_Fail -- Always fail - | TEFA_Recurse -- Just recurse - | TEFA_Break (FamAppBreaker a) -- Recurse, but replace with cycle breaker if fails, - -- using the FamAppBreaker - -data AreUnifying - = Unifying - MetaInfo -- MetaInfo of the LHS tyvar (which is a meta-tyvar) - TcLevel -- Level of the LHS tyvar - LevelCheck - - | NotUnifying -- Not attempting to unify + = TEFA_Fail -- ^ Always fail + | TEFA_Recurse -- ^ Just recurse + | TEFA_Break (FamAppBreaker a) -- ^ Recurse, but replace with cycle breaker if fails, + -- using the FamAppBreaker +-- | What level check to perform, in a call to the pure unifier? data LevelCheck - = LC_None -- Level check not needed: we should never encounter - -- a tyvar at deeper level than the LHS - - | LC_Check -- Do a level check between the LHS tyvar and the occurrence tyvar - -- Fail if the level check fails - - | LC_Promote -- Do a level check between the LHS tyvar and the occurrence tyvar - -- If the level check fails, and the occurrence is a unification - -- variable, promote it - Bool -- False <=> don't promote under type families (the common case) - -- True <=> promote even under type families - -- see Note [Defaulting equalities] in GHC.Tc.Solver + = LC_Check -- ^ Do a level check between the LHS tyvar and the occurrence tyvar. + -- + -- Fail if the level check fails. + + | LC_Promote Bool + -- ^ Do a level check between the LHS tyvar and the occurrence tyvar. + -- + -- If the level check fails, and the occurrence is a unification + -- variable, promote it. + -- + -- - False <=> don't promote under type families (the common case) + -- - True <=> promote even under type families + -- (see Note [Defaulting equalities] in GHC.Tc.Solver) instance Outputable (TyEqFlags a) where ppr (TEF { .. }) = text "TEF" <> braces ( - vcat [ text "tef_foralls =" <+> ppr tef_foralls - , text "tef_lhs =" <+> ppr tef_lhs - , text "tef_unifying =" <+> ppr tef_unifying - , text "tef_fam_app =" <+> ppr tef_fam_app - , text "tef_occurs =" <+> ppr tef_occurs ]) + vcat [ text "tef_task =" <+> ppr tef_task + , text "tef_fam_app =" <+> ppr tef_fam_app ]) instance Outputable (TyEqFamApp a) where ppr TEFA_Fail = text "TEFA_Fail" ppr TEFA_Recurse = text "TEFA_Recurse" ppr (TEFA_Break {}) = text "TEFA_Break" -instance Outputable AreUnifying where - ppr NotUnifying = text "NotUnifying" - ppr (Unifying mi lvl lc) = text "Unifying" <+> - braces (ppr mi <> comma <+> ppr lvl <> comma <+> ppr lc) - instance Outputable LevelCheck where - ppr LC_None = text "LC_None" ppr LC_Check = text "LC_Check" ppr (LC_Promote b) = text "LC_Promote" <> ppWhen b (text "(deep)") +-- | Adjust the 'TyEqFlags' when going undter a type family: +-- +-- 1. Only the outer family application gets the loop-breaker treatment +-- 2. Weaken level checks for tyvar promotion. For example, in @[W] alpha[2] ~ Maybe (F beta[3])@, +-- do not promote @beta[3]@, instead promote @(F beta[3])@. +-- 3. Occurs checks become potentially soluble (after additional type family +-- reductions). famAppArgFlags :: TyEqFlags a -> TyEqFlags a --- Adjust the flags when going undter a type family --- Only the outer family application gets the loop-breaker treatment --- Ditto tyvar promotion. E.g. --- [W] alpha[2] ~ Maybe (F beta[3]) --- Do not promote beta[3]; instead promote (F beta[3]) -famAppArgFlags flags@(TEF { tef_unifying = unifying }) - = flags { tef_fam_app = TEFA_Recurse - , tef_unifying = zap_promotion unifying - , tef_occurs = cteSolubleOccurs } - -- tef_occurs: under a type family, an occurs check is not definitely-insoluble +famAppArgFlags flags@(TEF { tef_task = task }) + = flags { tef_fam_app = TEFA_Recurse -- (1) + , tef_task = fam_app_task task + } where - zap_promotion (Unifying info lvl (LC_Promote deeply)) - | not deeply = Unifying info lvl LC_Check - zap_promotion unifying = unifying + fam_app_task :: TEFTask -> TEFTask + fam_app_task task = case task of + TEFTyFam {} -> + task + { tefTyFam_occursCheck = cteSolubleOccurs -- (3) + } + TEFTyVar { tefTyVar_occursCheck = mb_occ, tefTyVar_levelCheck = mb_lc } -> + task + { tefTyVar_occursCheck = + fmap (\ (tv, _old_occ_prob) -> (tv, cteSolubleOccurs)) mb_occ -- (3) + , tefTyVar_levelCheck = + fmap (\ (lvl, lc) -> (lvl, zap_lc lc)) mb_lc -- (2) + } + zap_lc = \case + LC_Promote deeply + | not deeply + -> LC_Check + lc -> lc type FamAppBreaker a = TcType -> TcM (PuResult a Reduction) -- Given a family-application ty, return a Reduction :: ty ~ cvb @@ -3196,7 +3314,6 @@ checkTyEqRhs flags ty FunTy {ft_af = af, ft_mult = w, ft_arg = a, ft_res = r} | isInvisibleFunArg af -- e.g. Num a => blah - , not (tef_foralls flags) -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) | otherwise -> do { w_res <- checkTyEqRhs flags w @@ -3215,38 +3332,48 @@ checkTyEqRhs flags ty CoercionTy co -> do { co_res <- checkCo flags co ; return (mkReflCoRedn Nominal <$> co_res) } - ForAllTy {} - | tef_foralls flags -> okCheckRefl ty - | otherwise -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) - + ForAllTy {} -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) ------------------- checkCo :: TyEqFlags a -> Coercion -> TcM (PuResult a Coercion) -- See Note [checkCo] -checkCo (TEF { tef_lhs = TyFamLHS {} }) co - = return (pure co) - -checkCo (TEF { tef_lhs = TyVarLHS lhs_tv - , tef_unifying = unifying - , tef_occurs = occ_prob }) co - -- Check for coercion holes, if unifying - -- See (COERCION-HOLE) in Note [Unification preconditions] - | hasCoercionHoleCo co - = failCheckWith (cteProblem cteCoercionHole) - - -- Occurs check (can promote) - | Unifying _ lhs_tv_lvl (LC_Promote {}) <- unifying - = do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co) - ; if cterHasNoProblem reason - then return (pure co) - else failCheckWith reason } - - -- Occurs check (no promotion) - | lhs_tv `elemVarSet` tyCoVarsOfCo co - = failCheckWith (cteProblem occ_prob) +checkCo (TEF { tef_task = task }) co = + case task of + TEFTyFam {} -> + -- NB: 'TEFTyFam' case means we are not unifying. + return (pure co) + TEFTyVar + { tefTyVar_concreteCheck = mb_conc + , tefTyVar_levelCheck = mb_lc + , tefTyVar_occursCheck = mb_occ + } + -- Coercions cannot appear in concrete types. + -- + -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. + | Just {} <- mb_conc + -> failCheckWith (cteProblem cteConcrete) + + -- Check for coercion holes, if unifying. + -- See (COERCION-HOLE) in Note [Unification preconditions] + | Just {} <- mb_lc -- equivalent to "we are unifying"; see Note [TEFTask] + , hasCoercionHoleCo co + -> failCheckWith (cteProblem cteCoercionHole) + + -- Occurs check (can promote) + | Just (lhs_tv, occ_prob) <- mb_occ + , Just (lhs_tv_lvl, LC_Promote {}) <- mb_lc + -> do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co) + ; if cterHasNoProblem reason + then return (pure co) + else failCheckWith reason } + + -- Occurs check (no promotion) + | Just (lhs_tv, occ_prob) <- mb_occ + , nameUnique lhs_tv `elemVarSetByKey` tyCoVarsOfCo co + -> failCheckWith (cteProblem occ_prob) - | otherwise - = return (pure co) + | otherwise + -> return (pure co) {- Note [checkCo] ~~~~~~~~~~~~~~~~~ @@ -3364,7 +3491,7 @@ If we have [W] alpha ~ Maybe (F (G alpha)) checkTyConApp :: TyEqFlags a -> TcType -> TyCon -> [TcType] -> TcM (PuResult a Reduction) -checkTyConApp flags@(TEF { tef_unifying = unifying, tef_foralls = foralls_ok }) +checkTyConApp flags@(TEF { tef_task = task }) tc_app tc tys | isTypeFamilyTyCon tc , let arity = tyConArity tc @@ -3383,11 +3510,10 @@ checkTyConApp flags@(TEF { tef_unifying = unifying, tef_foralls = foralls_ok }) -- See Note [Forgetful synonyms in checkTyConApp] = checkTyEqRhs flags ty' - | not (isTauTyCon tc || foralls_ok) + | not (isTauTyCon tc) = failCheckWith impredicativeProblem - | Unifying info _ _ <- unifying - , isConcreteInfo info + | Just {} <- tefTaskConcrete_maybe task , not (isConcreteTyCon tc) = failCheckWith (cteProblem cteConcrete) @@ -3404,21 +3530,19 @@ checkFamApp :: TyEqFlags a -> TcType -> TyCon -> [TcType] -- Saturated family application -> TcM (PuResult a Reduction) -- See Note [Family applications in canonical constraints] -checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob - , tef_fam_app = fam_app_flag, tef_lhs = lhs }) +checkFamApp flags@(TEF { tef_task = task, tef_fam_app = fam_app_flag }) fam_app tc tys = case fam_app_flag of TEFA_Fail -> failCheckWith (cteProblem cteTypeFamily) -- Occurs check: F ty ~ ...(F ty)... - _ | TyFamLHS lhs_tc lhs_tys <- lhs + _ | TEFTyFam occ_prob lhs_tc lhs_tys <- task , tcEqTyConApps lhs_tc lhs_tys tc tys -> case fam_app_flag of TEFA_Recurse -> failCheckWith (cteProblem occ_prob) TEFA_Break breaker -> breaker fam_app - _ | Unifying lhs_info _ _ <- unifying - , isConcreteInfo lhs_info + _ | Just {} <- tefTaskConcrete_maybe task -> case fam_app_flag of TEFA_Recurse -> failCheckWith (cteProblem cteConcrete) TEFA_Break breaker -> breaker fam_app @@ -3441,22 +3565,55 @@ checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob arg_flags = famAppArgFlags flags ------------------- + +-- | The result of a single check in 'checkTyVar', such as a concreteness check +-- or a level check. +data TyVarCheckResult + -- | Check succeded; nothing else to do. + = TyVarCheck_Success + -- | Check succeeded, but requires an additional promotion. + -- + -- Invariant: at least one of the fields is not 'Nothing'. + | TyVarCheck_Promote + (Maybe TcLevel) + -- ^ @Just lvl@ <=> 'TyVar' needs to be promoted to @lvl@ + (Maybe ConcreteTvOrigin) + -- ^ @Just conc_orig@ <=> 'TyVar' needs to be make concrete + -- | Check failed with some 'CheckTyEqProblem's. + -- + -- Invariant: the 'CheckTyEqResult' is not 'cteOK'. + | TyVarCheck_Error CheckTyEqResult + +instance Semigroup TyVarCheckResult where + TyVarCheck_Success <> r = r + r <> TyVarCheck_Success = r + TyVarCheck_Error e1 <> TyVarCheck_Error e2 = + TyVarCheck_Error (e1 S.<> e2) + e@(TyVarCheck_Error {}) <> _ = e + _ <> e@(TyVarCheck_Error {}) = e + TyVarCheck_Promote l1 c1 <> TyVarCheck_Promote l2 c2 = + TyVarCheck_Promote + (combineMaybe minTcLevel l1 l2) + (combineMaybe const c1 c2) -- pick one 'ConcreteTvOrigin' arbitrarily + +combineMaybe :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a +combineMaybe _ Nothing r = r +combineMaybe _ r Nothing = r +combineMaybe f (Just a) (Just b) = Just (f a b) +instance Monoid TyVarCheckResult where + mempty = TyVarCheck_Success + checkTyVar :: forall a. TyEqFlags a -> TcTyVar -> TcM (PuResult a Reduction) -checkTyVar (TEF { tef_lhs = lhs, tef_unifying = unifying, tef_occurs = occ_prob }) occ_tv - = case lhs of - TyFamLHS {} -> success -- Nothing to do if the LHS is a type-family - TyVarLHS lhs_tv -> check_tv unifying lhs_tv +checkTyVar flags@(TEF { tef_task = task }) occ_tv + = case task of + TEFTyFam {} -> success -- Nothing to do if the LHS is a type-family + TEFTyVar mb_occ mb_lc mb_conc -> check_tv mb_occ mb_lc mb_conc where lvl_occ = tcTyVarLevel occ_tv success = okCheckRefl (mkTyVarTy occ_tv) --------------------- - check_tv NotUnifying lhs_tv - = simple_occurs_check lhs_tv - -- We need an occurs-check here, but no level check - -- See Note [Promotion and level-checking] wrinkle (W1) - - check_tv (Unifying info lvl prom) lhs_tv + check_tv mb_occ mb_lc mb_conc = do { mb_done <- isFilledMetaTyVar_maybe occ_tv ; case mb_done of Just {} -> success @@ -3466,71 +3623,94 @@ checkTyVar (TEF { tef_lhs = lhs, tef_unifying = unifying, tef_occurs = occ_prob -- a second time; we don't want to re-promote it! -- Remember, the entire process started with a fully zonked type - Nothing -> check_unif info lvl prom lhs_tv } + Nothing -> + do_rhs_checks $ + -- Occurs check + [ simple_occurs_check tv occ_prob | (tv, occ_prob) <- maybeToList mb_occ ] + ++ + -- Level check + [ lvl_check lc | lc <- maybeToList mb_lc ] + ++ + -- Concreteness check + [ conc_check conc | conc <- maybeToList mb_conc ] + } --------------------- - -- We are in the Unifying branch of AreUnifying; and occ_tv is unfilled - check_unif :: MetaInfo -> TcLevel -> LevelCheck - -> TcTyVar -> TcM (PuResult a Reduction) - check_unif lhs_tv_info lhs_tv_lvl prom lhs_tv - | isConcreteInfo lhs_tv_info - , not (isConcreteTyVar occ_tv) - = if can_make_concrete occ_tv - then promote lhs_tv lhs_tv_info lhs_tv_lvl - else failCheckWith (cteProblem cteConcrete) - + simple_occurs_check :: Name -> CheckTyEqProblem -> TyVarCheckResult + simple_occurs_check lhs_tv occ_prob + | lhs_tv == tyVarName occ_tv || check_kind (tyVarKind occ_tv) + = TyVarCheck_Error (cteProblem occ_prob) + | otherwise + = TyVarCheck_Success + where (check_kind, _) = mkOccFolders lhs_tv + conc_check :: ConcreteTvOrigin -> TyVarCheckResult + conc_check conc_orig + | not (isConcreteTyVar occ_tv) + = if isMetaTyVar occ_tv + then TyVarCheck_Promote Nothing (Just conc_orig) + else TyVarCheck_Error (cteProblem cteConcrete) + | otherwise + = TyVarCheck_Success + lvl_check :: (TcLevel, LevelCheck) -> TyVarCheckResult + lvl_check (lhs_tv_lvl, lc) | lvl_occ `strictlyDeeperThan` lhs_tv_lvl - = case prom of - LC_None -> pprPanic "check_unif" (ppr lhs_tv $$ ppr occ_tv) - LC_Check -> failCheckWith (cteProblem cteSkolemEscape) + = case lc of + LC_Check -> TyVarCheck_Error (cteProblem cteSkolemEscape) LC_Promote {} - | isSkolemTyVar occ_tv -> failCheckWith (cteProblem cteSkolemEscape) - | otherwise -> promote lhs_tv lhs_tv_info lhs_tv_lvl - - | otherwise - = simple_occurs_check lhs_tv - - --------------------- - simple_occurs_check lhs_tv - | lhs_tv == occ_tv || check_kind (tyVarKind occ_tv) - = failCheckWith (cteProblem occ_prob) + | isSkolemTyVar occ_tv -> TyVarCheck_Error (cteProblem cteSkolemEscape) + | otherwise -> TyVarCheck_Promote (Just lhs_tv_lvl) Nothing | otherwise - = success - where - (check_kind, _) = mkOccFolders lhs_tv + = TyVarCheck_Success - --------------------- - can_make_concrete occ_tv = case tcTyVarDetails occ_tv of - MetaTv { mtv_info = info } -> case info of - ConcreteTv {} -> True - TauTv {} -> True - _ -> False - _ -> False -- Don't attempt to make other type variables concrete - -- (e.g. SkolemTv, TyVarTv, CycleBreakerTv, RuntimeUnkTv). + -- Combine the results of individual checks. See 'TyVarCheckResult'. + do_rhs_checks :: [TyVarCheckResult] -> TcM (PuResult a Reduction) + do_rhs_checks checks = + case mconcat checks of + TyVarCheck_Success -> success + TyVarCheck_Promote mb_lvl mb_conc -> promote mb_lvl mb_conc + TyVarCheck_Error cte_prob -> failCheckWith cte_prob --------------------- - -- occ_tv is definitely a MetaTyVar - promote lhs_tv lhs_tv_info lhs_tv_lvl + -- occ_tv is definitely a MetaTyVar; we need to promote it/make it concrete + promote :: Maybe TcLevel -> Maybe ConcreteTvOrigin -> TcM (PuResult a Reduction) + promote mb_lhs_tv_lvl mb_conc | MetaTv { mtv_info = info_occ, mtv_tclvl = lvl_occ } <- tcTyVarDetails occ_tv - = do { let new_info | isConcreteInfo lhs_tv_info = lhs_tv_info - | otherwise = info_occ - new_lvl = lhs_tv_lvl `minTcLevel` lvl_occ - -- c[conc,3] ~ p[tau,2]: want to clone p:=p'[conc,2] - -- c[tau,2] ~ p[tau,3]: want to clone p:=p'[tau,2] + = do { let new_info | Just conc <- mb_conc = ConcreteTv conc + | otherwise = info_occ + new_lvl = + case mb_lhs_tv_lvl of + Nothing -> lvl_occ + Just lhs_tv_lvl -> lhs_tv_lvl `minTcLevel` lvl_occ + -- c[conc,3] ~ p[tau,2]: want to clone p:=p'[conc,2] + -- c[tau,2] ~ p[tau,3]: want to clone p:=p'[tau,2] -- Check the kind of occ_tv - ; reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfType (tyVarKind occ_tv)) - - ; if cterHasNoProblem reason -- Successfully promoted - then do { new_tv_ty <- promote_meta_tyvar new_info new_lvl occ_tv - ; okCheckRefl new_tv_ty } - else failCheckWith reason } + -- + -- This is important for several reasons: + -- + -- 1. To ensure there is no occurs check or skolem-escape + -- in the kind of occ_tv. + -- 2. If the LHS is a concrete type variable and the RHS is an + -- unfilled meta-tyvar, we need to ensure that the kind of + -- 'occ_tv' is concrete. Test cases: T23051, T23176. + ; let occ_kind = tyVarKind occ_tv + ; kind_result <- checkTyEqRhs flags occ_kind + ; traceTc "checkTyVar: kind check" $ + vcat [ text "occ_tv:" <+> ppr occ_tv <+> dcolon <+> ppr occ_kind + , text "checkTyEqRHS result:" <+> pprPur kind_result + ] + ; for kind_result $ \ kind_redn -> + do { let kind_co = reductionCoercion kind_redn + new_kind = reductionReducedType kind_redn + ; new_tv_ty <- promote_meta_tyvar new_info new_lvl (setTyVarKind occ_tv new_kind) + ; return $ mkGReflLeftRedn Nominal new_tv_ty (mkSymCo kind_co) + } } | otherwise = pprPanic "promote" (ppr occ_tv) ------------------------- checkPromoteFreeVars :: CheckTyEqProblem -- What occurs check problem to report - -> TcTyVar -> TcLevel + -> Name -> TcLevel -> TyCoVarSet -> TcM CheckTyEqResult -- Check this set of TyCoVars for -- (a) occurs check @@ -3540,11 +3720,11 @@ checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl vs ; return (mconcat oks) } where do_one :: TyCoVar -> TcM CheckTyEqResult - do_one v | isCoVar v = return cteOK - | lhs_tv == v = return (cteProblem occ_prob) - | no_promotion = return cteOK - | not (isMetaTyVar v) = return (cteProblem cteSkolemEscape) - | otherwise = promote_one v + do_one v | isCoVar v = return cteOK + | tyVarName v == lhs_tv = return (cteProblem occ_prob) + | no_promotion = return cteOK + | not (isMetaTyVar v) = return (cteProblem cteSkolemEscape) + | otherwise = promote_one v where no_promotion = not (tcTyVarLevel v `strictlyDeeperThan` lhs_tv_lvl) @@ -3606,3 +3786,119 @@ checkTopShape info xi _ -> False CycleBreakerTv -> False -- We never unify these _ -> True + +-------------------------------------------------------------------------------- +-- Making a type concrete. + +-- | Try to turn the provided type into a concrete type, by ensuring +-- unfilled metavariables are appropriately marked as concrete. +-- +-- Returns a coercion whose RHS is a zonked type which is "as concrete as possible", +-- and a collection of Wanted equality constraints that are necessary to make +-- the type concrete. +-- +-- For example, for an input @TYPE a[sk]@ we will return a coercion with RHS +-- @TYPE gamma[conc]@ together with the Wanted equality constraint @a ~# gamma at . +-- +-- INVARIANT: the RHS type of the returned coercion is equal to the input type, +-- up to zonking and the returned Wanted equality constraints. +-- +-- INVARIANT: if this function returns an empty list of constraints +-- then the RHS type of the returned coercion is concrete, +-- in the sense of Note [Concrete types]. +makeTypeConcrete :: FastString -> ConcreteTvOrigin + -> TcType -> TcM (TcCoercion, Cts) +makeTypeConcrete occ_fs conc_orig ty = + do { traceTc "makeTypeConcrete {" $ + vcat [ text "ty:" <+> ppr ty ] + + -- To make a type 'ty' concrete, we query what would happen were we + -- to try unifying + -- + -- alpha[conc] ~# ty + -- + -- for a fresh concrete metavariable 'alpha'. + -- + -- We do this by calling 'checkTyEqRhs' with suitable 'TyEqFlags'. + -- NB: we don't actually need to create a fresh concrete metavariable + -- in order to call 'checkTyEqRhs'. + ; let ty_eq_flags = + TEF { tef_task = + TEFTyVar + { tefTyVar_occursCheck = Nothing + -- LHS is a fresh meta-tyvar: no occurs check needed + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Just conc_orig + } + , tef_fam_app = TEFA_Fail + } + + -- NB: 'checkTyEqRhs' expects a fully zonked type as input. + ; ty' <- liftZonkM $ zonkTcType ty + ; pu_res <- checkTyEqRhs @() ty_eq_flags ty' + -- NB: 'checkTyEqRhs' will also check the kind, thus upholding the + -- invariant that the kind of a concrete type must also be a concrete type. + + ; (cts, final_co) <- + case pu_res of + PuOK _ redn -> + do { traceTc "makeTypeConcrete: unifier success" $ + vcat [ text "ty:" <+> ppr ty <+> dcolon <+> ppr (typeKind ty) + , text "redn:" <+> ppr redn + ] + ; return (emptyBag, mkSymCo $ reductionCoercion redn) + -- NB: the unifier returns a 'Reduction' with the concrete + -- type on the left, but we want a coercion with it on the + -- right; so we use 'mkSymCo'. + } + PuFail _prob -> + do { traceTc "makeTypeConcrete: unifier failure" $ + vcat [ text "ty:" <+> ppr ty <+> dcolon <+> ppr (typeKind ty) + , text "problem:" <+> ppr _prob + ] + -- We failed to make 'ty' concrete. In order to continue + -- typechecking, we proceed as follows: + -- + -- - create a new concrete metavariable alpha[conc] + -- - emit the equality @ty ~# alpha[conc]@. + -- + -- This equality will eventually get reported as insoluble + -- to the user. + + -- The kind of a concrete metavariable must itself be concrete, + -- so we need to do a concreteness check on the kind first. + ; let ki = typeKind ty + ; (kind_co, kind_cts) <- + if isConcreteType ki + then return (mkNomReflCo ki, emptyBag) + else makeTypeConcrete occ_fs conc_orig ki + + -- Now create the new concrete metavariable. + ; conc_tv <- newConcreteTyVar conc_orig occ_fs (coercionRKind kind_co) + ; let conc_ty = mkTyVarTy conc_tv + pty = mkEqPredRole Nominal ty' conc_ty + ; hole <- newCoercionHoleO orig pty + ; loc <- getCtLocM orig (Just KindLevel) + ; let ct = mkNonCanonical + $ CtWanted { ctev_pred = pty + , ctev_dest = HoleDest hole + , ctev_loc = loc + , ctev_rewriters = emptyRewriterSet } + ; return (kind_cts S.<> unitBag ct, HoleCo hole) + } + + ; traceTc "makeTypeConcrete }" $ + vcat [ text "ty :" <+> _ppr_ty ty + , text "ty':" <+> _ppr_ty ty' + , text "final_co:" <+> _ppr_co final_co ] + + ; return (final_co, cts) + } + where + + _ppr_ty ty = ppr ty <+> dcolon <+> ppr (typeKind ty) + _ppr_co co = ppr co <+> dcolon <+> parens (_ppr_ty (coercionLKind co)) <+> text "~#" <+> parens (_ppr_ty (coercionRKind co)) + + orig :: CtOrigin + orig = case conc_orig of + ConcreteFRR frr_orig -> FRROrigin frr_orig ===================================== compiler/GHC/Tc/Utils/Unify.hs-boot ===================================== @@ -1,11 +1,15 @@ module GHC.Tc.Utils.Unify where import GHC.Prelude -import GHC.Core.Type ( Mult ) -import GHC.Tc.Utils.TcType ( TcTauType ) -import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Evidence ( TcCoercion ) -import GHC.Tc.Types.Origin ( CtOrigin, TypedThing ) +import GHC.Core.Type ( Mult ) +import GHC.Tc.Utils.TcType ( TcTauType ) +import GHC.Tc.Types ( TcM ) +import GHC.Tc.Types.Constraint ( Cts ) +import GHC.Tc.Types.Evidence ( TcCoercion ) +import GHC.Tc.Types.Origin ( CtOrigin, TypedThing ) +import GHC.Tc.Utils.TcType ( TcType, ConcreteTvOrigin ) + +import GHC.Data.FastString ( FastString ) -- This boot file exists only to tie the knot between @@ -15,3 +19,6 @@ unifyType :: Maybe TypedThing -> TcTauType -> TcTauType -> TcM TcCoerci unifyInvisibleType :: TcTauType -> TcTauType -> TcM TcCoercion tcSubMult :: CtOrigin -> Mult -> Mult -> TcM () + +makeTypeConcrete :: FastString -> ConcreteTvOrigin + -> TcType -> TcM (TcCoercion, Cts) ===================================== hie.yaml ===================================== @@ -5,4 +5,4 @@ # cradle: {bios: {program: "./hadrian/hie-bios.bat"}} # # The format is documented here - https://github.com/mpickering/hie-bios -cradle: {bios: {program: "./hadrian/hie-bios"}} +cradle: {bios: {program: "./hadrian/hie-bios.bat"}} ===================================== testsuite/tests/rep-poly/RepPolyInferPatBind.stderr ===================================== @@ -1,4 +1,3 @@ - RepPolyInferPatBind.hs:21:1: error: [GHC-55287] The binder ‘x’ does not have a fixed runtime representation. Its type is: @@ -8,9 +7,8 @@ RepPolyInferPatBind.hs:21:2: error: [GHC-55287] • The pattern binding does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘c0’ - because the former is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T In the pattern: x :: T In a pattern binding: (x :: T) = x + ===================================== testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr ===================================== @@ -1,12 +1,10 @@ - RepPolyInferPatSyn.hs:22:16: error: [GHC-55287] • The pattern synonym argument pattern does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘c0’ - because the former is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T In the pattern: a :: T In the declaration for pattern synonym ‘P’ + ===================================== testsuite/tests/rep-poly/RepPolyTuple3.stderr ===================================== @@ -1,6 +1,6 @@ - RepPolyTuple3.hs:21:9: error: [GHC-18872] • Couldn't match kind ‘FloatRep’ with ‘IntRep’ arising from a representation-polymorphism check • In the expression: (#,#) @RR @RR x In an equation for ‘bar’: bar x = (#,#) @RR @RR x + ===================================== testsuite/tests/rep-poly/T23153.stderr ===================================== @@ -1,4 +1,3 @@ - T23153.hs:8:1: error: [GHC-52083] The argument ‘(h ())’ of ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. @@ -13,3 +12,4 @@ T23153.hs:8:1: error: [GHC-52083] The argument ‘(h ())’ of ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. Suggested fix: Add a type signature. + ===================================== testsuite/tests/rep-poly/T23154.stderr ===================================== @@ -1,3 +1,7 @@ +T23154.hs:7:1: error: [GHC-52083] + The first pattern in the equation for ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. T23154.hs:7:1: error: [GHC-52083] The first pattern in the equation for ‘f’ @@ -8,3 +12,4 @@ T23154.hs:7:1: error: [GHC-52083] The first pattern in the equation for ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. Suggested fix: Add a type signature. + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87e82e2efd72fffefbc9537b5ab86611279e009a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87e82e2efd72fffefbc9537b5ab86611279e009a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 16:19:00 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 17 Jan 2025 11:19:00 -0500 Subject: [Git][ghc/ghc][master] x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# Message-ID: <678a82f47ae4c_c53a14eadb8621f8@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 4 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - + testsuite/tests/simd/should_run/T25658.hs - + testsuite/tests/simd/should_run/T25658.stdout - testsuite/tests/simd/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD II64 (OpReg r) (OpReg dst)) + (MOVD FF64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD II64 (OpReg tmp) (OpReg dst)) + (MOVD FF64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset ===================================== testsuite/tests/simd/should_run/T25658.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\a _ -> a) ===================================== testsuite/tests/simd/should_run/T25658.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (0,11) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -25,6 +25,8 @@ test('word16x8_basic_baseline', [], compile_and_run, ['']) test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) +test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation + # Ensure we set the CPU features we have available. # # This is especially important with the LLVM backend, as LLVM can otherwise View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5a8f35bd5d9735d7846a53bc9d08d8eeb67bccb5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5a8f35bd5d9735d7846a53bc9d08d8eeb67bccb5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 16:57:55 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Fri, 17 Jan 2025 11:57:55 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] 11 commits: Use checkTyEqRhs to make types concrete Message-ID: <678a8c139ef7_f2bb5c1b9c11077@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - c648141b by Patrick at 2025-01-17T16:57:28+00:00 update kcConDecl to also consider the result type in newtype GADT instance - - - - - 903de0b0 by Patrick at 2025-01-17T16:57:28+00:00 peek at the result kind - - - - - 6a24787f by Patrick at 2025-01-17T16:57:28+00:00 test if gadt has UserSuppliedResultKind in lhs, we let tc_res_kind to unify with rhs result kind if not to gain more inference - - - - - 310ea5a0 by Patrick at 2025-01-17T16:57:28+00:00 format and remove getTyConResultKind - - - - - b29be88b by Patrick at 2025-01-17T16:57:28+00:00 format - - - - - 106d22d4 by Patrick at 2025-01-17T16:57:28+00:00 add comment - - - - - 8cc3100a by Patrick at 2025-01-17T16:57:28+00:00 cleanup - - - - - fe01c442 by Patrick at 2025-01-17T16:57:28+00:00 cleanup - - - - - f82cd8a9 by Patrick at 2025-01-17T16:57:28+00:00 update T25611a - - - - - 24 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Unify.hs-boot - hie.yaml - testsuite/tests/indexed-types/should_compile/T25611a.hs - testsuite/tests/rep-poly/RepPolyInferPatBind.stderr - testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr - testsuite/tests/rep-poly/RepPolyTuple3.stderr - testsuite/tests/rep-poly/T23153.stderr - testsuite/tests/rep-poly/T23154.stderr - + testsuite/tests/simd/should_run/T25658.hs - + testsuite/tests/simd/should_run/T25658.stdout - testsuite/tests/simd/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD II64 (OpReg r) (OpReg dst)) + (MOVD FF64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD II64 (OpReg tmp) (OpReg dst)) + (MOVD FF64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -235,7 +235,8 @@ module GHC.Core.Type ( -- * Kinds isTYPEorCONSTRAINT, - isConcreteType, isFixedRuntimeRepKind, + isConcreteType, + isFixedRuntimeRepKind ) where import GHC.Prelude @@ -2869,12 +2870,14 @@ isFixedRuntimeRepKind k isConcreteType :: Type -> Bool isConcreteType = isConcreteTypeWith emptyVarSet -isConcreteTypeWith :: TyVarSet -> Type -> Bool +-- | Like 'isConcreteType', but allows passing in a set of 'TyVar's that +-- should be considered concrete. +-- -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. --- For this "With" version we pass in a set of TyVars to be considered --- concrete. This supports mkSynonymTyCon, which needs to test the RHS --- for concreteness, under the assumption that the binders are instantiated --- to concrete types +isConcreteTypeWith :: TyVarSet -> Type -> Bool +-- This version, with a 'TyVarSet' argument, supports 'mkSynonymTyCon', +-- which needs to test the RHS for concreteness, under the assumption that +-- the binders are instantiated to concrete types isConcreteTypeWith conc_tvs = go where go (TyVarTy tv) = isConcreteTyVar tv || tv `elemVarSet` conc_tvs @@ -2888,6 +2891,7 @@ isConcreteTypeWith conc_tvs = go go CastTy{} = False go CoercionTy{} = False + go_tc :: TyCon -> [Type] -> Bool go_tc tc tys | isForgetfulSynTyCon tc -- E.g. type S a = Int -- Then (S x) is concrete even if x isn't @@ -2903,7 +2907,6 @@ isConcreteTypeWith conc_tvs = go | otherwise -- E.g. type families = False - {- %************************************************************************ %* * ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -1048,8 +1048,7 @@ reportNotConcreteErrs ctxt errs@(err0:_) | frr_errs <- go frr_errs errs = case err of NCE_FRR - { nce_frr_origin = frr_orig - , nce_reasons = _not_conc } -> + { nce_frr_origin = frr_orig } -> FRR_Info { frr_info_origin = frr_orig , frr_info_not_concrete = Nothing } ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -1202,8 +1202,7 @@ tc_inst_forall_arg conc_tvs (tvb, inner_ty) hs_ty -> -- Example: user wrote e.g. (#,#) @(F Bool) for a type family F. -- Emit [W] F Bool ~ kappa[conc] and pretend the user wrote (#,#) @kappa. - do { mco <- unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0 - ; return $ case mco of { MRefl -> ty_arg0; MCo co -> coercionRKind co } } + coercionRKind <$> unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0 ; let fun_ty = mkForAllTy tvb inner_ty in_scope = mkInScopeSet (tyCoVarsOfTypes [fun_ty, ty_arg]) ===================================== compiler/GHC/Tc/Solver/Default.hs ===================================== @@ -440,7 +440,7 @@ defaultEquality ct where try_default_tv lhs_tv rhs_ty - | MetaTv { mtv_info = info, mtv_tclvl = lvl } <- tcTyVarDetails lhs_tv + | MetaTv { mtv_info = info } <- tcTyVarDetails lhs_tv , tyVarKind lhs_tv `tcEqType` typeKind rhs_ty , checkTopShape info rhs_ty -- Do not test for touchability of lhs_tv; that is the whole point! @@ -449,14 +449,13 @@ defaultEquality ct -- checkTyEqRhs: check that we can in fact unify lhs_tv := rhs_ty -- See Note [Defaulting equalities] - -- LC_Promote: promote deeper unification variables (DE4) - -- LC_Promote True: ...including under type families (DE5) - ; let flags :: TyEqFlags () - flags = TEF { tef_foralls = False - , tef_fam_app = TEFA_Recurse - , tef_lhs = TyVarLHS lhs_tv - , tef_unifying = Unifying info lvl (LC_Promote True) - , tef_occurs = cteInsolubleOccurs } + ; let task :: TEFTask + task = unifyingLHSMetaTyVar_TEFTask lhs_tv (LC_Promote True) + -- LC_Promote: promote deeper unification variables (DE4) + -- LC_Promote True: ...including under type families (DE5) + flags :: TyEqFlags () + flags = TEF { tef_task = task + , tef_fam_app = TEFA_Recurse } ; res :: PuResult () Reduction <- wrapTcS (checkTyEqRhs flags rhs_ty) ; case res of ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -201,6 +201,7 @@ import GHC.Exts (oneShot) import Control.Monad import Data.IORef import Data.List ( mapAccumL ) +import Data.Maybe ( isJust ) import Data.Foldable import qualified Data.Semigroup as S import GHC.Types.SrcLoc @@ -2122,7 +2123,7 @@ checkTouchableTyVarEq ev lhs_tv rhs _ -> pprPanic "checkTouchableTyVarEq" (ppr lhs_tv) -- lhs_tv should be a meta-tyvar - is_concrete_lhs_tv = isConcreteInfo lhs_tv_info + is_concrete_lhs_tv = isJust $ concreteInfo_maybe lhs_tv_info check_rhs rhs -- Crucial special case for alpha ~ F tys @@ -2134,11 +2135,9 @@ checkTouchableTyVarEq ev lhs_tv rhs | otherwise = checkTyEqRhs flags rhs - flags = TEF { tef_foralls = False -- isRuntimeUnkSkol lhs_tv - , tef_fam_app = mkTEFA_Break ev NomEq break_wanted - , tef_unifying = Unifying lhs_tv_info lhs_tv_lvl (LC_Promote False) - , tef_lhs = TyVarLHS lhs_tv - , tef_occurs = cteInsolubleOccurs } + flags = TEF { tef_task = unifyingLHSMetaTyVar_TEFTask lhs_tv (LC_Promote False) + , tef_fam_app = mkTEFA_Break ev NomEq break_wanted + } arg_flags = famAppArgFlags flags @@ -2147,7 +2146,8 @@ checkTouchableTyVarEq ev lhs_tv rhs -- Occurs check or skolem escape; so flatten = do { let fam_app_kind = typeKind fam_app ; reason <- checkPromoteFreeVars cteInsolubleOccurs - lhs_tv lhs_tv_lvl (tyCoVarsOfType fam_app_kind) + (tyVarName lhs_tv) lhs_tv_lvl + (tyCoVarsOfType fam_app_kind) ; if not (cterHasNoProblem reason) -- Failed to promote free vars then failCheckWith reason else @@ -2210,19 +2210,15 @@ checkTypeEq ev eq_rel lhs rhs arg_flags = famAppArgFlags given_flags given_flags :: TyEqFlags (TcTyVar,TcType) - given_flags = TEF { tef_lhs = lhs - , tef_foralls = False - , tef_unifying = NotUnifying - , tef_fam_app = mkTEFA_Break ev eq_rel break_given - , tef_occurs = occ_prob } + given_flags = TEF { tef_task = notUnifying_TEFTask occ_prob lhs + , tef_fam_app = mkTEFA_Break ev eq_rel break_given + } -- TEFA_Break used for: [G] a ~ Maybe (F a) -- or [W] F a ~ Maybe (F a) - wanted_flags = TEF { tef_lhs = lhs - , tef_foralls = False - , tef_unifying = NotUnifying - , tef_fam_app = TEFA_Recurse - , tef_occurs = occ_prob } + wanted_flags = TEF { tef_task = notUnifying_TEFTask occ_prob lhs + , tef_fam_app = TEFA_Recurse + } -- TEFA_Recurse: see Note [Don't cycle-break Wanteds when not unifying] -- occ_prob: see Note [Occurs check and representational equality] @@ -2289,7 +2285,7 @@ where both sides are TyFamLHSs. We don't want to flatten that RHS to Instead we'd like to say "occurs-check" and swap LHS and RHS, which yields a canonical constraint [G] G (...(F ty)...) ~ F ty -That tents to rewrite a big type to smaller one. This happens in T15703, +That tends to rewrite a big type to smaller one. This happens in T15703, where we had: [G] Pure g ~ From1 (To1 (Pure g)) Making a loop breaker and rewriting left to right just makes much bigger ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -14,8 +14,8 @@ -- | Typecheck type and class declarations module GHC.Tc.TyCl ( + LHSUserSuppliedResultKind(..), tcTyAndClassDecls, - -- Functions used by GHC.Tc.TyCl.Instance to check -- data/type family instance declarations kcConDecls, tcConDecls, DataDeclInfo(..), @@ -1765,7 +1765,7 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) kcTyClDecl (DataDecl { tcdLName = (L _ _name) - , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons, dd_kindSig = kindSig } }) tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no @@ -1774,7 +1774,9 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name) -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) (if (isJust kindSig) + then LHSUserSuppliedResultKind + else NoLHSUserSuppliedResultKind) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1834,12 +1836,18 @@ kcConGADTArgs exp_kind con_args = case con_args of RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds +-- Specifically for GADT style declarations +-- do we have lhs user supplied kind signature? +-- as in `data xxx :: UserSuppliedKind where ...` +data LHSUserSuppliedResultKind = LHSUserSuppliedResultKind | NoLHSUserSuppliedResultKind deriving Eq + kcConDecls :: TcKind -- Result kind of tycon -- Used only in H98 case + -> LHSUserSuppliedResultKind -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls tc_res_kind cons - = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons +kcConDecls tc_res_kind usrk cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data usrk tc_res_kind)) cons where new_or_data = dataDefnConsNewOrData cons @@ -1848,8 +1856,8 @@ kcConDecls tc_res_kind cons -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () -kcConDecl new_or_data tc_res_kind +kcConDecl :: NewOrData -> LHSUserSuppliedResultKind -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data _usrk tc_res_kind (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (DataConDefCtxt (NE.singleton name)) $ @@ -1865,7 +1873,7 @@ kcConDecl new_or_data tc_res_kind -- because that's done in tcConDecl } -kcConDecl new_or_data _tc_res_kind +kcConDecl new_or_data usrk tc_res_kind -- NB: _tc_res_kind is unused. See (KCD3) in -- Note [kcConDecls: kind-checking data type decls] (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs @@ -1877,10 +1885,11 @@ kcConDecl new_or_data _tc_res_kind bindOuterSigTKBndrs_Tv outer_bndrs $ -- Why "_Tv"? See Note [Using TyVarTvs for kind-checking GADTs] do { _ <- tcHsContext cxt - ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) - ; con_res_kind <- newOpenTypeKind - ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - + ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty $$ ppr tc_res_kind) + ; con_res_kind <- if NewType == new_or_data && NoLHSUserSuppliedResultKind == usrk + then return tc_res_kind + else newOpenTypeKind + ; _ <- tcCheckLHsTypeInContext res_ty $ (TheKind con_res_kind) ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind -- getArgExpKind: for newtypes, check that the argument kind -- is the same the kind of `res_ty`, the data con's return type ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -946,7 +946,11 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Add constraints from the data constructors -- Fix #25611 -- See DESIGN CHOICE in Note [Kind inference for data family instances] - ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind (if (isJust m_ksig) + then LHSUserSuppliedResultKind + else NoLHSUserSuppliedResultKind) + hs_cons + -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -52,7 +52,6 @@ module GHC.Tc.Types.Constraint ( Hole(..), HoleSort(..), isOutOfScopeHole, DelayedError(..), NotConcreteError(..), - NotConcreteReason(..), WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, @@ -132,7 +131,6 @@ import Data.Coerce import qualified Data.Semigroup as S import Control.Monad ( msum, when ) import Data.Maybe ( mapMaybe, isJust ) -import Data.List.NonEmpty ( NonEmpty ) -- these are for CheckTyEqResult import Data.Word ( Word8 ) @@ -435,30 +433,8 @@ data NotConcreteError -- ^ Where did this check take place? , nce_frr_origin :: FixedRuntimeRepOrigin -- ^ Which representation-polymorphism check did we perform? - , nce_reasons :: NonEmpty NotConcreteReason - -- ^ Why did the check fail? } --- | Why did we decide that a type was not concrete? -data NotConcreteReason - -- | The type contains a 'TyConApp' of a non-concrete 'TyCon'. - -- - -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. - = NonConcreteTyCon TyCon [TcType] - - -- | The type contains a type variable that could not be made - -- concrete (e.g. a skolem type variable). - | NonConcretisableTyVar TyVar - - -- | The type contains a cast. - | ContainsCast TcType TcCoercionN - - -- | The type contains a forall. - | ContainsForall ForAllTyBinder TcType - - -- | The type contains a 'CoercionTy'. - | ContainsCoercionTy TcCoercion - instance Outputable NotConcreteError where ppr (NCE_FRR { nce_frr_origin = frr_orig }) = text "NCE_FRR" <+> parens (ppr (frr_type frr_orig)) ===================================== compiler/GHC/Tc/Utils/Concrete.hs ===================================== @@ -19,39 +19,35 @@ module GHC.Tc.Utils.Concrete import GHC.Prelude import GHC.Builtin.Names ( unsafeCoercePrimName ) -import GHC.Builtin.Types ( liftedTypeKindTyCon, unliftedTypeKindTyCon ) +import GHC.Builtin.Types -import GHC.Core.Coercion ( coToMCo, mkCastTyMCo - , mkGReflRightMCo, mkNomReflCo ) -import GHC.Core.TyCo.Rep ( Type(..), MCoercion(..) ) -import GHC.Core.TyCon ( isConcreteTyCon ) -import GHC.Core.Type ( isConcreteType, typeKind, mkFunTy) +import GHC.Core.Coercion +import GHC.Core.TyCo.Rep +import GHC.Core.Type -import GHC.Tc.Types.Constraint ( NotConcreteError(..), NotConcreteReason(..) ) -import GHC.Tc.Types.Evidence ( Role(..), TcCoercionN, TcMCoercionN ) +import GHC.Data.Bag + +import GHC.Tc.Types.Constraint +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Origin import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType -import GHC.Tc.Utils.TcMType +import {-# SOURCE #-} GHC.Tc.Utils.Unify import GHC.Types.Basic ( TypeOrKind(KindLevel) ) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Types.Name import GHC.Types.Name.Env -import GHC.Types.Var ( tyVarKind, tyVarName ) +import GHC.Types.Var import GHC.Utils.Misc ( HasDebugCallStack ) import GHC.Utils.Outputable +import GHC.Utils.Panic import GHC.Data.FastString ( FastString, fsLit ) - import Control.Monad ( void ) import Data.Functor ( ($>) ) -import Data.List.NonEmpty ( NonEmpty((:|)) ) -import Control.Monad.Trans.Class ( lift ) -import Control.Monad.Trans.Writer.CPS ( WriterT, runWriterT, tell ) {- Note [Concrete overview] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -221,7 +217,6 @@ other type variables, a 'ConcreteTv' type variable is a type variable which can only be unified with a concrete type (in the sense of Note [Concrete types]). INVARIANT: the kind of a concrete metavariable is concrete. - This invariant is upheld at the time of creation of a new concrete metavariable. Concrete metavariables are useful for representation-polymorphism checks: @@ -632,7 +627,7 @@ hasFixedRuntimeRep :: HasDebugCallStack -- That is, @ty'@ has a syntactically fixed RuntimeRep -- in the sense of Note [Fixed RuntimeRep]. hasFixedRuntimeRep frr_ctxt ty = - checkFRR_with (unifyConcrete (fsLit "cx") . ConcreteFRR) frr_ctxt ty + checkFRR_with (fmap (fmap coToMCo) . unifyConcrete_kind (fsLit "cx") . ConcreteFRR) frr_ctxt ty -- | Like 'hasFixedRuntimeRep', but we perform an eager syntactic check. -- @@ -700,226 +695,86 @@ checkFRR_with check_kind frr_ctxt ty frr_orig :: FixedRuntimeRepOrigin frr_orig = FixedRuntimeRepOrigin { frr_type = ty, frr_context = frr_ctxt } --- | Ensure that the given type @ty@ can unify with a concrete type, +-- | Ensure that the given kind @ki@ can unify with a concrete type, -- in the sense of Note [Concrete types]. -- --- Returns a coercion @co :: ty ~# conc_ty@, where @conc_ty@ is +-- Returns a coercion @co :: ki ~# conc_ki@, where @conc_ki@ is -- concrete. -- --- If the type is already syntactically concrete, this +-- If the kind is already syntactically concrete, this -- immediately returns a reflexive coercion. Otherwise, -- it creates a new concrete metavariable @concrete_tv@ --- and emits an equality constraint @ty ~# concrete_tv@, +-- and emits an equality constraint @ki ~# concrete_tv@, -- to be handled by the constraint solver. -- +-- Precondition: @ki@ must be of the form @TYPE rep@ or @CONSTRAINT rep at . +unifyConcrete_kind :: HasDebugCallStack + => FastString -- ^ name to use when creating concrete metavariables + -> ConcreteTvOrigin + -> TcKind + -> TcM TcCoercionN +unifyConcrete_kind occ_fs conc_orig ki + | Just (torc, rep) <- sORTKind_maybe ki + = do { let tc = case torc of + TypeLike -> tYPETyCon + ConstraintLike -> cONSTRAINTTyCon + ; rep_co <- unifyConcrete occ_fs conc_orig rep + ; return $ mkTyConAppCo Nominal tc [rep_co] } + | otherwise + = pprPanic "unifyConcrete_kind: kind is not of the form 'TYPE rep' or 'CONSTRAINT rep'" $ + ppr ki <+> dcolon <+> ppr (typeKind ki) + + +-- | Ensure the given type can be unified with +-- a concrete type, in the sense of Note [Concrete types]. +-- +-- Returns a coercion @co :: ty ~# conc_ty@, where @conc_ty@ is +-- concrete. +-- +-- If the type is already syntactically concrete, this +-- immediately returns a reflexive coercion. +-- Otherwise, it will create new concrete metavariables and emit +-- new Wanted equality constraints, to be handled by the constraint solver. +-- -- Invariant: the kind of the supplied type must be concrete. -- -- We assume the provided type is already at the kind-level -- (this only matters for error messages). -unifyConcrete :: HasDebugCallStack - => FastString -> ConcreteTvOrigin -> TcType -> TcM TcMCoercionN +unifyConcrete :: FastString -> ConcreteTvOrigin -> TcType -> TcM TcCoercionN unifyConcrete occ_fs conc_orig ty - = do { (ty, errs) <- makeTypeConcrete conc_orig ty - ; case errs of - -- We were able to make the type fully concrete. - { [] -> return MRefl - -- The type could not be made concrete; perhaps it contains - -- a skolem type variable, a type family application, ... - -- - -- Create a new ConcreteTv metavariable @concrete_tv@ - -- and unify @ty ~# concrete_tv at . - ; _ -> - do { conc_tv <- newConcreteTyVar conc_orig occ_fs ki - -- NB: newConcreteTyVar asserts that 'ki' is concrete. - ; coToMCo <$> emitWantedEq orig KindLevel Nominal ty (mkTyVarTy conc_tv) } } } - where - ki :: TcKind - ki = typeKind ty - orig :: CtOrigin - orig = case conc_orig of - ConcreteFRR frr_orig -> FRROrigin frr_orig + = do { (co, cts) <- makeTypeConcrete occ_fs conc_orig ty + ; emitSimples cts + ; return co } --- | Ensure that the given type is concrete. +-- | Ensure that the given kind @ki@ is concrete. -- -- This is an eager syntactic check, and never defers --- any work to the constraint solver. --- --- Invariant: the kind of the supplied type must be concrete. --- Invariant: the output type is equal to the input type, --- up to zonking. +-- any work to the constraint solver. However, +-- it may perform unification. -- --- We assume the provided type is already at the kind-level --- (this only matters for error messages). +-- Invariant: the output type is equal to the input type, up to zonking. ensureConcrete :: HasDebugCallStack => FixedRuntimeRepOrigin - -> TcType - -> TcM TcType -ensureConcrete frr_orig ty - = do { traceTc "ensureConcrete {" (ppr frr_orig $$ ppr ty) - ; (ty', errs) <- makeTypeConcrete conc_orig ty - ; case errs of - { err:errs -> - do { traceTc "ensureConcrete } failure" $ - vcat [ text "ty:" <+> ppr ty - , text "ty':" <+> ppr ty' ] + -> TcKind + -> TcM TcKind +ensureConcrete frr_orig ki + = do { (co, cts) <- makeTypeConcrete (fsLit "cx") conc_orig ki + ; let trace_msg = vcat [ text "ty: " <+> ppr ki + , text "co:" <+> ppr co ] + ; if isEmptyBag cts + then traceTc "ensureConcrete } success" trace_msg + else do { traceTc "ensureConcrete } failure" trace_msg ; loc <- getCtLocM (FRROrigin frr_orig) (Just KindLevel) ; emitNotConcreteError $ NCE_FRR { nce_loc = loc - , nce_frr_origin = frr_orig - , nce_reasons = err :| errs } - } - ; [] -> - traceTc "ensureConcrete } success" $ - vcat [ text "ty: " <+> ppr ty - , text "ty':" <+> ppr ty' ] } - ; return ty' } + , nce_frr_origin = frr_orig } + } + ; return $ coercionRKind co } where conc_orig :: ConcreteTvOrigin conc_orig = ConcreteFRR frr_orig -{-*********************************************************************** -%* * - Making a type concrete -%* * -%************************************************************************ - -Note [Unifying concrete metavariables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Unifying concrete metavariables (as defined in Note [ConcreteTv]) is not -an all-or-nothing affair as it is for other sorts of metavariables. - -Consider the following unification problem in which all metavariables -are unfilled (and ignoring any TcLevel considerations): - - alpha[conc] ~# TYPE (TupleRep '[ beta[conc], IntRep, gamma[tau] ]) - -We can't immediately unify `alpha` with the RHS, because the RHS is not -a concrete type (in the sense of Note [Concrete types]). Instead, we -proceed as follows: - - - create a fresh concrete metavariable variable `gamma'[conc]`, - - write gamma[tau] := gamma'[conc], - - write alpha[conc] := TYPE (TupleRep '[ beta[conc], IntRep, gamma'[conc] ]). - -Thus, in general, to unify `alpha[conc] ~# rhs`, we first try to turn -`rhs` into a concrete type (see the 'makeTypeConcrete' function). -If this succeeds, resulting in a concrete type `rhs'`, we simply fill -`alpha[conc] := rhs'`. If it fails, then syntactic unification fails. - -Example 1: - - alpha[conc] ~# TYPE (TupleRep '[ beta[conc], IntRep, gamma[tau] ]) - - We proceed by filling metavariables: - - gamma[tau] := gamma[conc] - alpha[conc] := TYPE (TupleRep '[ beta[conc], IntRep, gamma[conc] ]) - - This successfully unifies alpha. - -Example 2: - - For a type family `F :: Type -> Type`: - - delta[conc] ~# TYPE (SumRep '[ zeta[tau], a[sk], F omega[tau] ]) - - We write zeta[tau] := zeta[conc], and then fail, providing the following - two reasons: - - - `a[sk]` is not a concrete type variable, so the overall type - cannot be concrete - - `F` is not a concrete type constructor, in the sense of - Note [Concrete types]. So we keep it as is; in particular, - we /should not/ try to make its argument `omega[tau]` into - a ConcreteTv. - - Note that making zeta concrete allows us to propagate information. - For example, after more typechecking, we might try to unify - `zeta ~# rr[sk]`. If we made zeta a ConcreteTv, we will report - this unsolved equality using the 'ConcreteTvOrigin' stored in zeta[conc]. - This allows us to report ALL the problems in a representation-polymorphism - check (instead of only a non-empty subset). --} - --- | Try to turn the provided type into a concrete type, by ensuring --- unfilled metavariables are appropriately marked as concrete. --- --- Returns a zonked type which is "as concrete as possible", and --- a list of problems encountered when trying to make it concrete. --- --- INVARIANT: the returned type is equal to the input type, up to zonking. --- INVARIANT: if this function returns an empty list of 'NotConcreteReasons', --- then the returned type is concrete, in the sense of Note [Concrete types]. -makeTypeConcrete :: ConcreteTvOrigin -> TcType -> TcM (TcType, [NotConcreteReason]) --- TODO: it could be worthwhile to return enough information to continue solving. --- Consider unifying `alpha[conc] ~# TupleRep '[ beta[tau], F Int ]` for --- a type family 'F'. --- This function will concretise `beta[tau] := beta[conc]` and return --- that `TupleRep '[ beta[conc], F Int ]` is not concrete because of the --- type family application `F Int`. But we could decompose by setting --- alpha := TupleRep '[ beta, gamma[conc] ] and emitting `[W] gamma[conc] ~ F Int`. -makeTypeConcrete conc_orig ty = - do { res@(ty', _) <- runWriterT $ go ty - ; traceTc "makeTypeConcrete" $ - vcat [ text "ty:" <+> ppr ty - , text "ty':" <+> ppr ty' ] - ; return res } - where - go :: TcType -> WriterT [NotConcreteReason] TcM TcType - go ty - | Just ty <- coreView ty - = go ty - | isConcreteType ty - = pure ty - go ty@(TyVarTy tv) -- not a ConcreteTv (already handled above) - = do { mb_filled <- lift $ isFilledMetaTyVar_maybe tv - ; case mb_filled of - { Just ty -> go ty - ; Nothing - | isMetaTyVar tv - , TauTv <- metaTyVarInfo tv - -> -- Change the MetaInfo to ConcreteTv, but retain the TcLevel - do { kind <- go (tyVarKind tv) - ; let occ_fs = occNameFS (getOccName tv) - -- occ_fs: preserve the occurrence name of the original tyvar - -- This helps in error messages - ; lift $ - do { conc_tv <- setTcLevel (tcTyVarLevel tv) $ - newConcreteTyVar conc_orig occ_fs kind - ; let conc_ty = mkTyVarTy conc_tv - ; liftZonkM $ writeMetaTyVar tv conc_ty - ; return conc_ty } } - | otherwise - -- Don't attempt to make other type variables concrete - -- (e.g. SkolemTv, TyVarTv, CycleBreakerTv, RuntimeUnkTv). - -> bale_out ty (NonConcretisableTyVar tv) } } - go ty@(TyConApp tc tys) - | isConcreteTyCon tc - = mkTyConApp tc <$> mapM go tys - | otherwise - = bale_out ty (NonConcreteTyCon tc tys) - go (FunTy af w ty1 ty2) - = do { w <- go w - ; ty1 <- go ty1 - ; ty2 <- go ty2 - ; return $ mkFunTy af w ty1 ty2 } - go (AppTy ty1 ty2) - = do { ty1 <- go ty1 - ; ty2 <- go ty2 - ; return $ mkAppTy ty1 ty2 } - go ty@(LitTy {}) - = return ty - go ty@(CastTy cast_ty kco) - = bale_out ty (ContainsCast cast_ty kco) - go ty@(ForAllTy tcv body) - = bale_out ty (ContainsForall tcv body) - go ty@(CoercionTy co) - = bale_out ty (ContainsCoercionTy co) - - bale_out :: TcType -> NotConcreteReason -> WriterT [NotConcreteReason] TcM TcType - bale_out ty reason = do { tell [reason]; return ty } - {-*********************************************************************** %* * Concrete type variables of Ids ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -755,7 +755,7 @@ newNamedAnonMetaTyVar tyvar_name meta_info kind = do { name <- newMetaTyVarName tyvar_name ; details <- newMetaDetails meta_info ; let tyvar = mkTcTyVar name kind details - ; traceTc "newAnonMetaTyVar" (ppr tyvar) + ; traceTc "newAnonMetaTyVar" (ppr tyvar <+> dcolon <+> ppr kind) ; return tyvar } -- makes a new skolem tv ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -53,7 +53,7 @@ module GHC.Tc.Utils.TcType ( isImmutableTyVar, isSkolemTyVar, isMetaTyVar, isMetaTyVarTy, isTyVarTy, tcIsTcTyVar, isTyVarTyVar, isOverlappableTyVar, isTyConableTyVar, ConcreteTvOrigin(..), isConcreteTyVar_maybe, isConcreteTyVar, - isConcreteTyVarTy, isConcreteTyVarTy_maybe, isConcreteInfo, + isConcreteTyVarTy, isConcreteTyVarTy_maybe, concreteInfo_maybe, ConcreteTyVars, noConcreteTyVars, isAmbiguousTyVar, isCycleBreakerTyVar, metaTyVarRef, metaTyVarInfo, isFlexi, isIndirect, isRuntimeUnkSkol, @@ -1266,9 +1266,9 @@ isConcreteTyVar_maybe tv | otherwise = Nothing -isConcreteInfo :: MetaInfo -> Bool -isConcreteInfo (ConcreteTv {}) = True -isConcreteInfo _ = False +concreteInfo_maybe :: MetaInfo -> Maybe ConcreteTvOrigin +concreteInfo_maybe (ConcreteTv conc_orig) = Just conc_orig +concreteInfo_maybe _ = Nothing -- | Is this type variable a concrete type variable, i.e. -- it is a metavariable with 'ConcreteTv' 'MetaInfo'? ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1,8 +1,13 @@ +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeApplications #-} + {- (c) The University of Glasgow 2006 @@ -28,6 +33,7 @@ module GHC.Tc.Utils.Unify ( swapOverTyVars, touchabilityAndShapeTest, checkTopShape, lhsPriority, UnifyEnv(..), updUEnvLoc, setUEnvRole, uType, + makeTypeConcrete, -------------------------------- -- Holes @@ -41,8 +47,11 @@ module GHC.Tc.Utils.Unify ( checkTyEqRhs, recurseIntoTyConApp, PuResult(..), failCheckWith, okCheckRefl, mapCheck, - TyEqFlags(..), TyEqFamApp(..), AreUnifying(..), LevelCheck(..), FamAppBreaker, + TyEqFlags(..), TEFTask(..), + notUnifying_TEFTask, unifyingLHSMetaTyVar_TEFTask, + LevelCheck(..), TyEqFamApp(..), FamAppBreaker, famAppArgFlags, checkPromoteFreeVars, + simpleUnifyCheck, UnifyCheckCaller(..), fillInferResult, @@ -54,7 +63,7 @@ import GHC.Hs import GHC.Tc.Errors.Types ( ErrCtxtMsg(..) ) import GHC.Tc.Errors.Ppr ( pprErrCtxtMsg ) -import GHC.Tc.Utils.Concrete ( hasFixedRuntimeRep, hasFixedRuntimeRep_syntactic ) +import GHC.Tc.Utils.Concrete import GHC.Tc.Utils.Env import GHC.Tc.Utils.Instantiate import GHC.Tc.Utils.Monad @@ -94,11 +103,13 @@ import GHC.Utils.Panic import GHC.Driver.DynFlags import GHC.Data.Bag -import GHC.Data.FastString( fsLit ) +import GHC.Data.FastString import Control.Monad +import Data.Maybe (maybeToList, isJust) import Data.Monoid as DM ( Any(..) ) import qualified Data.Semigroup as S ( (<>) ) +import Data.Traversable (for) {- ********************************************************************* * * @@ -2927,7 +2938,7 @@ simpleUnifyCheck caller lhs_tv rhs = go rhs where - !(occ_in_ty, occ_in_co) = mkOccFolders lhs_tv + !(occ_in_ty, occ_in_co) = mkOccFolders (tyVarName lhs_tv) lhs_tv_lvl = tcTyVarLevel lhs_tv lhs_tv_is_concrete = isConcreteTyVar lhs_tv @@ -2974,7 +2985,7 @@ simpleUnifyCheck caller lhs_tv rhs go (LitTy {}) = True -mkOccFolders :: TcTyVar -> (TcType -> Bool, TcCoercion -> Bool) +mkOccFolders :: Name -> (TcType -> Bool, TcCoercion -> Bool) -- These functions return True -- * if lhs_tv occurs (incl deeply, in the kind of variable) -- * if there is a coercion hole @@ -2987,7 +2998,7 @@ mkOccFolders lhs_tv = (getAny . check_ty, getAny . check_co) , tcf_hole = do_hole , tcf_tycobinder = do_bndr } - do_tcv is v = Any (not (v `elemVarSet` is) && v == lhs_tv) + do_tcv is v = Any (not (v `elemVarSet` is) && tyVarName v == lhs_tv) `mappend` check_ty (varType v) do_bndr is tcv _faf = extendVarSet is tcv @@ -3058,10 +3069,7 @@ reductionCoercion is Refl. See `canEqCanLHSFinish_no_unification`. data PuResult a b = PuFail CheckTyEqResult | PuOK (Bag a) b - -instance Functor (PuResult a) where - fmap _ (PuFail prob) = PuFail prob - fmap f (PuOK cts x) = PuOK cts (f x) + deriving stock (Functor, Foldable, Traversable) instance Applicative (PuResult a) where pure x = PuOK emptyBag x @@ -3100,82 +3108,192 @@ mapCheck f xs -- | Options describing how to deal with a type equality -- in the pure unifier. See 'checkTyEqRhs' data TyEqFlags a - = TEF { tef_foralls :: Bool -- Allow foralls - , tef_lhs :: CanEqLHS -- LHS of the constraint - , tef_unifying :: AreUnifying -- Always NotUnifying if tef_lhs is TyFamLHS + = TEF { tef_task :: TEFTask + -- ^ LHS structure, and which checks to perform on the RHS , tef_fam_app :: TyEqFamApp a - , tef_occurs :: CheckTyEqProblem } -- Soluble or insoluble occurs check + -- ^ How to deal with type family applications + } + +-- | The structure of the LHS and which checks to perform in 'checkTyEqRhs', +-- for an equality @lhs ~# rhs at . +-- +-- See Note [TEFTask]. +data TEFTask + -- | LHS is a type family application; we are not unifying. + = TEFTyFam + { tefTyFam_occursCheck :: CheckTyEqProblem + -- ^ The 'CheckTyEqProblem' to report for occurs-check failures + -- (soluble or insoluble) + , tefTyFam_tyCon :: TyCon + , tefTyFam_args :: [Type] + } + -- | LHS is a 'TyVar'. + | TEFTyVar + { tefTyVar_occursCheck :: Maybe (Name, CheckTyEqProblem) + -- ^ Occurs check: LHS 'TyVar' 'Name', + -- and which 'CheckTyEqProblem' to report for occurs-check failures + -- (soluble or insoluble) + , tefTyVar_levelCheck :: Maybe (TcLevel, LevelCheck) + -- ^ Level check: LHS 'TyVar' 'TcLevel', + -- and which 'LevelCheck' to perform + , tefTyVar_concreteCheck :: Maybe ConcreteTvOrigin + -- ^ Concreteness check: LHS 'TyVar' 'ConcreteTvOrigin' + -- to use for the check + } + +{- Note [TEFTask] +~~~~~~~~~~~~~~~~~ +When we call the pure unifier, e.g. through 'checkTyEqRhs', we can decide what +kind of checks the unifier performs via the 'TyEqFlags' argument. In particular, +when the LHS type in a unification is a type variable, we might want to perform +different checks; this is achieved using the 'TEFTyVar' constructor to 'TEFTask': + + 1. LHS is a skolem tyvar, or an untouchable meta-tyvar. + We are not unifying; we only want to perform occurs-checks. + + TEFTyVar + { tefTyVar_occursCheck = Just ... + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Nothing + } + + 2. LHS is a touchable meta-tyvar. + We are unifying; we want to perform an occurs check, a level check, + and a concreteness check (when the meta-tyvar is a ConcreteTv). + + TEFTyVar + { tefTyVar_occursCheck = Just ... + , tefTyVar_levelCheck = Just ... + , tefTyVar_concreteCheck = isConcreteTyVar_maybe lhs_tv + } + + 3. LHS is a fresh ConcreteTv meta-tyvar (see call to 'checkTyEqRhs' in + 'makeTypeConcrete'). We are unifying; we only want to perform + a concreteness check. + + TEFTyVar + { tefTyVar_occursCheck = Nothing + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Just ... + } +-} + +-- | Create a "not unifying" 'TEFTask' from a 'CanEqLHS'. +-- +-- See use-case (1) in Note [TEFTask]. +notUnifying_TEFTask :: CheckTyEqProblem -> CanEqLHS -> TEFTask +notUnifying_TEFTask occ_prob = \case + TyFamLHS tc tys -> + TEFTyFam occ_prob tc tys + TyVarLHS tv -> + TEFTyVar + { tefTyVar_occursCheck = Just (tyVarName tv, occ_prob) + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Nothing + } + -- We need an occurs-check here, but no level check. + -- See Note [Promotion and level-checking] wrinkle (W1) + +-- | Create "unifying" 'TEFTask' from a 'TyVarLHS'. +-- +-- Invariant: the argument 'TyVar' is a 'MetaTv'. +unifyingLHSMetaTyVar_TEFTask :: TyVar -> LevelCheck -> TEFTask +unifyingLHSMetaTyVar_TEFTask lhs_tv lc = + TEFTyVar + { tefTyVar_occursCheck = Just (tyVarName lhs_tv, cteInsolubleOccurs) + , tefTyVar_levelCheck = Just (tcTyVarLevel lhs_tv, lc) + , tefTyVar_concreteCheck = isConcreteTyVar_maybe lhs_tv + } + +-- | Do we want to perform a concreteness check in 'checkTyEqRhs'? +tefTaskConcrete_maybe :: TEFTask -> Maybe ConcreteTvOrigin +tefTaskConcrete_maybe (TEFTyFam {}) = Nothing +tefTaskConcrete_maybe (TEFTyVar { tefTyVar_concreteCheck = conc }) = conc + +instance Outputable TEFTask where + ppr = \case + TEFTyFam occ tc tys -> + text "TEFTyFam" <+> ppr occ <+> ppr (mkTyConApp tc tys) + TEFTyVar mb_occ mb_lc mb_conc -> + text "TEFTyVar" <+> hcat (punctuate comma fields) + where + fields = [ text "OccursCheck:" <+> ppr tv | (tv, _) <- maybeToList mb_occ ] + ++ + [ text "LevelCheck:" <+> ppr lc | lc <- maybeToList mb_lc ] + ++ + [ text "ConcreteCheck" | isJust mb_conc ] -- | What to do when encountering a type-family application while processing -- a type equality in the pure unifier. -- -- See Note [Family applications in canonical constraints] data TyEqFamApp a - = TEFA_Fail -- Always fail - | TEFA_Recurse -- Just recurse - | TEFA_Break (FamAppBreaker a) -- Recurse, but replace with cycle breaker if fails, - -- using the FamAppBreaker - -data AreUnifying - = Unifying - MetaInfo -- MetaInfo of the LHS tyvar (which is a meta-tyvar) - TcLevel -- Level of the LHS tyvar - LevelCheck - - | NotUnifying -- Not attempting to unify + = TEFA_Fail -- ^ Always fail + | TEFA_Recurse -- ^ Just recurse + | TEFA_Break (FamAppBreaker a) -- ^ Recurse, but replace with cycle breaker if fails, + -- using the FamAppBreaker +-- | What level check to perform, in a call to the pure unifier? data LevelCheck - = LC_None -- Level check not needed: we should never encounter - -- a tyvar at deeper level than the LHS - - | LC_Check -- Do a level check between the LHS tyvar and the occurrence tyvar - -- Fail if the level check fails - - | LC_Promote -- Do a level check between the LHS tyvar and the occurrence tyvar - -- If the level check fails, and the occurrence is a unification - -- variable, promote it - Bool -- False <=> don't promote under type families (the common case) - -- True <=> promote even under type families - -- see Note [Defaulting equalities] in GHC.Tc.Solver + = LC_Check -- ^ Do a level check between the LHS tyvar and the occurrence tyvar. + -- + -- Fail if the level check fails. + + | LC_Promote Bool + -- ^ Do a level check between the LHS tyvar and the occurrence tyvar. + -- + -- If the level check fails, and the occurrence is a unification + -- variable, promote it. + -- + -- - False <=> don't promote under type families (the common case) + -- - True <=> promote even under type families + -- (see Note [Defaulting equalities] in GHC.Tc.Solver) instance Outputable (TyEqFlags a) where ppr (TEF { .. }) = text "TEF" <> braces ( - vcat [ text "tef_foralls =" <+> ppr tef_foralls - , text "tef_lhs =" <+> ppr tef_lhs - , text "tef_unifying =" <+> ppr tef_unifying - , text "tef_fam_app =" <+> ppr tef_fam_app - , text "tef_occurs =" <+> ppr tef_occurs ]) + vcat [ text "tef_task =" <+> ppr tef_task + , text "tef_fam_app =" <+> ppr tef_fam_app ]) instance Outputable (TyEqFamApp a) where ppr TEFA_Fail = text "TEFA_Fail" ppr TEFA_Recurse = text "TEFA_Recurse" ppr (TEFA_Break {}) = text "TEFA_Break" -instance Outputable AreUnifying where - ppr NotUnifying = text "NotUnifying" - ppr (Unifying mi lvl lc) = text "Unifying" <+> - braces (ppr mi <> comma <+> ppr lvl <> comma <+> ppr lc) - instance Outputable LevelCheck where - ppr LC_None = text "LC_None" ppr LC_Check = text "LC_Check" ppr (LC_Promote b) = text "LC_Promote" <> ppWhen b (text "(deep)") +-- | Adjust the 'TyEqFlags' when going undter a type family: +-- +-- 1. Only the outer family application gets the loop-breaker treatment +-- 2. Weaken level checks for tyvar promotion. For example, in @[W] alpha[2] ~ Maybe (F beta[3])@, +-- do not promote @beta[3]@, instead promote @(F beta[3])@. +-- 3. Occurs checks become potentially soluble (after additional type family +-- reductions). famAppArgFlags :: TyEqFlags a -> TyEqFlags a --- Adjust the flags when going undter a type family --- Only the outer family application gets the loop-breaker treatment --- Ditto tyvar promotion. E.g. --- [W] alpha[2] ~ Maybe (F beta[3]) --- Do not promote beta[3]; instead promote (F beta[3]) -famAppArgFlags flags@(TEF { tef_unifying = unifying }) - = flags { tef_fam_app = TEFA_Recurse - , tef_unifying = zap_promotion unifying - , tef_occurs = cteSolubleOccurs } - -- tef_occurs: under a type family, an occurs check is not definitely-insoluble +famAppArgFlags flags@(TEF { tef_task = task }) + = flags { tef_fam_app = TEFA_Recurse -- (1) + , tef_task = fam_app_task task + } where - zap_promotion (Unifying info lvl (LC_Promote deeply)) - | not deeply = Unifying info lvl LC_Check - zap_promotion unifying = unifying + fam_app_task :: TEFTask -> TEFTask + fam_app_task task = case task of + TEFTyFam {} -> + task + { tefTyFam_occursCheck = cteSolubleOccurs -- (3) + } + TEFTyVar { tefTyVar_occursCheck = mb_occ, tefTyVar_levelCheck = mb_lc } -> + task + { tefTyVar_occursCheck = + fmap (\ (tv, _old_occ_prob) -> (tv, cteSolubleOccurs)) mb_occ -- (3) + , tefTyVar_levelCheck = + fmap (\ (lvl, lc) -> (lvl, zap_lc lc)) mb_lc -- (2) + } + zap_lc = \case + LC_Promote deeply + | not deeply + -> LC_Check + lc -> lc type FamAppBreaker a = TcType -> TcM (PuResult a Reduction) -- Given a family-application ty, return a Reduction :: ty ~ cvb @@ -3196,7 +3314,6 @@ checkTyEqRhs flags ty FunTy {ft_af = af, ft_mult = w, ft_arg = a, ft_res = r} | isInvisibleFunArg af -- e.g. Num a => blah - , not (tef_foralls flags) -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) | otherwise -> do { w_res <- checkTyEqRhs flags w @@ -3215,38 +3332,48 @@ checkTyEqRhs flags ty CoercionTy co -> do { co_res <- checkCo flags co ; return (mkReflCoRedn Nominal <$> co_res) } - ForAllTy {} - | tef_foralls flags -> okCheckRefl ty - | otherwise -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) - + ForAllTy {} -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) ------------------- checkCo :: TyEqFlags a -> Coercion -> TcM (PuResult a Coercion) -- See Note [checkCo] -checkCo (TEF { tef_lhs = TyFamLHS {} }) co - = return (pure co) - -checkCo (TEF { tef_lhs = TyVarLHS lhs_tv - , tef_unifying = unifying - , tef_occurs = occ_prob }) co - -- Check for coercion holes, if unifying - -- See (COERCION-HOLE) in Note [Unification preconditions] - | hasCoercionHoleCo co - = failCheckWith (cteProblem cteCoercionHole) - - -- Occurs check (can promote) - | Unifying _ lhs_tv_lvl (LC_Promote {}) <- unifying - = do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co) - ; if cterHasNoProblem reason - then return (pure co) - else failCheckWith reason } - - -- Occurs check (no promotion) - | lhs_tv `elemVarSet` tyCoVarsOfCo co - = failCheckWith (cteProblem occ_prob) +checkCo (TEF { tef_task = task }) co = + case task of + TEFTyFam {} -> + -- NB: 'TEFTyFam' case means we are not unifying. + return (pure co) + TEFTyVar + { tefTyVar_concreteCheck = mb_conc + , tefTyVar_levelCheck = mb_lc + , tefTyVar_occursCheck = mb_occ + } + -- Coercions cannot appear in concrete types. + -- + -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. + | Just {} <- mb_conc + -> failCheckWith (cteProblem cteConcrete) + + -- Check for coercion holes, if unifying. + -- See (COERCION-HOLE) in Note [Unification preconditions] + | Just {} <- mb_lc -- equivalent to "we are unifying"; see Note [TEFTask] + , hasCoercionHoleCo co + -> failCheckWith (cteProblem cteCoercionHole) + + -- Occurs check (can promote) + | Just (lhs_tv, occ_prob) <- mb_occ + , Just (lhs_tv_lvl, LC_Promote {}) <- mb_lc + -> do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co) + ; if cterHasNoProblem reason + then return (pure co) + else failCheckWith reason } + + -- Occurs check (no promotion) + | Just (lhs_tv, occ_prob) <- mb_occ + , nameUnique lhs_tv `elemVarSetByKey` tyCoVarsOfCo co + -> failCheckWith (cteProblem occ_prob) - | otherwise - = return (pure co) + | otherwise + -> return (pure co) {- Note [checkCo] ~~~~~~~~~~~~~~~~~ @@ -3364,7 +3491,7 @@ If we have [W] alpha ~ Maybe (F (G alpha)) checkTyConApp :: TyEqFlags a -> TcType -> TyCon -> [TcType] -> TcM (PuResult a Reduction) -checkTyConApp flags@(TEF { tef_unifying = unifying, tef_foralls = foralls_ok }) +checkTyConApp flags@(TEF { tef_task = task }) tc_app tc tys | isTypeFamilyTyCon tc , let arity = tyConArity tc @@ -3383,11 +3510,10 @@ checkTyConApp flags@(TEF { tef_unifying = unifying, tef_foralls = foralls_ok }) -- See Note [Forgetful synonyms in checkTyConApp] = checkTyEqRhs flags ty' - | not (isTauTyCon tc || foralls_ok) + | not (isTauTyCon tc) = failCheckWith impredicativeProblem - | Unifying info _ _ <- unifying - , isConcreteInfo info + | Just {} <- tefTaskConcrete_maybe task , not (isConcreteTyCon tc) = failCheckWith (cteProblem cteConcrete) @@ -3404,21 +3530,19 @@ checkFamApp :: TyEqFlags a -> TcType -> TyCon -> [TcType] -- Saturated family application -> TcM (PuResult a Reduction) -- See Note [Family applications in canonical constraints] -checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob - , tef_fam_app = fam_app_flag, tef_lhs = lhs }) +checkFamApp flags@(TEF { tef_task = task, tef_fam_app = fam_app_flag }) fam_app tc tys = case fam_app_flag of TEFA_Fail -> failCheckWith (cteProblem cteTypeFamily) -- Occurs check: F ty ~ ...(F ty)... - _ | TyFamLHS lhs_tc lhs_tys <- lhs + _ | TEFTyFam occ_prob lhs_tc lhs_tys <- task , tcEqTyConApps lhs_tc lhs_tys tc tys -> case fam_app_flag of TEFA_Recurse -> failCheckWith (cteProblem occ_prob) TEFA_Break breaker -> breaker fam_app - _ | Unifying lhs_info _ _ <- unifying - , isConcreteInfo lhs_info + _ | Just {} <- tefTaskConcrete_maybe task -> case fam_app_flag of TEFA_Recurse -> failCheckWith (cteProblem cteConcrete) TEFA_Break breaker -> breaker fam_app @@ -3441,22 +3565,55 @@ checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob arg_flags = famAppArgFlags flags ------------------- + +-- | The result of a single check in 'checkTyVar', such as a concreteness check +-- or a level check. +data TyVarCheckResult + -- | Check succeded; nothing else to do. + = TyVarCheck_Success + -- | Check succeeded, but requires an additional promotion. + -- + -- Invariant: at least one of the fields is not 'Nothing'. + | TyVarCheck_Promote + (Maybe TcLevel) + -- ^ @Just lvl@ <=> 'TyVar' needs to be promoted to @lvl@ + (Maybe ConcreteTvOrigin) + -- ^ @Just conc_orig@ <=> 'TyVar' needs to be make concrete + -- | Check failed with some 'CheckTyEqProblem's. + -- + -- Invariant: the 'CheckTyEqResult' is not 'cteOK'. + | TyVarCheck_Error CheckTyEqResult + +instance Semigroup TyVarCheckResult where + TyVarCheck_Success <> r = r + r <> TyVarCheck_Success = r + TyVarCheck_Error e1 <> TyVarCheck_Error e2 = + TyVarCheck_Error (e1 S.<> e2) + e@(TyVarCheck_Error {}) <> _ = e + _ <> e@(TyVarCheck_Error {}) = e + TyVarCheck_Promote l1 c1 <> TyVarCheck_Promote l2 c2 = + TyVarCheck_Promote + (combineMaybe minTcLevel l1 l2) + (combineMaybe const c1 c2) -- pick one 'ConcreteTvOrigin' arbitrarily + +combineMaybe :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a +combineMaybe _ Nothing r = r +combineMaybe _ r Nothing = r +combineMaybe f (Just a) (Just b) = Just (f a b) +instance Monoid TyVarCheckResult where + mempty = TyVarCheck_Success + checkTyVar :: forall a. TyEqFlags a -> TcTyVar -> TcM (PuResult a Reduction) -checkTyVar (TEF { tef_lhs = lhs, tef_unifying = unifying, tef_occurs = occ_prob }) occ_tv - = case lhs of - TyFamLHS {} -> success -- Nothing to do if the LHS is a type-family - TyVarLHS lhs_tv -> check_tv unifying lhs_tv +checkTyVar flags@(TEF { tef_task = task }) occ_tv + = case task of + TEFTyFam {} -> success -- Nothing to do if the LHS is a type-family + TEFTyVar mb_occ mb_lc mb_conc -> check_tv mb_occ mb_lc mb_conc where lvl_occ = tcTyVarLevel occ_tv success = okCheckRefl (mkTyVarTy occ_tv) --------------------- - check_tv NotUnifying lhs_tv - = simple_occurs_check lhs_tv - -- We need an occurs-check here, but no level check - -- See Note [Promotion and level-checking] wrinkle (W1) - - check_tv (Unifying info lvl prom) lhs_tv + check_tv mb_occ mb_lc mb_conc = do { mb_done <- isFilledMetaTyVar_maybe occ_tv ; case mb_done of Just {} -> success @@ -3466,71 +3623,94 @@ checkTyVar (TEF { tef_lhs = lhs, tef_unifying = unifying, tef_occurs = occ_prob -- a second time; we don't want to re-promote it! -- Remember, the entire process started with a fully zonked type - Nothing -> check_unif info lvl prom lhs_tv } + Nothing -> + do_rhs_checks $ + -- Occurs check + [ simple_occurs_check tv occ_prob | (tv, occ_prob) <- maybeToList mb_occ ] + ++ + -- Level check + [ lvl_check lc | lc <- maybeToList mb_lc ] + ++ + -- Concreteness check + [ conc_check conc | conc <- maybeToList mb_conc ] + } --------------------- - -- We are in the Unifying branch of AreUnifying; and occ_tv is unfilled - check_unif :: MetaInfo -> TcLevel -> LevelCheck - -> TcTyVar -> TcM (PuResult a Reduction) - check_unif lhs_tv_info lhs_tv_lvl prom lhs_tv - | isConcreteInfo lhs_tv_info - , not (isConcreteTyVar occ_tv) - = if can_make_concrete occ_tv - then promote lhs_tv lhs_tv_info lhs_tv_lvl - else failCheckWith (cteProblem cteConcrete) - + simple_occurs_check :: Name -> CheckTyEqProblem -> TyVarCheckResult + simple_occurs_check lhs_tv occ_prob + | lhs_tv == tyVarName occ_tv || check_kind (tyVarKind occ_tv) + = TyVarCheck_Error (cteProblem occ_prob) + | otherwise + = TyVarCheck_Success + where (check_kind, _) = mkOccFolders lhs_tv + conc_check :: ConcreteTvOrigin -> TyVarCheckResult + conc_check conc_orig + | not (isConcreteTyVar occ_tv) + = if isMetaTyVar occ_tv + then TyVarCheck_Promote Nothing (Just conc_orig) + else TyVarCheck_Error (cteProblem cteConcrete) + | otherwise + = TyVarCheck_Success + lvl_check :: (TcLevel, LevelCheck) -> TyVarCheckResult + lvl_check (lhs_tv_lvl, lc) | lvl_occ `strictlyDeeperThan` lhs_tv_lvl - = case prom of - LC_None -> pprPanic "check_unif" (ppr lhs_tv $$ ppr occ_tv) - LC_Check -> failCheckWith (cteProblem cteSkolemEscape) + = case lc of + LC_Check -> TyVarCheck_Error (cteProblem cteSkolemEscape) LC_Promote {} - | isSkolemTyVar occ_tv -> failCheckWith (cteProblem cteSkolemEscape) - | otherwise -> promote lhs_tv lhs_tv_info lhs_tv_lvl - - | otherwise - = simple_occurs_check lhs_tv - - --------------------- - simple_occurs_check lhs_tv - | lhs_tv == occ_tv || check_kind (tyVarKind occ_tv) - = failCheckWith (cteProblem occ_prob) + | isSkolemTyVar occ_tv -> TyVarCheck_Error (cteProblem cteSkolemEscape) + | otherwise -> TyVarCheck_Promote (Just lhs_tv_lvl) Nothing | otherwise - = success - where - (check_kind, _) = mkOccFolders lhs_tv + = TyVarCheck_Success - --------------------- - can_make_concrete occ_tv = case tcTyVarDetails occ_tv of - MetaTv { mtv_info = info } -> case info of - ConcreteTv {} -> True - TauTv {} -> True - _ -> False - _ -> False -- Don't attempt to make other type variables concrete - -- (e.g. SkolemTv, TyVarTv, CycleBreakerTv, RuntimeUnkTv). + -- Combine the results of individual checks. See 'TyVarCheckResult'. + do_rhs_checks :: [TyVarCheckResult] -> TcM (PuResult a Reduction) + do_rhs_checks checks = + case mconcat checks of + TyVarCheck_Success -> success + TyVarCheck_Promote mb_lvl mb_conc -> promote mb_lvl mb_conc + TyVarCheck_Error cte_prob -> failCheckWith cte_prob --------------------- - -- occ_tv is definitely a MetaTyVar - promote lhs_tv lhs_tv_info lhs_tv_lvl + -- occ_tv is definitely a MetaTyVar; we need to promote it/make it concrete + promote :: Maybe TcLevel -> Maybe ConcreteTvOrigin -> TcM (PuResult a Reduction) + promote mb_lhs_tv_lvl mb_conc | MetaTv { mtv_info = info_occ, mtv_tclvl = lvl_occ } <- tcTyVarDetails occ_tv - = do { let new_info | isConcreteInfo lhs_tv_info = lhs_tv_info - | otherwise = info_occ - new_lvl = lhs_tv_lvl `minTcLevel` lvl_occ - -- c[conc,3] ~ p[tau,2]: want to clone p:=p'[conc,2] - -- c[tau,2] ~ p[tau,3]: want to clone p:=p'[tau,2] + = do { let new_info | Just conc <- mb_conc = ConcreteTv conc + | otherwise = info_occ + new_lvl = + case mb_lhs_tv_lvl of + Nothing -> lvl_occ + Just lhs_tv_lvl -> lhs_tv_lvl `minTcLevel` lvl_occ + -- c[conc,3] ~ p[tau,2]: want to clone p:=p'[conc,2] + -- c[tau,2] ~ p[tau,3]: want to clone p:=p'[tau,2] -- Check the kind of occ_tv - ; reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfType (tyVarKind occ_tv)) - - ; if cterHasNoProblem reason -- Successfully promoted - then do { new_tv_ty <- promote_meta_tyvar new_info new_lvl occ_tv - ; okCheckRefl new_tv_ty } - else failCheckWith reason } + -- + -- This is important for several reasons: + -- + -- 1. To ensure there is no occurs check or skolem-escape + -- in the kind of occ_tv. + -- 2. If the LHS is a concrete type variable and the RHS is an + -- unfilled meta-tyvar, we need to ensure that the kind of + -- 'occ_tv' is concrete. Test cases: T23051, T23176. + ; let occ_kind = tyVarKind occ_tv + ; kind_result <- checkTyEqRhs flags occ_kind + ; traceTc "checkTyVar: kind check" $ + vcat [ text "occ_tv:" <+> ppr occ_tv <+> dcolon <+> ppr occ_kind + , text "checkTyEqRHS result:" <+> pprPur kind_result + ] + ; for kind_result $ \ kind_redn -> + do { let kind_co = reductionCoercion kind_redn + new_kind = reductionReducedType kind_redn + ; new_tv_ty <- promote_meta_tyvar new_info new_lvl (setTyVarKind occ_tv new_kind) + ; return $ mkGReflLeftRedn Nominal new_tv_ty (mkSymCo kind_co) + } } | otherwise = pprPanic "promote" (ppr occ_tv) ------------------------- checkPromoteFreeVars :: CheckTyEqProblem -- What occurs check problem to report - -> TcTyVar -> TcLevel + -> Name -> TcLevel -> TyCoVarSet -> TcM CheckTyEqResult -- Check this set of TyCoVars for -- (a) occurs check @@ -3540,11 +3720,11 @@ checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl vs ; return (mconcat oks) } where do_one :: TyCoVar -> TcM CheckTyEqResult - do_one v | isCoVar v = return cteOK - | lhs_tv == v = return (cteProblem occ_prob) - | no_promotion = return cteOK - | not (isMetaTyVar v) = return (cteProblem cteSkolemEscape) - | otherwise = promote_one v + do_one v | isCoVar v = return cteOK + | tyVarName v == lhs_tv = return (cteProblem occ_prob) + | no_promotion = return cteOK + | not (isMetaTyVar v) = return (cteProblem cteSkolemEscape) + | otherwise = promote_one v where no_promotion = not (tcTyVarLevel v `strictlyDeeperThan` lhs_tv_lvl) @@ -3606,3 +3786,119 @@ checkTopShape info xi _ -> False CycleBreakerTv -> False -- We never unify these _ -> True + +-------------------------------------------------------------------------------- +-- Making a type concrete. + +-- | Try to turn the provided type into a concrete type, by ensuring +-- unfilled metavariables are appropriately marked as concrete. +-- +-- Returns a coercion whose RHS is a zonked type which is "as concrete as possible", +-- and a collection of Wanted equality constraints that are necessary to make +-- the type concrete. +-- +-- For example, for an input @TYPE a[sk]@ we will return a coercion with RHS +-- @TYPE gamma[conc]@ together with the Wanted equality constraint @a ~# gamma at . +-- +-- INVARIANT: the RHS type of the returned coercion is equal to the input type, +-- up to zonking and the returned Wanted equality constraints. +-- +-- INVARIANT: if this function returns an empty list of constraints +-- then the RHS type of the returned coercion is concrete, +-- in the sense of Note [Concrete types]. +makeTypeConcrete :: FastString -> ConcreteTvOrigin + -> TcType -> TcM (TcCoercion, Cts) +makeTypeConcrete occ_fs conc_orig ty = + do { traceTc "makeTypeConcrete {" $ + vcat [ text "ty:" <+> ppr ty ] + + -- To make a type 'ty' concrete, we query what would happen were we + -- to try unifying + -- + -- alpha[conc] ~# ty + -- + -- for a fresh concrete metavariable 'alpha'. + -- + -- We do this by calling 'checkTyEqRhs' with suitable 'TyEqFlags'. + -- NB: we don't actually need to create a fresh concrete metavariable + -- in order to call 'checkTyEqRhs'. + ; let ty_eq_flags = + TEF { tef_task = + TEFTyVar + { tefTyVar_occursCheck = Nothing + -- LHS is a fresh meta-tyvar: no occurs check needed + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Just conc_orig + } + , tef_fam_app = TEFA_Fail + } + + -- NB: 'checkTyEqRhs' expects a fully zonked type as input. + ; ty' <- liftZonkM $ zonkTcType ty + ; pu_res <- checkTyEqRhs @() ty_eq_flags ty' + -- NB: 'checkTyEqRhs' will also check the kind, thus upholding the + -- invariant that the kind of a concrete type must also be a concrete type. + + ; (cts, final_co) <- + case pu_res of + PuOK _ redn -> + do { traceTc "makeTypeConcrete: unifier success" $ + vcat [ text "ty:" <+> ppr ty <+> dcolon <+> ppr (typeKind ty) + , text "redn:" <+> ppr redn + ] + ; return (emptyBag, mkSymCo $ reductionCoercion redn) + -- NB: the unifier returns a 'Reduction' with the concrete + -- type on the left, but we want a coercion with it on the + -- right; so we use 'mkSymCo'. + } + PuFail _prob -> + do { traceTc "makeTypeConcrete: unifier failure" $ + vcat [ text "ty:" <+> ppr ty <+> dcolon <+> ppr (typeKind ty) + , text "problem:" <+> ppr _prob + ] + -- We failed to make 'ty' concrete. In order to continue + -- typechecking, we proceed as follows: + -- + -- - create a new concrete metavariable alpha[conc] + -- - emit the equality @ty ~# alpha[conc]@. + -- + -- This equality will eventually get reported as insoluble + -- to the user. + + -- The kind of a concrete metavariable must itself be concrete, + -- so we need to do a concreteness check on the kind first. + ; let ki = typeKind ty + ; (kind_co, kind_cts) <- + if isConcreteType ki + then return (mkNomReflCo ki, emptyBag) + else makeTypeConcrete occ_fs conc_orig ki + + -- Now create the new concrete metavariable. + ; conc_tv <- newConcreteTyVar conc_orig occ_fs (coercionRKind kind_co) + ; let conc_ty = mkTyVarTy conc_tv + pty = mkEqPredRole Nominal ty' conc_ty + ; hole <- newCoercionHoleO orig pty + ; loc <- getCtLocM orig (Just KindLevel) + ; let ct = mkNonCanonical + $ CtWanted { ctev_pred = pty + , ctev_dest = HoleDest hole + , ctev_loc = loc + , ctev_rewriters = emptyRewriterSet } + ; return (kind_cts S.<> unitBag ct, HoleCo hole) + } + + ; traceTc "makeTypeConcrete }" $ + vcat [ text "ty :" <+> _ppr_ty ty + , text "ty':" <+> _ppr_ty ty' + , text "final_co:" <+> _ppr_co final_co ] + + ; return (final_co, cts) + } + where + + _ppr_ty ty = ppr ty <+> dcolon <+> ppr (typeKind ty) + _ppr_co co = ppr co <+> dcolon <+> parens (_ppr_ty (coercionLKind co)) <+> text "~#" <+> parens (_ppr_ty (coercionRKind co)) + + orig :: CtOrigin + orig = case conc_orig of + ConcreteFRR frr_orig -> FRROrigin frr_orig ===================================== compiler/GHC/Tc/Utils/Unify.hs-boot ===================================== @@ -1,11 +1,15 @@ module GHC.Tc.Utils.Unify where import GHC.Prelude -import GHC.Core.Type ( Mult ) -import GHC.Tc.Utils.TcType ( TcTauType ) -import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Evidence ( TcCoercion ) -import GHC.Tc.Types.Origin ( CtOrigin, TypedThing ) +import GHC.Core.Type ( Mult ) +import GHC.Tc.Utils.TcType ( TcTauType ) +import GHC.Tc.Types ( TcM ) +import GHC.Tc.Types.Constraint ( Cts ) +import GHC.Tc.Types.Evidence ( TcCoercion ) +import GHC.Tc.Types.Origin ( CtOrigin, TypedThing ) +import GHC.Tc.Utils.TcType ( TcType, ConcreteTvOrigin ) + +import GHC.Data.FastString ( FastString ) -- This boot file exists only to tie the knot between @@ -15,3 +19,6 @@ unifyType :: Maybe TypedThing -> TcTauType -> TcTauType -> TcM TcCoerci unifyInvisibleType :: TcTauType -> TcTauType -> TcM TcCoercion tcSubMult :: CtOrigin -> Mult -> Mult -> TcM () + +makeTypeConcrete :: FastString -> ConcreteTvOrigin + -> TcType -> TcM (TcCoercion, Cts) ===================================== hie.yaml ===================================== @@ -5,4 +5,4 @@ # cradle: {bios: {program: "./hadrian/hie-bios.bat"}} # # The format is documented here - https://github.com/mpickering/hie-bios -cradle: {bios: {program: "./hadrian/hie-bios"}} +cradle: {bios: {program: "./hadrian/hie-bios.bat"}} ===================================== testsuite/tests/indexed-types/should_compile/T25611a.hs ===================================== @@ -12,6 +12,6 @@ data family Fix0 :: (k -> Type) -> k newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } -- This is the GADT newtype instance case --- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` --- data family Fix2 :: (k -> Type) -> k --- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f +-- enabled since !13809 +data family Fix2 :: (k -> Type) -> k +newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/rep-poly/RepPolyInferPatBind.stderr ===================================== @@ -1,4 +1,3 @@ - RepPolyInferPatBind.hs:21:1: error: [GHC-55287] The binder ‘x’ does not have a fixed runtime representation. Its type is: @@ -8,9 +7,8 @@ RepPolyInferPatBind.hs:21:2: error: [GHC-55287] • The pattern binding does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘c0’ - because the former is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T In the pattern: x :: T In a pattern binding: (x :: T) = x + ===================================== testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr ===================================== @@ -1,12 +1,10 @@ - RepPolyInferPatSyn.hs:22:16: error: [GHC-55287] • The pattern synonym argument pattern does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘c0’ - because the former is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T In the pattern: a :: T In the declaration for pattern synonym ‘P’ + ===================================== testsuite/tests/rep-poly/RepPolyTuple3.stderr ===================================== @@ -1,6 +1,6 @@ - RepPolyTuple3.hs:21:9: error: [GHC-18872] • Couldn't match kind ‘FloatRep’ with ‘IntRep’ arising from a representation-polymorphism check • In the expression: (#,#) @RR @RR x In an equation for ‘bar’: bar x = (#,#) @RR @RR x + ===================================== testsuite/tests/rep-poly/T23153.stderr ===================================== @@ -1,4 +1,3 @@ - T23153.hs:8:1: error: [GHC-52083] The argument ‘(h ())’ of ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. @@ -13,3 +12,4 @@ T23153.hs:8:1: error: [GHC-52083] The argument ‘(h ())’ of ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. Suggested fix: Add a type signature. + ===================================== testsuite/tests/rep-poly/T23154.stderr ===================================== @@ -1,3 +1,7 @@ +T23154.hs:7:1: error: [GHC-52083] + The first pattern in the equation for ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. T23154.hs:7:1: error: [GHC-52083] The first pattern in the equation for ‘f’ @@ -8,3 +12,4 @@ T23154.hs:7:1: error: [GHC-52083] The first pattern in the equation for ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. Suggested fix: Add a type signature. + ===================================== testsuite/tests/simd/should_run/T25658.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\a _ -> a) ===================================== testsuite/tests/simd/should_run/T25658.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (0,11) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -25,6 +25,8 @@ test('word16x8_basic_baseline', [], compile_and_run, ['']) test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) +test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation + # Ensure we set the CPU features we have available. # # This is especially important with the LLVM backend, as LLVM can otherwise View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c20734e6dbeda89d7ed3337be3764fdbbce3c9f3...f82cd8a9b8fcb1fec11b10aaff4933dae3691e9d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c20734e6dbeda89d7ed3337be3764fdbbce3c9f3...f82cd8a9b8fcb1fec11b10aaff4933dae3691e9d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 17:35:20 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 17 Jan 2025 12:35:20 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25661 Message-ID: <678a94d840933_f2bb57b25dc197e0@gitlab.mail> Simon Peyton Jones pushed new branch wip/T25661 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25661 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 21:58:11 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Fri, 17 Jan 2025 16:58:11 -0500 Subject: [Git][ghc/ghc][wip/T25661] Fix a buglet in tcSplitForAllTyVarsReqTVBindersN Message-ID: <678ad27316036_191ccf4f25cc90747@gitlab.mail> Simon Peyton Jones pushed to branch wip/T25661 at Glasgow Haskell Compiler / GHC Commits: 98e06512 by Simon Peyton Jones at 2025-01-17T21:57:18+00:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 7 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Var.hs - + testsuite/tests/polykinds/T25661.hs - + testsuite/tests/polykinds/T25661.stderr - testsuite/tests/polykinds/all.T Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -155,11 +155,13 @@ data Type | ForAllTy -- See Note [ForAllTy] {-# UNPACK #-} !ForAllTyBinder - Type -- ^ A Π type. - -- See Note [Why ForAllTy can quantify over a coercion variable] - -- INVARIANT: If the binder is a coercion variable, it must - -- be mentioned in the Type. - -- See Note [Unused coercion variable in ForAllTy] + -- ForAllTyBinder: see GHC.Types.Var + -- Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] + Type + -- INVARIANT: If the binder is a coercion variable, it must + -- be mentioned in the Type. + -- See Note [Unused coercion variable in ForAllTy] + -- See Note [Why ForAllTy can quantify over a coercion variable] | FunTy -- ^ FUN m t1 t2 Very common, so an important special case -- See Note [Function types] ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -120,13 +120,17 @@ tcFunBindMatches ctxt fun_name mult matches invis_pat_tys exp_ty -- Makes sure that if the binding is unrestricted, it counts as -- consuming its rhs Many times. - do { traceTc "tcFunBindMatches 2" (vcat [ pprUserTypeCtxt ctxt, ppr invis_pat_tys - , ppr pat_tys $$ ppr rhs_ty ]) + do { traceTc "tcFunBindMatches 2" $ + vcat [ text "ctxt:" <+> pprUserTypeCtxt ctxt + , text "arity:" <+> ppr arity + , text "invis_pat_tys:" <+> ppr invis_pat_tys + , text "pat_tys:" <+> ppr pat_tys + , text "rhs_ty:" <+> ppr rhs_ty ] ; tcMatches tcBody (invis_pat_tys ++ pat_tys) rhs_ty matches } ; return (wrap_fun, r) } where - herald = ExpectedFunTyMatches (NameThing fun_name) matches + herald = ExpectedFunTyMatches (NameThing fun_name) matches funBindPrecondition :: MatchGroup GhcRn (LHsExpr GhcRn) -> Bool funBindPrecondition (MG { mg_alts = L _ alts }) ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -1490,8 +1490,10 @@ tcSplitForAllTyVarsReqTVBindersN n_req ty = split n_req ty ty [] where split n_req _orig_ty (ForAllTy b@(Bndr _ argf) ty) bs - | isVisibleForAllTyFlag argf, n_req > 0 = split (n_req - 1) ty ty (b:bs) - | otherwise = split n_req ty ty (b:bs) + | isVisibleForAllTyFlag argf, n_req > 0 -- Split off a visible forall + = split (n_req - 1) ty ty (b:bs) + | isInvisibleForAllTyFlag argf -- Split off an invisible forall, + = split n_req ty ty (b:bs) -- even if n_req=0, i.e. the trailing ones split n_req orig_ty ty bs | Just ty' <- coreView ty = split n_req orig_ty ty' bs split n_req orig_ty _ty bs = (n_req, reverse bs, orig_ty) @@ -1975,7 +1977,7 @@ isSigmaTy :: TcType -> Bool -- forall a. blah -- Eq a => blah -- ?x::Int => blah --- But not +-- But NOT -- forall a -> blah isSigmaTy (ForAllTy (Bndr _ af) _) = isInvisibleForAllTyFlag af isSigmaTy (FunTy { ft_af = af }) = isInvisibleFunArg af ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -648,6 +648,7 @@ data VarBndr var argf = Bndr var argf -- A 'ForAllTyBinder' is the binder of a ForAllTy -- It's convenient to define this synonym here rather its natural -- home in "GHC.Core.TyCo.Rep", because it's used in GHC.Core.DataCon.hs-boot +-- See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] -- -- A 'TyVarBinder' is a binder with only TyVar type ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag ===================================== testsuite/tests/polykinds/T25661.hs ===================================== @@ -0,0 +1,38 @@ +{-# Language TypeFamilyDependencies #-} +{-# Language RequiredTypeArguments #-} +module T25661 where + +import Data.Kind +import Control.Category (Category(id, (.))) +import Prelude hiding (id, (.)) + +type Cat :: Type -> Type +type Cat k = k -> k -> Type +-- type Op :: (k -> j -> Type) -> (j -> k -> Type) +-- newtype Op cat b a = Op (cat a b) + +-- instance Category cat => Category (Op @k @k cat) where +-- id = Op id +-- Op f . Op g = Op (g . f) + +type NaturalTransformation :: Cat s -> Cat t -> Cat (s -> t) +data NaturalTransformation src tgt f g where + -- NaturalTransformationId :: NaturalTransformation src tgt f f + NaturalTransformation :: (FunctorOf src tgt f, FunctorOf src tgt g) => { getNaturalTransformation :: forall x. f x `tgt` g x } -> NaturalTransformation src tgt f g + +type + FunctorOf :: Cat s -> Cat t -> (s -> t) -> Constraint +class (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f +instance (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f + +type + NewFunctor :: (s -> t) -> Constraint +class (Category (Source f), Category (Target f)) => NewFunctor (f :: s -> t) where + type Source (f :: s -> t) :: Cat s + type Target (f :: s -> t) :: Cat t + newmap :: Source f a a' -> Target f (f a) (f a') + + +newmapVis :: NewFunctor f => forall source -> source ~ Source f + => forall target -> target ~ Target f => source a a' -> target (f a) (f a') +newmapVis source = undefined ===================================== testsuite/tests/polykinds/T25661.stderr ===================================== @@ -0,0 +1,17 @@ +T25661.hs:38:20: error: [GHC-91028] + • Couldn't match expected type ‘forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a')’ + with actual type ‘a0’ + Cannot instantiate unification variable ‘a0’ + with a type involving polytypes: + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + • In the expression: undefined + In an equation for ‘newmapVis’: newmapVis source = undefined + • Relevant bindings include + newmapVis :: forall (source :: Cat s) -> + (source ~ Source f) => + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + (bound at T25661.hs:38:1) + ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -247,3 +247,4 @@ test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) test('T24686', normal, compile_fail, ['']) test('T24686a', normal, compile_fail, ['']) +test('T25661', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/98e065128cd723bfa5edf13c9bc2f03149770938 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/98e065128cd723bfa5edf13c9bc2f03149770938 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 17 22:49:41 2025 From: gitlab at gitlab.haskell.org (=?UTF-8?B?TWF0ZXVzeiBHb8WbbGlub3dza2kgKEBTd29yZGxhc2gp?=) Date: Fri, 17 Jan 2025 17:49:41 -0500 Subject: [Git][ghc/ghc][wip/swordlash/allow_multiline_strings_in_js_ffi] 3 commits: Use checkTyEqRhs to make types concrete Message-ID: <678ade85c527e_1c65e71218086375d@gitlab.mail> Mateusz Goślinowski pushed to branch wip/swordlash/allow_multiline_strings_in_js_ffi at Glasgow Haskell Compiler / GHC Commits: 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 26 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Utils/Concrete.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Tc/Utils/Unify.hs - compiler/GHC/Tc/Utils/Unify.hs-boot - docs/users_guide/9.14.1-notes.rst - hie.yaml - + testsuite/tests/javascript/T25633.hs - + testsuite/tests/javascript/T25633.stdout - testsuite/tests/javascript/all.T - testsuite/tests/rep-poly/RepPolyInferPatBind.stderr - testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr - testsuite/tests/rep-poly/RepPolyTuple3.stderr - testsuite/tests/rep-poly/T23153.stderr - testsuite/tests/rep-poly/T23154.stderr - + testsuite/tests/simd/should_run/T25658.hs - + testsuite/tests/simd/should_run/T25658.stdout - testsuite/tests/simd/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD II64 (OpReg r) (OpReg dst)) + (MOVD FF64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD II64 (OpReg tmp) (OpReg dst)) + (MOVD FF64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -235,7 +235,8 @@ module GHC.Core.Type ( -- * Kinds isTYPEorCONSTRAINT, - isConcreteType, isFixedRuntimeRepKind, + isConcreteType, + isFixedRuntimeRepKind ) where import GHC.Prelude @@ -2869,12 +2870,14 @@ isFixedRuntimeRepKind k isConcreteType :: Type -> Bool isConcreteType = isConcreteTypeWith emptyVarSet -isConcreteTypeWith :: TyVarSet -> Type -> Bool +-- | Like 'isConcreteType', but allows passing in a set of 'TyVar's that +-- should be considered concrete. +-- -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. --- For this "With" version we pass in a set of TyVars to be considered --- concrete. This supports mkSynonymTyCon, which needs to test the RHS --- for concreteness, under the assumption that the binders are instantiated --- to concrete types +isConcreteTypeWith :: TyVarSet -> Type -> Bool +-- This version, with a 'TyVarSet' argument, supports 'mkSynonymTyCon', +-- which needs to test the RHS for concreteness, under the assumption that +-- the binders are instantiated to concrete types isConcreteTypeWith conc_tvs = go where go (TyVarTy tv) = isConcreteTyVar tv || tv `elemVarSet` conc_tvs @@ -2888,6 +2891,7 @@ isConcreteTypeWith conc_tvs = go go CastTy{} = False go CoercionTy{} = False + go_tc :: TyCon -> [Type] -> Bool go_tc tc tys | isForgetfulSynTyCon tc -- E.g. type S a = Int -- Then (S x) is concrete even if x isn't @@ -2903,7 +2907,6 @@ isConcreteTypeWith conc_tvs = go | otherwise -- E.g. type families = False - {- %************************************************************************ %* * ===================================== compiler/GHC/Parser.y ===================================== @@ -2148,6 +2148,9 @@ fspec :: { Located (TokDcolon : STRING var '::' sigtype { sLL $1 $> (epUniTok $3 ,(L (getLoc $1) (getStringLiteral $1), $2, $4)) } + | STRING_MULTI var '::' sigtype { sLL $1 $> (epUniTok $3 + ,(L (getLoc $1) + (getStringMultiLiteral $1), $2, $4)) } | var '::' sigtype { sLL $1 $> (epUniTok $2 ,(noLoc (StringLiteral NoSourceText nilFS Nothing), $1, $3)) } -- if the entity string is missing, it defaults to the empty string; @@ -4247,6 +4250,7 @@ getINCOHERENT_PRAGs (L _ (ITincoherent_prag src)) = src getCTYPEs (L _ (ITctype src)) = src getStringLiteral l = StringLiteral (getSTRINGs l) (getSTRING l) Nothing +getStringMultiLiteral l = StringLiteral (getSTRINGMULTIs l) (getSTRINGMULTI l) Nothing isUnicode :: Located Token -> Bool isUnicode (L _ (ITforall iu)) = iu == UnicodeSyntax ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -1048,8 +1048,7 @@ reportNotConcreteErrs ctxt errs@(err0:_) | frr_errs <- go frr_errs errs = case err of NCE_FRR - { nce_frr_origin = frr_orig - , nce_reasons = _not_conc } -> + { nce_frr_origin = frr_orig } -> FRR_Info { frr_info_origin = frr_orig , frr_info_not_concrete = Nothing } ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -1202,8 +1202,7 @@ tc_inst_forall_arg conc_tvs (tvb, inner_ty) hs_ty -> -- Example: user wrote e.g. (#,#) @(F Bool) for a type family F. -- Emit [W] F Bool ~ kappa[conc] and pretend the user wrote (#,#) @kappa. - do { mco <- unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0 - ; return $ case mco of { MRefl -> ty_arg0; MCo co -> coercionRKind co } } + coercionRKind <$> unifyConcrete (occNameFS $ getOccName $ tv_nm) conc ty_arg0 ; let fun_ty = mkForAllTy tvb inner_ty in_scope = mkInScopeSet (tyCoVarsOfTypes [fun_ty, ty_arg]) ===================================== compiler/GHC/Tc/Solver/Default.hs ===================================== @@ -440,7 +440,7 @@ defaultEquality ct where try_default_tv lhs_tv rhs_ty - | MetaTv { mtv_info = info, mtv_tclvl = lvl } <- tcTyVarDetails lhs_tv + | MetaTv { mtv_info = info } <- tcTyVarDetails lhs_tv , tyVarKind lhs_tv `tcEqType` typeKind rhs_ty , checkTopShape info rhs_ty -- Do not test for touchability of lhs_tv; that is the whole point! @@ -449,14 +449,13 @@ defaultEquality ct -- checkTyEqRhs: check that we can in fact unify lhs_tv := rhs_ty -- See Note [Defaulting equalities] - -- LC_Promote: promote deeper unification variables (DE4) - -- LC_Promote True: ...including under type families (DE5) - ; let flags :: TyEqFlags () - flags = TEF { tef_foralls = False - , tef_fam_app = TEFA_Recurse - , tef_lhs = TyVarLHS lhs_tv - , tef_unifying = Unifying info lvl (LC_Promote True) - , tef_occurs = cteInsolubleOccurs } + ; let task :: TEFTask + task = unifyingLHSMetaTyVar_TEFTask lhs_tv (LC_Promote True) + -- LC_Promote: promote deeper unification variables (DE4) + -- LC_Promote True: ...including under type families (DE5) + flags :: TyEqFlags () + flags = TEF { tef_task = task + , tef_fam_app = TEFA_Recurse } ; res :: PuResult () Reduction <- wrapTcS (checkTyEqRhs flags rhs_ty) ; case res of ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -201,6 +201,7 @@ import GHC.Exts (oneShot) import Control.Monad import Data.IORef import Data.List ( mapAccumL ) +import Data.Maybe ( isJust ) import Data.Foldable import qualified Data.Semigroup as S import GHC.Types.SrcLoc @@ -2122,7 +2123,7 @@ checkTouchableTyVarEq ev lhs_tv rhs _ -> pprPanic "checkTouchableTyVarEq" (ppr lhs_tv) -- lhs_tv should be a meta-tyvar - is_concrete_lhs_tv = isConcreteInfo lhs_tv_info + is_concrete_lhs_tv = isJust $ concreteInfo_maybe lhs_tv_info check_rhs rhs -- Crucial special case for alpha ~ F tys @@ -2134,11 +2135,9 @@ checkTouchableTyVarEq ev lhs_tv rhs | otherwise = checkTyEqRhs flags rhs - flags = TEF { tef_foralls = False -- isRuntimeUnkSkol lhs_tv - , tef_fam_app = mkTEFA_Break ev NomEq break_wanted - , tef_unifying = Unifying lhs_tv_info lhs_tv_lvl (LC_Promote False) - , tef_lhs = TyVarLHS lhs_tv - , tef_occurs = cteInsolubleOccurs } + flags = TEF { tef_task = unifyingLHSMetaTyVar_TEFTask lhs_tv (LC_Promote False) + , tef_fam_app = mkTEFA_Break ev NomEq break_wanted + } arg_flags = famAppArgFlags flags @@ -2147,7 +2146,8 @@ checkTouchableTyVarEq ev lhs_tv rhs -- Occurs check or skolem escape; so flatten = do { let fam_app_kind = typeKind fam_app ; reason <- checkPromoteFreeVars cteInsolubleOccurs - lhs_tv lhs_tv_lvl (tyCoVarsOfType fam_app_kind) + (tyVarName lhs_tv) lhs_tv_lvl + (tyCoVarsOfType fam_app_kind) ; if not (cterHasNoProblem reason) -- Failed to promote free vars then failCheckWith reason else @@ -2210,19 +2210,15 @@ checkTypeEq ev eq_rel lhs rhs arg_flags = famAppArgFlags given_flags given_flags :: TyEqFlags (TcTyVar,TcType) - given_flags = TEF { tef_lhs = lhs - , tef_foralls = False - , tef_unifying = NotUnifying - , tef_fam_app = mkTEFA_Break ev eq_rel break_given - , tef_occurs = occ_prob } + given_flags = TEF { tef_task = notUnifying_TEFTask occ_prob lhs + , tef_fam_app = mkTEFA_Break ev eq_rel break_given + } -- TEFA_Break used for: [G] a ~ Maybe (F a) -- or [W] F a ~ Maybe (F a) - wanted_flags = TEF { tef_lhs = lhs - , tef_foralls = False - , tef_unifying = NotUnifying - , tef_fam_app = TEFA_Recurse - , tef_occurs = occ_prob } + wanted_flags = TEF { tef_task = notUnifying_TEFTask occ_prob lhs + , tef_fam_app = TEFA_Recurse + } -- TEFA_Recurse: see Note [Don't cycle-break Wanteds when not unifying] -- occ_prob: see Note [Occurs check and representational equality] @@ -2289,7 +2285,7 @@ where both sides are TyFamLHSs. We don't want to flatten that RHS to Instead we'd like to say "occurs-check" and swap LHS and RHS, which yields a canonical constraint [G] G (...(F ty)...) ~ F ty -That tents to rewrite a big type to smaller one. This happens in T15703, +That tends to rewrite a big type to smaller one. This happens in T15703, where we had: [G] Pure g ~ From1 (To1 (Pure g)) Making a loop breaker and rewriting left to right just makes much bigger ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -52,7 +52,6 @@ module GHC.Tc.Types.Constraint ( Hole(..), HoleSort(..), isOutOfScopeHole, DelayedError(..), NotConcreteError(..), - NotConcreteReason(..), WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, @@ -132,7 +131,6 @@ import Data.Coerce import qualified Data.Semigroup as S import Control.Monad ( msum, when ) import Data.Maybe ( mapMaybe, isJust ) -import Data.List.NonEmpty ( NonEmpty ) -- these are for CheckTyEqResult import Data.Word ( Word8 ) @@ -435,30 +433,8 @@ data NotConcreteError -- ^ Where did this check take place? , nce_frr_origin :: FixedRuntimeRepOrigin -- ^ Which representation-polymorphism check did we perform? - , nce_reasons :: NonEmpty NotConcreteReason - -- ^ Why did the check fail? } --- | Why did we decide that a type was not concrete? -data NotConcreteReason - -- | The type contains a 'TyConApp' of a non-concrete 'TyCon'. - -- - -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. - = NonConcreteTyCon TyCon [TcType] - - -- | The type contains a type variable that could not be made - -- concrete (e.g. a skolem type variable). - | NonConcretisableTyVar TyVar - - -- | The type contains a cast. - | ContainsCast TcType TcCoercionN - - -- | The type contains a forall. - | ContainsForall ForAllTyBinder TcType - - -- | The type contains a 'CoercionTy'. - | ContainsCoercionTy TcCoercion - instance Outputable NotConcreteError where ppr (NCE_FRR { nce_frr_origin = frr_orig }) = text "NCE_FRR" <+> parens (ppr (frr_type frr_orig)) ===================================== compiler/GHC/Tc/Utils/Concrete.hs ===================================== @@ -19,39 +19,35 @@ module GHC.Tc.Utils.Concrete import GHC.Prelude import GHC.Builtin.Names ( unsafeCoercePrimName ) -import GHC.Builtin.Types ( liftedTypeKindTyCon, unliftedTypeKindTyCon ) +import GHC.Builtin.Types -import GHC.Core.Coercion ( coToMCo, mkCastTyMCo - , mkGReflRightMCo, mkNomReflCo ) -import GHC.Core.TyCo.Rep ( Type(..), MCoercion(..) ) -import GHC.Core.TyCon ( isConcreteTyCon ) -import GHC.Core.Type ( isConcreteType, typeKind, mkFunTy) +import GHC.Core.Coercion +import GHC.Core.TyCo.Rep +import GHC.Core.Type -import GHC.Tc.Types.Constraint ( NotConcreteError(..), NotConcreteReason(..) ) -import GHC.Tc.Types.Evidence ( Role(..), TcCoercionN, TcMCoercionN ) +import GHC.Data.Bag + +import GHC.Tc.Types.Constraint +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Origin import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType -import GHC.Tc.Utils.TcMType +import {-# SOURCE #-} GHC.Tc.Utils.Unify import GHC.Types.Basic ( TypeOrKind(KindLevel) ) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Types.Name import GHC.Types.Name.Env -import GHC.Types.Var ( tyVarKind, tyVarName ) +import GHC.Types.Var import GHC.Utils.Misc ( HasDebugCallStack ) import GHC.Utils.Outputable +import GHC.Utils.Panic import GHC.Data.FastString ( FastString, fsLit ) - import Control.Monad ( void ) import Data.Functor ( ($>) ) -import Data.List.NonEmpty ( NonEmpty((:|)) ) -import Control.Monad.Trans.Class ( lift ) -import Control.Monad.Trans.Writer.CPS ( WriterT, runWriterT, tell ) {- Note [Concrete overview] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -221,7 +217,6 @@ other type variables, a 'ConcreteTv' type variable is a type variable which can only be unified with a concrete type (in the sense of Note [Concrete types]). INVARIANT: the kind of a concrete metavariable is concrete. - This invariant is upheld at the time of creation of a new concrete metavariable. Concrete metavariables are useful for representation-polymorphism checks: @@ -632,7 +627,7 @@ hasFixedRuntimeRep :: HasDebugCallStack -- That is, @ty'@ has a syntactically fixed RuntimeRep -- in the sense of Note [Fixed RuntimeRep]. hasFixedRuntimeRep frr_ctxt ty = - checkFRR_with (unifyConcrete (fsLit "cx") . ConcreteFRR) frr_ctxt ty + checkFRR_with (fmap (fmap coToMCo) . unifyConcrete_kind (fsLit "cx") . ConcreteFRR) frr_ctxt ty -- | Like 'hasFixedRuntimeRep', but we perform an eager syntactic check. -- @@ -700,226 +695,86 @@ checkFRR_with check_kind frr_ctxt ty frr_orig :: FixedRuntimeRepOrigin frr_orig = FixedRuntimeRepOrigin { frr_type = ty, frr_context = frr_ctxt } --- | Ensure that the given type @ty@ can unify with a concrete type, +-- | Ensure that the given kind @ki@ can unify with a concrete type, -- in the sense of Note [Concrete types]. -- --- Returns a coercion @co :: ty ~# conc_ty@, where @conc_ty@ is +-- Returns a coercion @co :: ki ~# conc_ki@, where @conc_ki@ is -- concrete. -- --- If the type is already syntactically concrete, this +-- If the kind is already syntactically concrete, this -- immediately returns a reflexive coercion. Otherwise, -- it creates a new concrete metavariable @concrete_tv@ --- and emits an equality constraint @ty ~# concrete_tv@, +-- and emits an equality constraint @ki ~# concrete_tv@, -- to be handled by the constraint solver. -- +-- Precondition: @ki@ must be of the form @TYPE rep@ or @CONSTRAINT rep at . +unifyConcrete_kind :: HasDebugCallStack + => FastString -- ^ name to use when creating concrete metavariables + -> ConcreteTvOrigin + -> TcKind + -> TcM TcCoercionN +unifyConcrete_kind occ_fs conc_orig ki + | Just (torc, rep) <- sORTKind_maybe ki + = do { let tc = case torc of + TypeLike -> tYPETyCon + ConstraintLike -> cONSTRAINTTyCon + ; rep_co <- unifyConcrete occ_fs conc_orig rep + ; return $ mkTyConAppCo Nominal tc [rep_co] } + | otherwise + = pprPanic "unifyConcrete_kind: kind is not of the form 'TYPE rep' or 'CONSTRAINT rep'" $ + ppr ki <+> dcolon <+> ppr (typeKind ki) + + +-- | Ensure the given type can be unified with +-- a concrete type, in the sense of Note [Concrete types]. +-- +-- Returns a coercion @co :: ty ~# conc_ty@, where @conc_ty@ is +-- concrete. +-- +-- If the type is already syntactically concrete, this +-- immediately returns a reflexive coercion. +-- Otherwise, it will create new concrete metavariables and emit +-- new Wanted equality constraints, to be handled by the constraint solver. +-- -- Invariant: the kind of the supplied type must be concrete. -- -- We assume the provided type is already at the kind-level -- (this only matters for error messages). -unifyConcrete :: HasDebugCallStack - => FastString -> ConcreteTvOrigin -> TcType -> TcM TcMCoercionN +unifyConcrete :: FastString -> ConcreteTvOrigin -> TcType -> TcM TcCoercionN unifyConcrete occ_fs conc_orig ty - = do { (ty, errs) <- makeTypeConcrete conc_orig ty - ; case errs of - -- We were able to make the type fully concrete. - { [] -> return MRefl - -- The type could not be made concrete; perhaps it contains - -- a skolem type variable, a type family application, ... - -- - -- Create a new ConcreteTv metavariable @concrete_tv@ - -- and unify @ty ~# concrete_tv at . - ; _ -> - do { conc_tv <- newConcreteTyVar conc_orig occ_fs ki - -- NB: newConcreteTyVar asserts that 'ki' is concrete. - ; coToMCo <$> emitWantedEq orig KindLevel Nominal ty (mkTyVarTy conc_tv) } } } - where - ki :: TcKind - ki = typeKind ty - orig :: CtOrigin - orig = case conc_orig of - ConcreteFRR frr_orig -> FRROrigin frr_orig + = do { (co, cts) <- makeTypeConcrete occ_fs conc_orig ty + ; emitSimples cts + ; return co } --- | Ensure that the given type is concrete. +-- | Ensure that the given kind @ki@ is concrete. -- -- This is an eager syntactic check, and never defers --- any work to the constraint solver. --- --- Invariant: the kind of the supplied type must be concrete. --- Invariant: the output type is equal to the input type, --- up to zonking. +-- any work to the constraint solver. However, +-- it may perform unification. -- --- We assume the provided type is already at the kind-level --- (this only matters for error messages). +-- Invariant: the output type is equal to the input type, up to zonking. ensureConcrete :: HasDebugCallStack => FixedRuntimeRepOrigin - -> TcType - -> TcM TcType -ensureConcrete frr_orig ty - = do { traceTc "ensureConcrete {" (ppr frr_orig $$ ppr ty) - ; (ty', errs) <- makeTypeConcrete conc_orig ty - ; case errs of - { err:errs -> - do { traceTc "ensureConcrete } failure" $ - vcat [ text "ty:" <+> ppr ty - , text "ty':" <+> ppr ty' ] + -> TcKind + -> TcM TcKind +ensureConcrete frr_orig ki + = do { (co, cts) <- makeTypeConcrete (fsLit "cx") conc_orig ki + ; let trace_msg = vcat [ text "ty: " <+> ppr ki + , text "co:" <+> ppr co ] + ; if isEmptyBag cts + then traceTc "ensureConcrete } success" trace_msg + else do { traceTc "ensureConcrete } failure" trace_msg ; loc <- getCtLocM (FRROrigin frr_orig) (Just KindLevel) ; emitNotConcreteError $ NCE_FRR { nce_loc = loc - , nce_frr_origin = frr_orig - , nce_reasons = err :| errs } - } - ; [] -> - traceTc "ensureConcrete } success" $ - vcat [ text "ty: " <+> ppr ty - , text "ty':" <+> ppr ty' ] } - ; return ty' } + , nce_frr_origin = frr_orig } + } + ; return $ coercionRKind co } where conc_orig :: ConcreteTvOrigin conc_orig = ConcreteFRR frr_orig -{-*********************************************************************** -%* * - Making a type concrete -%* * -%************************************************************************ - -Note [Unifying concrete metavariables] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Unifying concrete metavariables (as defined in Note [ConcreteTv]) is not -an all-or-nothing affair as it is for other sorts of metavariables. - -Consider the following unification problem in which all metavariables -are unfilled (and ignoring any TcLevel considerations): - - alpha[conc] ~# TYPE (TupleRep '[ beta[conc], IntRep, gamma[tau] ]) - -We can't immediately unify `alpha` with the RHS, because the RHS is not -a concrete type (in the sense of Note [Concrete types]). Instead, we -proceed as follows: - - - create a fresh concrete metavariable variable `gamma'[conc]`, - - write gamma[tau] := gamma'[conc], - - write alpha[conc] := TYPE (TupleRep '[ beta[conc], IntRep, gamma'[conc] ]). - -Thus, in general, to unify `alpha[conc] ~# rhs`, we first try to turn -`rhs` into a concrete type (see the 'makeTypeConcrete' function). -If this succeeds, resulting in a concrete type `rhs'`, we simply fill -`alpha[conc] := rhs'`. If it fails, then syntactic unification fails. - -Example 1: - - alpha[conc] ~# TYPE (TupleRep '[ beta[conc], IntRep, gamma[tau] ]) - - We proceed by filling metavariables: - - gamma[tau] := gamma[conc] - alpha[conc] := TYPE (TupleRep '[ beta[conc], IntRep, gamma[conc] ]) - - This successfully unifies alpha. - -Example 2: - - For a type family `F :: Type -> Type`: - - delta[conc] ~# TYPE (SumRep '[ zeta[tau], a[sk], F omega[tau] ]) - - We write zeta[tau] := zeta[conc], and then fail, providing the following - two reasons: - - - `a[sk]` is not a concrete type variable, so the overall type - cannot be concrete - - `F` is not a concrete type constructor, in the sense of - Note [Concrete types]. So we keep it as is; in particular, - we /should not/ try to make its argument `omega[tau]` into - a ConcreteTv. - - Note that making zeta concrete allows us to propagate information. - For example, after more typechecking, we might try to unify - `zeta ~# rr[sk]`. If we made zeta a ConcreteTv, we will report - this unsolved equality using the 'ConcreteTvOrigin' stored in zeta[conc]. - This allows us to report ALL the problems in a representation-polymorphism - check (instead of only a non-empty subset). --} - --- | Try to turn the provided type into a concrete type, by ensuring --- unfilled metavariables are appropriately marked as concrete. --- --- Returns a zonked type which is "as concrete as possible", and --- a list of problems encountered when trying to make it concrete. --- --- INVARIANT: the returned type is equal to the input type, up to zonking. --- INVARIANT: if this function returns an empty list of 'NotConcreteReasons', --- then the returned type is concrete, in the sense of Note [Concrete types]. -makeTypeConcrete :: ConcreteTvOrigin -> TcType -> TcM (TcType, [NotConcreteReason]) --- TODO: it could be worthwhile to return enough information to continue solving. --- Consider unifying `alpha[conc] ~# TupleRep '[ beta[tau], F Int ]` for --- a type family 'F'. --- This function will concretise `beta[tau] := beta[conc]` and return --- that `TupleRep '[ beta[conc], F Int ]` is not concrete because of the --- type family application `F Int`. But we could decompose by setting --- alpha := TupleRep '[ beta, gamma[conc] ] and emitting `[W] gamma[conc] ~ F Int`. -makeTypeConcrete conc_orig ty = - do { res@(ty', _) <- runWriterT $ go ty - ; traceTc "makeTypeConcrete" $ - vcat [ text "ty:" <+> ppr ty - , text "ty':" <+> ppr ty' ] - ; return res } - where - go :: TcType -> WriterT [NotConcreteReason] TcM TcType - go ty - | Just ty <- coreView ty - = go ty - | isConcreteType ty - = pure ty - go ty@(TyVarTy tv) -- not a ConcreteTv (already handled above) - = do { mb_filled <- lift $ isFilledMetaTyVar_maybe tv - ; case mb_filled of - { Just ty -> go ty - ; Nothing - | isMetaTyVar tv - , TauTv <- metaTyVarInfo tv - -> -- Change the MetaInfo to ConcreteTv, but retain the TcLevel - do { kind <- go (tyVarKind tv) - ; let occ_fs = occNameFS (getOccName tv) - -- occ_fs: preserve the occurrence name of the original tyvar - -- This helps in error messages - ; lift $ - do { conc_tv <- setTcLevel (tcTyVarLevel tv) $ - newConcreteTyVar conc_orig occ_fs kind - ; let conc_ty = mkTyVarTy conc_tv - ; liftZonkM $ writeMetaTyVar tv conc_ty - ; return conc_ty } } - | otherwise - -- Don't attempt to make other type variables concrete - -- (e.g. SkolemTv, TyVarTv, CycleBreakerTv, RuntimeUnkTv). - -> bale_out ty (NonConcretisableTyVar tv) } } - go ty@(TyConApp tc tys) - | isConcreteTyCon tc - = mkTyConApp tc <$> mapM go tys - | otherwise - = bale_out ty (NonConcreteTyCon tc tys) - go (FunTy af w ty1 ty2) - = do { w <- go w - ; ty1 <- go ty1 - ; ty2 <- go ty2 - ; return $ mkFunTy af w ty1 ty2 } - go (AppTy ty1 ty2) - = do { ty1 <- go ty1 - ; ty2 <- go ty2 - ; return $ mkAppTy ty1 ty2 } - go ty@(LitTy {}) - = return ty - go ty@(CastTy cast_ty kco) - = bale_out ty (ContainsCast cast_ty kco) - go ty@(ForAllTy tcv body) - = bale_out ty (ContainsForall tcv body) - go ty@(CoercionTy co) - = bale_out ty (ContainsCoercionTy co) - - bale_out :: TcType -> NotConcreteReason -> WriterT [NotConcreteReason] TcM TcType - bale_out ty reason = do { tell [reason]; return ty } - {-*********************************************************************** %* * Concrete type variables of Ids ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -755,7 +755,7 @@ newNamedAnonMetaTyVar tyvar_name meta_info kind = do { name <- newMetaTyVarName tyvar_name ; details <- newMetaDetails meta_info ; let tyvar = mkTcTyVar name kind details - ; traceTc "newAnonMetaTyVar" (ppr tyvar) + ; traceTc "newAnonMetaTyVar" (ppr tyvar <+> dcolon <+> ppr kind) ; return tyvar } -- makes a new skolem tv ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -53,7 +53,7 @@ module GHC.Tc.Utils.TcType ( isImmutableTyVar, isSkolemTyVar, isMetaTyVar, isMetaTyVarTy, isTyVarTy, tcIsTcTyVar, isTyVarTyVar, isOverlappableTyVar, isTyConableTyVar, ConcreteTvOrigin(..), isConcreteTyVar_maybe, isConcreteTyVar, - isConcreteTyVarTy, isConcreteTyVarTy_maybe, isConcreteInfo, + isConcreteTyVarTy, isConcreteTyVarTy_maybe, concreteInfo_maybe, ConcreteTyVars, noConcreteTyVars, isAmbiguousTyVar, isCycleBreakerTyVar, metaTyVarRef, metaTyVarInfo, isFlexi, isIndirect, isRuntimeUnkSkol, @@ -1266,9 +1266,9 @@ isConcreteTyVar_maybe tv | otherwise = Nothing -isConcreteInfo :: MetaInfo -> Bool -isConcreteInfo (ConcreteTv {}) = True -isConcreteInfo _ = False +concreteInfo_maybe :: MetaInfo -> Maybe ConcreteTvOrigin +concreteInfo_maybe (ConcreteTv conc_orig) = Just conc_orig +concreteInfo_maybe _ = Nothing -- | Is this type variable a concrete type variable, i.e. -- it is a metavariable with 'ConcreteTv' 'MetaInfo'? ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -1,8 +1,13 @@ +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE RecursiveDo #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TypeApplications #-} + {- (c) The University of Glasgow 2006 @@ -28,6 +33,7 @@ module GHC.Tc.Utils.Unify ( swapOverTyVars, touchabilityAndShapeTest, checkTopShape, lhsPriority, UnifyEnv(..), updUEnvLoc, setUEnvRole, uType, + makeTypeConcrete, -------------------------------- -- Holes @@ -41,8 +47,11 @@ module GHC.Tc.Utils.Unify ( checkTyEqRhs, recurseIntoTyConApp, PuResult(..), failCheckWith, okCheckRefl, mapCheck, - TyEqFlags(..), TyEqFamApp(..), AreUnifying(..), LevelCheck(..), FamAppBreaker, + TyEqFlags(..), TEFTask(..), + notUnifying_TEFTask, unifyingLHSMetaTyVar_TEFTask, + LevelCheck(..), TyEqFamApp(..), FamAppBreaker, famAppArgFlags, checkPromoteFreeVars, + simpleUnifyCheck, UnifyCheckCaller(..), fillInferResult, @@ -54,7 +63,7 @@ import GHC.Hs import GHC.Tc.Errors.Types ( ErrCtxtMsg(..) ) import GHC.Tc.Errors.Ppr ( pprErrCtxtMsg ) -import GHC.Tc.Utils.Concrete ( hasFixedRuntimeRep, hasFixedRuntimeRep_syntactic ) +import GHC.Tc.Utils.Concrete import GHC.Tc.Utils.Env import GHC.Tc.Utils.Instantiate import GHC.Tc.Utils.Monad @@ -94,11 +103,13 @@ import GHC.Utils.Panic import GHC.Driver.DynFlags import GHC.Data.Bag -import GHC.Data.FastString( fsLit ) +import GHC.Data.FastString import Control.Monad +import Data.Maybe (maybeToList, isJust) import Data.Monoid as DM ( Any(..) ) import qualified Data.Semigroup as S ( (<>) ) +import Data.Traversable (for) {- ********************************************************************* * * @@ -2927,7 +2938,7 @@ simpleUnifyCheck caller lhs_tv rhs = go rhs where - !(occ_in_ty, occ_in_co) = mkOccFolders lhs_tv + !(occ_in_ty, occ_in_co) = mkOccFolders (tyVarName lhs_tv) lhs_tv_lvl = tcTyVarLevel lhs_tv lhs_tv_is_concrete = isConcreteTyVar lhs_tv @@ -2974,7 +2985,7 @@ simpleUnifyCheck caller lhs_tv rhs go (LitTy {}) = True -mkOccFolders :: TcTyVar -> (TcType -> Bool, TcCoercion -> Bool) +mkOccFolders :: Name -> (TcType -> Bool, TcCoercion -> Bool) -- These functions return True -- * if lhs_tv occurs (incl deeply, in the kind of variable) -- * if there is a coercion hole @@ -2987,7 +2998,7 @@ mkOccFolders lhs_tv = (getAny . check_ty, getAny . check_co) , tcf_hole = do_hole , tcf_tycobinder = do_bndr } - do_tcv is v = Any (not (v `elemVarSet` is) && v == lhs_tv) + do_tcv is v = Any (not (v `elemVarSet` is) && tyVarName v == lhs_tv) `mappend` check_ty (varType v) do_bndr is tcv _faf = extendVarSet is tcv @@ -3058,10 +3069,7 @@ reductionCoercion is Refl. See `canEqCanLHSFinish_no_unification`. data PuResult a b = PuFail CheckTyEqResult | PuOK (Bag a) b - -instance Functor (PuResult a) where - fmap _ (PuFail prob) = PuFail prob - fmap f (PuOK cts x) = PuOK cts (f x) + deriving stock (Functor, Foldable, Traversable) instance Applicative (PuResult a) where pure x = PuOK emptyBag x @@ -3100,82 +3108,192 @@ mapCheck f xs -- | Options describing how to deal with a type equality -- in the pure unifier. See 'checkTyEqRhs' data TyEqFlags a - = TEF { tef_foralls :: Bool -- Allow foralls - , tef_lhs :: CanEqLHS -- LHS of the constraint - , tef_unifying :: AreUnifying -- Always NotUnifying if tef_lhs is TyFamLHS + = TEF { tef_task :: TEFTask + -- ^ LHS structure, and which checks to perform on the RHS , tef_fam_app :: TyEqFamApp a - , tef_occurs :: CheckTyEqProblem } -- Soluble or insoluble occurs check + -- ^ How to deal with type family applications + } + +-- | The structure of the LHS and which checks to perform in 'checkTyEqRhs', +-- for an equality @lhs ~# rhs at . +-- +-- See Note [TEFTask]. +data TEFTask + -- | LHS is a type family application; we are not unifying. + = TEFTyFam + { tefTyFam_occursCheck :: CheckTyEqProblem + -- ^ The 'CheckTyEqProblem' to report for occurs-check failures + -- (soluble or insoluble) + , tefTyFam_tyCon :: TyCon + , tefTyFam_args :: [Type] + } + -- | LHS is a 'TyVar'. + | TEFTyVar + { tefTyVar_occursCheck :: Maybe (Name, CheckTyEqProblem) + -- ^ Occurs check: LHS 'TyVar' 'Name', + -- and which 'CheckTyEqProblem' to report for occurs-check failures + -- (soluble or insoluble) + , tefTyVar_levelCheck :: Maybe (TcLevel, LevelCheck) + -- ^ Level check: LHS 'TyVar' 'TcLevel', + -- and which 'LevelCheck' to perform + , tefTyVar_concreteCheck :: Maybe ConcreteTvOrigin + -- ^ Concreteness check: LHS 'TyVar' 'ConcreteTvOrigin' + -- to use for the check + } + +{- Note [TEFTask] +~~~~~~~~~~~~~~~~~ +When we call the pure unifier, e.g. through 'checkTyEqRhs', we can decide what +kind of checks the unifier performs via the 'TyEqFlags' argument. In particular, +when the LHS type in a unification is a type variable, we might want to perform +different checks; this is achieved using the 'TEFTyVar' constructor to 'TEFTask': + + 1. LHS is a skolem tyvar, or an untouchable meta-tyvar. + We are not unifying; we only want to perform occurs-checks. + + TEFTyVar + { tefTyVar_occursCheck = Just ... + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Nothing + } + + 2. LHS is a touchable meta-tyvar. + We are unifying; we want to perform an occurs check, a level check, + and a concreteness check (when the meta-tyvar is a ConcreteTv). + + TEFTyVar + { tefTyVar_occursCheck = Just ... + , tefTyVar_levelCheck = Just ... + , tefTyVar_concreteCheck = isConcreteTyVar_maybe lhs_tv + } + + 3. LHS is a fresh ConcreteTv meta-tyvar (see call to 'checkTyEqRhs' in + 'makeTypeConcrete'). We are unifying; we only want to perform + a concreteness check. + + TEFTyVar + { tefTyVar_occursCheck = Nothing + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Just ... + } +-} + +-- | Create a "not unifying" 'TEFTask' from a 'CanEqLHS'. +-- +-- See use-case (1) in Note [TEFTask]. +notUnifying_TEFTask :: CheckTyEqProblem -> CanEqLHS -> TEFTask +notUnifying_TEFTask occ_prob = \case + TyFamLHS tc tys -> + TEFTyFam occ_prob tc tys + TyVarLHS tv -> + TEFTyVar + { tefTyVar_occursCheck = Just (tyVarName tv, occ_prob) + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Nothing + } + -- We need an occurs-check here, but no level check. + -- See Note [Promotion and level-checking] wrinkle (W1) + +-- | Create "unifying" 'TEFTask' from a 'TyVarLHS'. +-- +-- Invariant: the argument 'TyVar' is a 'MetaTv'. +unifyingLHSMetaTyVar_TEFTask :: TyVar -> LevelCheck -> TEFTask +unifyingLHSMetaTyVar_TEFTask lhs_tv lc = + TEFTyVar + { tefTyVar_occursCheck = Just (tyVarName lhs_tv, cteInsolubleOccurs) + , tefTyVar_levelCheck = Just (tcTyVarLevel lhs_tv, lc) + , tefTyVar_concreteCheck = isConcreteTyVar_maybe lhs_tv + } + +-- | Do we want to perform a concreteness check in 'checkTyEqRhs'? +tefTaskConcrete_maybe :: TEFTask -> Maybe ConcreteTvOrigin +tefTaskConcrete_maybe (TEFTyFam {}) = Nothing +tefTaskConcrete_maybe (TEFTyVar { tefTyVar_concreteCheck = conc }) = conc + +instance Outputable TEFTask where + ppr = \case + TEFTyFam occ tc tys -> + text "TEFTyFam" <+> ppr occ <+> ppr (mkTyConApp tc tys) + TEFTyVar mb_occ mb_lc mb_conc -> + text "TEFTyVar" <+> hcat (punctuate comma fields) + where + fields = [ text "OccursCheck:" <+> ppr tv | (tv, _) <- maybeToList mb_occ ] + ++ + [ text "LevelCheck:" <+> ppr lc | lc <- maybeToList mb_lc ] + ++ + [ text "ConcreteCheck" | isJust mb_conc ] -- | What to do when encountering a type-family application while processing -- a type equality in the pure unifier. -- -- See Note [Family applications in canonical constraints] data TyEqFamApp a - = TEFA_Fail -- Always fail - | TEFA_Recurse -- Just recurse - | TEFA_Break (FamAppBreaker a) -- Recurse, but replace with cycle breaker if fails, - -- using the FamAppBreaker - -data AreUnifying - = Unifying - MetaInfo -- MetaInfo of the LHS tyvar (which is a meta-tyvar) - TcLevel -- Level of the LHS tyvar - LevelCheck - - | NotUnifying -- Not attempting to unify + = TEFA_Fail -- ^ Always fail + | TEFA_Recurse -- ^ Just recurse + | TEFA_Break (FamAppBreaker a) -- ^ Recurse, but replace with cycle breaker if fails, + -- using the FamAppBreaker +-- | What level check to perform, in a call to the pure unifier? data LevelCheck - = LC_None -- Level check not needed: we should never encounter - -- a tyvar at deeper level than the LHS - - | LC_Check -- Do a level check between the LHS tyvar and the occurrence tyvar - -- Fail if the level check fails - - | LC_Promote -- Do a level check between the LHS tyvar and the occurrence tyvar - -- If the level check fails, and the occurrence is a unification - -- variable, promote it - Bool -- False <=> don't promote under type families (the common case) - -- True <=> promote even under type families - -- see Note [Defaulting equalities] in GHC.Tc.Solver + = LC_Check -- ^ Do a level check between the LHS tyvar and the occurrence tyvar. + -- + -- Fail if the level check fails. + + | LC_Promote Bool + -- ^ Do a level check between the LHS tyvar and the occurrence tyvar. + -- + -- If the level check fails, and the occurrence is a unification + -- variable, promote it. + -- + -- - False <=> don't promote under type families (the common case) + -- - True <=> promote even under type families + -- (see Note [Defaulting equalities] in GHC.Tc.Solver) instance Outputable (TyEqFlags a) where ppr (TEF { .. }) = text "TEF" <> braces ( - vcat [ text "tef_foralls =" <+> ppr tef_foralls - , text "tef_lhs =" <+> ppr tef_lhs - , text "tef_unifying =" <+> ppr tef_unifying - , text "tef_fam_app =" <+> ppr tef_fam_app - , text "tef_occurs =" <+> ppr tef_occurs ]) + vcat [ text "tef_task =" <+> ppr tef_task + , text "tef_fam_app =" <+> ppr tef_fam_app ]) instance Outputable (TyEqFamApp a) where ppr TEFA_Fail = text "TEFA_Fail" ppr TEFA_Recurse = text "TEFA_Recurse" ppr (TEFA_Break {}) = text "TEFA_Break" -instance Outputable AreUnifying where - ppr NotUnifying = text "NotUnifying" - ppr (Unifying mi lvl lc) = text "Unifying" <+> - braces (ppr mi <> comma <+> ppr lvl <> comma <+> ppr lc) - instance Outputable LevelCheck where - ppr LC_None = text "LC_None" ppr LC_Check = text "LC_Check" ppr (LC_Promote b) = text "LC_Promote" <> ppWhen b (text "(deep)") +-- | Adjust the 'TyEqFlags' when going undter a type family: +-- +-- 1. Only the outer family application gets the loop-breaker treatment +-- 2. Weaken level checks for tyvar promotion. For example, in @[W] alpha[2] ~ Maybe (F beta[3])@, +-- do not promote @beta[3]@, instead promote @(F beta[3])@. +-- 3. Occurs checks become potentially soluble (after additional type family +-- reductions). famAppArgFlags :: TyEqFlags a -> TyEqFlags a --- Adjust the flags when going undter a type family --- Only the outer family application gets the loop-breaker treatment --- Ditto tyvar promotion. E.g. --- [W] alpha[2] ~ Maybe (F beta[3]) --- Do not promote beta[3]; instead promote (F beta[3]) -famAppArgFlags flags@(TEF { tef_unifying = unifying }) - = flags { tef_fam_app = TEFA_Recurse - , tef_unifying = zap_promotion unifying - , tef_occurs = cteSolubleOccurs } - -- tef_occurs: under a type family, an occurs check is not definitely-insoluble +famAppArgFlags flags@(TEF { tef_task = task }) + = flags { tef_fam_app = TEFA_Recurse -- (1) + , tef_task = fam_app_task task + } where - zap_promotion (Unifying info lvl (LC_Promote deeply)) - | not deeply = Unifying info lvl LC_Check - zap_promotion unifying = unifying + fam_app_task :: TEFTask -> TEFTask + fam_app_task task = case task of + TEFTyFam {} -> + task + { tefTyFam_occursCheck = cteSolubleOccurs -- (3) + } + TEFTyVar { tefTyVar_occursCheck = mb_occ, tefTyVar_levelCheck = mb_lc } -> + task + { tefTyVar_occursCheck = + fmap (\ (tv, _old_occ_prob) -> (tv, cteSolubleOccurs)) mb_occ -- (3) + , tefTyVar_levelCheck = + fmap (\ (lvl, lc) -> (lvl, zap_lc lc)) mb_lc -- (2) + } + zap_lc = \case + LC_Promote deeply + | not deeply + -> LC_Check + lc -> lc type FamAppBreaker a = TcType -> TcM (PuResult a Reduction) -- Given a family-application ty, return a Reduction :: ty ~ cvb @@ -3196,7 +3314,6 @@ checkTyEqRhs flags ty FunTy {ft_af = af, ft_mult = w, ft_arg = a, ft_res = r} | isInvisibleFunArg af -- e.g. Num a => blah - , not (tef_foralls flags) -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) | otherwise -> do { w_res <- checkTyEqRhs flags w @@ -3215,38 +3332,48 @@ checkTyEqRhs flags ty CoercionTy co -> do { co_res <- checkCo flags co ; return (mkReflCoRedn Nominal <$> co_res) } - ForAllTy {} - | tef_foralls flags -> okCheckRefl ty - | otherwise -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) - + ForAllTy {} -> failCheckWith impredicativeProblem -- Not allowed (TyEq:F) ------------------- checkCo :: TyEqFlags a -> Coercion -> TcM (PuResult a Coercion) -- See Note [checkCo] -checkCo (TEF { tef_lhs = TyFamLHS {} }) co - = return (pure co) - -checkCo (TEF { tef_lhs = TyVarLHS lhs_tv - , tef_unifying = unifying - , tef_occurs = occ_prob }) co - -- Check for coercion holes, if unifying - -- See (COERCION-HOLE) in Note [Unification preconditions] - | hasCoercionHoleCo co - = failCheckWith (cteProblem cteCoercionHole) - - -- Occurs check (can promote) - | Unifying _ lhs_tv_lvl (LC_Promote {}) <- unifying - = do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co) - ; if cterHasNoProblem reason - then return (pure co) - else failCheckWith reason } - - -- Occurs check (no promotion) - | lhs_tv `elemVarSet` tyCoVarsOfCo co - = failCheckWith (cteProblem occ_prob) +checkCo (TEF { tef_task = task }) co = + case task of + TEFTyFam {} -> + -- NB: 'TEFTyFam' case means we are not unifying. + return (pure co) + TEFTyVar + { tefTyVar_concreteCheck = mb_conc + , tefTyVar_levelCheck = mb_lc + , tefTyVar_occursCheck = mb_occ + } + -- Coercions cannot appear in concrete types. + -- + -- See Note [Concrete types] in GHC.Tc.Utils.Concrete. + | Just {} <- mb_conc + -> failCheckWith (cteProblem cteConcrete) + + -- Check for coercion holes, if unifying. + -- See (COERCION-HOLE) in Note [Unification preconditions] + | Just {} <- mb_lc -- equivalent to "we are unifying"; see Note [TEFTask] + , hasCoercionHoleCo co + -> failCheckWith (cteProblem cteCoercionHole) + + -- Occurs check (can promote) + | Just (lhs_tv, occ_prob) <- mb_occ + , Just (lhs_tv_lvl, LC_Promote {}) <- mb_lc + -> do { reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfCo co) + ; if cterHasNoProblem reason + then return (pure co) + else failCheckWith reason } + + -- Occurs check (no promotion) + | Just (lhs_tv, occ_prob) <- mb_occ + , nameUnique lhs_tv `elemVarSetByKey` tyCoVarsOfCo co + -> failCheckWith (cteProblem occ_prob) - | otherwise - = return (pure co) + | otherwise + -> return (pure co) {- Note [checkCo] ~~~~~~~~~~~~~~~~~ @@ -3364,7 +3491,7 @@ If we have [W] alpha ~ Maybe (F (G alpha)) checkTyConApp :: TyEqFlags a -> TcType -> TyCon -> [TcType] -> TcM (PuResult a Reduction) -checkTyConApp flags@(TEF { tef_unifying = unifying, tef_foralls = foralls_ok }) +checkTyConApp flags@(TEF { tef_task = task }) tc_app tc tys | isTypeFamilyTyCon tc , let arity = tyConArity tc @@ -3383,11 +3510,10 @@ checkTyConApp flags@(TEF { tef_unifying = unifying, tef_foralls = foralls_ok }) -- See Note [Forgetful synonyms in checkTyConApp] = checkTyEqRhs flags ty' - | not (isTauTyCon tc || foralls_ok) + | not (isTauTyCon tc) = failCheckWith impredicativeProblem - | Unifying info _ _ <- unifying - , isConcreteInfo info + | Just {} <- tefTaskConcrete_maybe task , not (isConcreteTyCon tc) = failCheckWith (cteProblem cteConcrete) @@ -3404,21 +3530,19 @@ checkFamApp :: TyEqFlags a -> TcType -> TyCon -> [TcType] -- Saturated family application -> TcM (PuResult a Reduction) -- See Note [Family applications in canonical constraints] -checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob - , tef_fam_app = fam_app_flag, tef_lhs = lhs }) +checkFamApp flags@(TEF { tef_task = task, tef_fam_app = fam_app_flag }) fam_app tc tys = case fam_app_flag of TEFA_Fail -> failCheckWith (cteProblem cteTypeFamily) -- Occurs check: F ty ~ ...(F ty)... - _ | TyFamLHS lhs_tc lhs_tys <- lhs + _ | TEFTyFam occ_prob lhs_tc lhs_tys <- task , tcEqTyConApps lhs_tc lhs_tys tc tys -> case fam_app_flag of TEFA_Recurse -> failCheckWith (cteProblem occ_prob) TEFA_Break breaker -> breaker fam_app - _ | Unifying lhs_info _ _ <- unifying - , isConcreteInfo lhs_info + _ | Just {} <- tefTaskConcrete_maybe task -> case fam_app_flag of TEFA_Recurse -> failCheckWith (cteProblem cteConcrete) TEFA_Break breaker -> breaker fam_app @@ -3441,22 +3565,55 @@ checkFamApp flags@(TEF { tef_unifying = unifying, tef_occurs = occ_prob arg_flags = famAppArgFlags flags ------------------- + +-- | The result of a single check in 'checkTyVar', such as a concreteness check +-- or a level check. +data TyVarCheckResult + -- | Check succeded; nothing else to do. + = TyVarCheck_Success + -- | Check succeeded, but requires an additional promotion. + -- + -- Invariant: at least one of the fields is not 'Nothing'. + | TyVarCheck_Promote + (Maybe TcLevel) + -- ^ @Just lvl@ <=> 'TyVar' needs to be promoted to @lvl@ + (Maybe ConcreteTvOrigin) + -- ^ @Just conc_orig@ <=> 'TyVar' needs to be make concrete + -- | Check failed with some 'CheckTyEqProblem's. + -- + -- Invariant: the 'CheckTyEqResult' is not 'cteOK'. + | TyVarCheck_Error CheckTyEqResult + +instance Semigroup TyVarCheckResult where + TyVarCheck_Success <> r = r + r <> TyVarCheck_Success = r + TyVarCheck_Error e1 <> TyVarCheck_Error e2 = + TyVarCheck_Error (e1 S.<> e2) + e@(TyVarCheck_Error {}) <> _ = e + _ <> e@(TyVarCheck_Error {}) = e + TyVarCheck_Promote l1 c1 <> TyVarCheck_Promote l2 c2 = + TyVarCheck_Promote + (combineMaybe minTcLevel l1 l2) + (combineMaybe const c1 c2) -- pick one 'ConcreteTvOrigin' arbitrarily + +combineMaybe :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a +combineMaybe _ Nothing r = r +combineMaybe _ r Nothing = r +combineMaybe f (Just a) (Just b) = Just (f a b) +instance Monoid TyVarCheckResult where + mempty = TyVarCheck_Success + checkTyVar :: forall a. TyEqFlags a -> TcTyVar -> TcM (PuResult a Reduction) -checkTyVar (TEF { tef_lhs = lhs, tef_unifying = unifying, tef_occurs = occ_prob }) occ_tv - = case lhs of - TyFamLHS {} -> success -- Nothing to do if the LHS is a type-family - TyVarLHS lhs_tv -> check_tv unifying lhs_tv +checkTyVar flags@(TEF { tef_task = task }) occ_tv + = case task of + TEFTyFam {} -> success -- Nothing to do if the LHS is a type-family + TEFTyVar mb_occ mb_lc mb_conc -> check_tv mb_occ mb_lc mb_conc where lvl_occ = tcTyVarLevel occ_tv success = okCheckRefl (mkTyVarTy occ_tv) --------------------- - check_tv NotUnifying lhs_tv - = simple_occurs_check lhs_tv - -- We need an occurs-check here, but no level check - -- See Note [Promotion and level-checking] wrinkle (W1) - - check_tv (Unifying info lvl prom) lhs_tv + check_tv mb_occ mb_lc mb_conc = do { mb_done <- isFilledMetaTyVar_maybe occ_tv ; case mb_done of Just {} -> success @@ -3466,71 +3623,94 @@ checkTyVar (TEF { tef_lhs = lhs, tef_unifying = unifying, tef_occurs = occ_prob -- a second time; we don't want to re-promote it! -- Remember, the entire process started with a fully zonked type - Nothing -> check_unif info lvl prom lhs_tv } + Nothing -> + do_rhs_checks $ + -- Occurs check + [ simple_occurs_check tv occ_prob | (tv, occ_prob) <- maybeToList mb_occ ] + ++ + -- Level check + [ lvl_check lc | lc <- maybeToList mb_lc ] + ++ + -- Concreteness check + [ conc_check conc | conc <- maybeToList mb_conc ] + } --------------------- - -- We are in the Unifying branch of AreUnifying; and occ_tv is unfilled - check_unif :: MetaInfo -> TcLevel -> LevelCheck - -> TcTyVar -> TcM (PuResult a Reduction) - check_unif lhs_tv_info lhs_tv_lvl prom lhs_tv - | isConcreteInfo lhs_tv_info - , not (isConcreteTyVar occ_tv) - = if can_make_concrete occ_tv - then promote lhs_tv lhs_tv_info lhs_tv_lvl - else failCheckWith (cteProblem cteConcrete) - + simple_occurs_check :: Name -> CheckTyEqProblem -> TyVarCheckResult + simple_occurs_check lhs_tv occ_prob + | lhs_tv == tyVarName occ_tv || check_kind (tyVarKind occ_tv) + = TyVarCheck_Error (cteProblem occ_prob) + | otherwise + = TyVarCheck_Success + where (check_kind, _) = mkOccFolders lhs_tv + conc_check :: ConcreteTvOrigin -> TyVarCheckResult + conc_check conc_orig + | not (isConcreteTyVar occ_tv) + = if isMetaTyVar occ_tv + then TyVarCheck_Promote Nothing (Just conc_orig) + else TyVarCheck_Error (cteProblem cteConcrete) + | otherwise + = TyVarCheck_Success + lvl_check :: (TcLevel, LevelCheck) -> TyVarCheckResult + lvl_check (lhs_tv_lvl, lc) | lvl_occ `strictlyDeeperThan` lhs_tv_lvl - = case prom of - LC_None -> pprPanic "check_unif" (ppr lhs_tv $$ ppr occ_tv) - LC_Check -> failCheckWith (cteProblem cteSkolemEscape) + = case lc of + LC_Check -> TyVarCheck_Error (cteProblem cteSkolemEscape) LC_Promote {} - | isSkolemTyVar occ_tv -> failCheckWith (cteProblem cteSkolemEscape) - | otherwise -> promote lhs_tv lhs_tv_info lhs_tv_lvl - - | otherwise - = simple_occurs_check lhs_tv - - --------------------- - simple_occurs_check lhs_tv - | lhs_tv == occ_tv || check_kind (tyVarKind occ_tv) - = failCheckWith (cteProblem occ_prob) + | isSkolemTyVar occ_tv -> TyVarCheck_Error (cteProblem cteSkolemEscape) + | otherwise -> TyVarCheck_Promote (Just lhs_tv_lvl) Nothing | otherwise - = success - where - (check_kind, _) = mkOccFolders lhs_tv + = TyVarCheck_Success - --------------------- - can_make_concrete occ_tv = case tcTyVarDetails occ_tv of - MetaTv { mtv_info = info } -> case info of - ConcreteTv {} -> True - TauTv {} -> True - _ -> False - _ -> False -- Don't attempt to make other type variables concrete - -- (e.g. SkolemTv, TyVarTv, CycleBreakerTv, RuntimeUnkTv). + -- Combine the results of individual checks. See 'TyVarCheckResult'. + do_rhs_checks :: [TyVarCheckResult] -> TcM (PuResult a Reduction) + do_rhs_checks checks = + case mconcat checks of + TyVarCheck_Success -> success + TyVarCheck_Promote mb_lvl mb_conc -> promote mb_lvl mb_conc + TyVarCheck_Error cte_prob -> failCheckWith cte_prob --------------------- - -- occ_tv is definitely a MetaTyVar - promote lhs_tv lhs_tv_info lhs_tv_lvl + -- occ_tv is definitely a MetaTyVar; we need to promote it/make it concrete + promote :: Maybe TcLevel -> Maybe ConcreteTvOrigin -> TcM (PuResult a Reduction) + promote mb_lhs_tv_lvl mb_conc | MetaTv { mtv_info = info_occ, mtv_tclvl = lvl_occ } <- tcTyVarDetails occ_tv - = do { let new_info | isConcreteInfo lhs_tv_info = lhs_tv_info - | otherwise = info_occ - new_lvl = lhs_tv_lvl `minTcLevel` lvl_occ - -- c[conc,3] ~ p[tau,2]: want to clone p:=p'[conc,2] - -- c[tau,2] ~ p[tau,3]: want to clone p:=p'[tau,2] + = do { let new_info | Just conc <- mb_conc = ConcreteTv conc + | otherwise = info_occ + new_lvl = + case mb_lhs_tv_lvl of + Nothing -> lvl_occ + Just lhs_tv_lvl -> lhs_tv_lvl `minTcLevel` lvl_occ + -- c[conc,3] ~ p[tau,2]: want to clone p:=p'[conc,2] + -- c[tau,2] ~ p[tau,3]: want to clone p:=p'[tau,2] -- Check the kind of occ_tv - ; reason <- checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl (tyCoVarsOfType (tyVarKind occ_tv)) - - ; if cterHasNoProblem reason -- Successfully promoted - then do { new_tv_ty <- promote_meta_tyvar new_info new_lvl occ_tv - ; okCheckRefl new_tv_ty } - else failCheckWith reason } + -- + -- This is important for several reasons: + -- + -- 1. To ensure there is no occurs check or skolem-escape + -- in the kind of occ_tv. + -- 2. If the LHS is a concrete type variable and the RHS is an + -- unfilled meta-tyvar, we need to ensure that the kind of + -- 'occ_tv' is concrete. Test cases: T23051, T23176. + ; let occ_kind = tyVarKind occ_tv + ; kind_result <- checkTyEqRhs flags occ_kind + ; traceTc "checkTyVar: kind check" $ + vcat [ text "occ_tv:" <+> ppr occ_tv <+> dcolon <+> ppr occ_kind + , text "checkTyEqRHS result:" <+> pprPur kind_result + ] + ; for kind_result $ \ kind_redn -> + do { let kind_co = reductionCoercion kind_redn + new_kind = reductionReducedType kind_redn + ; new_tv_ty <- promote_meta_tyvar new_info new_lvl (setTyVarKind occ_tv new_kind) + ; return $ mkGReflLeftRedn Nominal new_tv_ty (mkSymCo kind_co) + } } | otherwise = pprPanic "promote" (ppr occ_tv) ------------------------- checkPromoteFreeVars :: CheckTyEqProblem -- What occurs check problem to report - -> TcTyVar -> TcLevel + -> Name -> TcLevel -> TyCoVarSet -> TcM CheckTyEqResult -- Check this set of TyCoVars for -- (a) occurs check @@ -3540,11 +3720,11 @@ checkPromoteFreeVars occ_prob lhs_tv lhs_tv_lvl vs ; return (mconcat oks) } where do_one :: TyCoVar -> TcM CheckTyEqResult - do_one v | isCoVar v = return cteOK - | lhs_tv == v = return (cteProblem occ_prob) - | no_promotion = return cteOK - | not (isMetaTyVar v) = return (cteProblem cteSkolemEscape) - | otherwise = promote_one v + do_one v | isCoVar v = return cteOK + | tyVarName v == lhs_tv = return (cteProblem occ_prob) + | no_promotion = return cteOK + | not (isMetaTyVar v) = return (cteProblem cteSkolemEscape) + | otherwise = promote_one v where no_promotion = not (tcTyVarLevel v `strictlyDeeperThan` lhs_tv_lvl) @@ -3606,3 +3786,119 @@ checkTopShape info xi _ -> False CycleBreakerTv -> False -- We never unify these _ -> True + +-------------------------------------------------------------------------------- +-- Making a type concrete. + +-- | Try to turn the provided type into a concrete type, by ensuring +-- unfilled metavariables are appropriately marked as concrete. +-- +-- Returns a coercion whose RHS is a zonked type which is "as concrete as possible", +-- and a collection of Wanted equality constraints that are necessary to make +-- the type concrete. +-- +-- For example, for an input @TYPE a[sk]@ we will return a coercion with RHS +-- @TYPE gamma[conc]@ together with the Wanted equality constraint @a ~# gamma at . +-- +-- INVARIANT: the RHS type of the returned coercion is equal to the input type, +-- up to zonking and the returned Wanted equality constraints. +-- +-- INVARIANT: if this function returns an empty list of constraints +-- then the RHS type of the returned coercion is concrete, +-- in the sense of Note [Concrete types]. +makeTypeConcrete :: FastString -> ConcreteTvOrigin + -> TcType -> TcM (TcCoercion, Cts) +makeTypeConcrete occ_fs conc_orig ty = + do { traceTc "makeTypeConcrete {" $ + vcat [ text "ty:" <+> ppr ty ] + + -- To make a type 'ty' concrete, we query what would happen were we + -- to try unifying + -- + -- alpha[conc] ~# ty + -- + -- for a fresh concrete metavariable 'alpha'. + -- + -- We do this by calling 'checkTyEqRhs' with suitable 'TyEqFlags'. + -- NB: we don't actually need to create a fresh concrete metavariable + -- in order to call 'checkTyEqRhs'. + ; let ty_eq_flags = + TEF { tef_task = + TEFTyVar + { tefTyVar_occursCheck = Nothing + -- LHS is a fresh meta-tyvar: no occurs check needed + , tefTyVar_levelCheck = Nothing + , tefTyVar_concreteCheck = Just conc_orig + } + , tef_fam_app = TEFA_Fail + } + + -- NB: 'checkTyEqRhs' expects a fully zonked type as input. + ; ty' <- liftZonkM $ zonkTcType ty + ; pu_res <- checkTyEqRhs @() ty_eq_flags ty' + -- NB: 'checkTyEqRhs' will also check the kind, thus upholding the + -- invariant that the kind of a concrete type must also be a concrete type. + + ; (cts, final_co) <- + case pu_res of + PuOK _ redn -> + do { traceTc "makeTypeConcrete: unifier success" $ + vcat [ text "ty:" <+> ppr ty <+> dcolon <+> ppr (typeKind ty) + , text "redn:" <+> ppr redn + ] + ; return (emptyBag, mkSymCo $ reductionCoercion redn) + -- NB: the unifier returns a 'Reduction' with the concrete + -- type on the left, but we want a coercion with it on the + -- right; so we use 'mkSymCo'. + } + PuFail _prob -> + do { traceTc "makeTypeConcrete: unifier failure" $ + vcat [ text "ty:" <+> ppr ty <+> dcolon <+> ppr (typeKind ty) + , text "problem:" <+> ppr _prob + ] + -- We failed to make 'ty' concrete. In order to continue + -- typechecking, we proceed as follows: + -- + -- - create a new concrete metavariable alpha[conc] + -- - emit the equality @ty ~# alpha[conc]@. + -- + -- This equality will eventually get reported as insoluble + -- to the user. + + -- The kind of a concrete metavariable must itself be concrete, + -- so we need to do a concreteness check on the kind first. + ; let ki = typeKind ty + ; (kind_co, kind_cts) <- + if isConcreteType ki + then return (mkNomReflCo ki, emptyBag) + else makeTypeConcrete occ_fs conc_orig ki + + -- Now create the new concrete metavariable. + ; conc_tv <- newConcreteTyVar conc_orig occ_fs (coercionRKind kind_co) + ; let conc_ty = mkTyVarTy conc_tv + pty = mkEqPredRole Nominal ty' conc_ty + ; hole <- newCoercionHoleO orig pty + ; loc <- getCtLocM orig (Just KindLevel) + ; let ct = mkNonCanonical + $ CtWanted { ctev_pred = pty + , ctev_dest = HoleDest hole + , ctev_loc = loc + , ctev_rewriters = emptyRewriterSet } + ; return (kind_cts S.<> unitBag ct, HoleCo hole) + } + + ; traceTc "makeTypeConcrete }" $ + vcat [ text "ty :" <+> _ppr_ty ty + , text "ty':" <+> _ppr_ty ty' + , text "final_co:" <+> _ppr_co final_co ] + + ; return (final_co, cts) + } + where + + _ppr_ty ty = ppr ty <+> dcolon <+> ppr (typeKind ty) + _ppr_co co = ppr co <+> dcolon <+> parens (_ppr_ty (coercionLKind co)) <+> text "~#" <+> parens (_ppr_ty (coercionRKind co)) + + orig :: CtOrigin + orig = case conc_orig of + ConcreteFRR frr_orig -> FRROrigin frr_orig ===================================== compiler/GHC/Tc/Utils/Unify.hs-boot ===================================== @@ -1,11 +1,15 @@ module GHC.Tc.Utils.Unify where import GHC.Prelude -import GHC.Core.Type ( Mult ) -import GHC.Tc.Utils.TcType ( TcTauType ) -import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Evidence ( TcCoercion ) -import GHC.Tc.Types.Origin ( CtOrigin, TypedThing ) +import GHC.Core.Type ( Mult ) +import GHC.Tc.Utils.TcType ( TcTauType ) +import GHC.Tc.Types ( TcM ) +import GHC.Tc.Types.Constraint ( Cts ) +import GHC.Tc.Types.Evidence ( TcCoercion ) +import GHC.Tc.Types.Origin ( CtOrigin, TypedThing ) +import GHC.Tc.Utils.TcType ( TcType, ConcreteTvOrigin ) + +import GHC.Data.FastString ( FastString ) -- This boot file exists only to tie the knot between @@ -15,3 +19,6 @@ unifyType :: Maybe TypedThing -> TcTauType -> TcTauType -> TcM TcCoerci unifyInvisibleType :: TcTauType -> TcTauType -> TcM TcCoercion tcSubMult :: CtOrigin -> Mult -> Mult -> TcM () + +makeTypeConcrete :: FastString -> ConcreteTvOrigin + -> TcType -> TcM (TcCoercion, Cts) ===================================== docs/users_guide/9.14.1-notes.rst ===================================== @@ -38,6 +38,8 @@ Language That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`. +* Multiline strings are now accepted in foreign imports. (#25157) + Compiler ~~~~~~~~ ===================================== hie.yaml ===================================== @@ -5,4 +5,4 @@ # cradle: {bios: {program: "./hadrian/hie-bios.bat"}} # # The format is documented here - https://github.com/mpickering/hie-bios -cradle: {bios: {program: "./hadrian/hie-bios"}} +cradle: {bios: {program: "./hadrian/hie-bios.bat"}} ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE MultilineStrings #-} +module Main where + +import GHC.Prim +import GHC.JS.Prim +import Foreign.C +import System.IO + +foreign import javascript + """ + ((x) => x) + """ + toJSDouble :: Double -> JSVal + +foreign import javascript + """ + (function (x) { + console.log(x); + }) + """ + multiLog :: JSVal -> IO () + +foreign import javascript + """ + ((x) => + x + "" + ) + """ + jsToString :: JSVal -> JSVal + +foreign import ccall + """ + cos + """ mycos :: CDouble -> CDouble + +main :: IO () +main = do + hSetBuffering stdout NoBuffering + + multiLog $ toJSInt 5 + multiLog $ toJSString "Hello" + putStrLn $ fromJSString $ jsToString $ toJSInt (- 5) + multiLog $ jsToString $ toJSDouble 3.0 + print $ mycos 0 == 1 \ No newline at end of file ===================================== testsuite/tests/javascript/T25633.stdout ===================================== @@ -0,0 +1,5 @@ +5 +Hello +-5 +3 +True \ No newline at end of file ===================================== testsuite/tests/javascript/all.T ===================================== @@ -25,3 +25,5 @@ test('T24495', normal, makefile_test, ['T24495']) test('T23479', normal, makefile_test, ['T23479']) test('T24744', normal, makefile_test, ['T24744']) + +test('T25633', normal, compile_and_run, ['']) ===================================== testsuite/tests/rep-poly/RepPolyInferPatBind.stderr ===================================== @@ -1,4 +1,3 @@ - RepPolyInferPatBind.hs:21:1: error: [GHC-55287] The binder ‘x’ does not have a fixed runtime representation. Its type is: @@ -8,9 +7,8 @@ RepPolyInferPatBind.hs:21:2: error: [GHC-55287] • The pattern binding does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘c0’ - because the former is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T In the pattern: x :: T In a pattern binding: (x :: T) = x + ===================================== testsuite/tests/rep-poly/RepPolyInferPatSyn.stderr ===================================== @@ -1,12 +1,10 @@ - RepPolyInferPatSyn.hs:22:16: error: [GHC-55287] • The pattern synonym argument pattern does not have a fixed runtime representation. Its type is: T :: TYPE R - Cannot unify ‘R’ with the type variable ‘c0’ - because the former is not a concrete ‘RuntimeRep’. • When checking that the pattern signature: T fits the type of its context: T In the pattern: a :: T In the declaration for pattern synonym ‘P’ + ===================================== testsuite/tests/rep-poly/RepPolyTuple3.stderr ===================================== @@ -1,6 +1,6 @@ - RepPolyTuple3.hs:21:9: error: [GHC-18872] • Couldn't match kind ‘FloatRep’ with ‘IntRep’ arising from a representation-polymorphism check • In the expression: (#,#) @RR @RR x In an equation for ‘bar’: bar x = (#,#) @RR @RR x + ===================================== testsuite/tests/rep-poly/T23153.stderr ===================================== @@ -1,4 +1,3 @@ - T23153.hs:8:1: error: [GHC-52083] The argument ‘(h ())’ of ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. @@ -13,3 +12,4 @@ T23153.hs:8:1: error: [GHC-52083] The argument ‘(h ())’ of ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. Suggested fix: Add a type signature. + ===================================== testsuite/tests/rep-poly/T23154.stderr ===================================== @@ -1,3 +1,7 @@ +T23154.hs:7:1: error: [GHC-52083] + The first pattern in the equation for ‘f’ + cannot be assigned a fixed runtime representation, not even by defaulting. + Suggested fix: Add a type signature. T23154.hs:7:1: error: [GHC-52083] The first pattern in the equation for ‘f’ @@ -8,3 +12,4 @@ T23154.hs:7:1: error: [GHC-52083] The first pattern in the equation for ‘f’ cannot be assigned a fixed runtime representation, not even by defaulting. Suggested fix: Add a type signature. + ===================================== testsuite/tests/simd/should_run/T25658.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\a _ -> a) ===================================== testsuite/tests/simd/should_run/T25658.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (0,11) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -25,6 +25,8 @@ test('word16x8_basic_baseline', [], compile_and_run, ['']) test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) +test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation + # Ensure we set the CPU features we have available. # # This is especially important with the LLVM backend, as LLVM can otherwise View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b65a3524e6d874bb4a25718b11d2c6810425f14...14f8a7ec7ffd4368de84b6cc415a9a36ad396260 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b65a3524e6d874bb4a25718b11d2c6810425f14...14f8a7ec7ffd4368de84b6cc415a9a36ad396260 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 01:23:25 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 17 Jan 2025 20:23:25 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# Message-ID: <678b028ded036_24206a36c298286e5@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - f746630e by Simon Peyton Jones at 2025-01-17T20:22:59-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 16 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Parser.y - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Var.hs - docs/users_guide/9.14.1-notes.rst - + testsuite/tests/javascript/T25633.hs - + testsuite/tests/javascript/T25633.stdout - testsuite/tests/javascript/all.T - + testsuite/tests/polykinds/T25661.hs - + testsuite/tests/polykinds/T25661.stderr - testsuite/tests/polykinds/all.T - + testsuite/tests/simd/should_run/T25658.hs - + testsuite/tests/simd/should_run/T25658.stdout - testsuite/tests/simd/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD II64 (OpReg r) (OpReg dst)) + (MOVD FF64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD II64 (OpReg tmp) (OpReg dst)) + (MOVD FF64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -155,11 +155,13 @@ data Type | ForAllTy -- See Note [ForAllTy] {-# UNPACK #-} !ForAllTyBinder - Type -- ^ A Π type. - -- See Note [Why ForAllTy can quantify over a coercion variable] - -- INVARIANT: If the binder is a coercion variable, it must - -- be mentioned in the Type. - -- See Note [Unused coercion variable in ForAllTy] + -- ForAllTyBinder: see GHC.Types.Var + -- Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] + Type + -- INVARIANT: If the binder is a coercion variable, it must + -- be mentioned in the Type. + -- See Note [Unused coercion variable in ForAllTy] + -- See Note [Why ForAllTy can quantify over a coercion variable] | FunTy -- ^ FUN m t1 t2 Very common, so an important special case -- See Note [Function types] ===================================== compiler/GHC/Parser.y ===================================== @@ -2148,6 +2148,9 @@ fspec :: { Located (TokDcolon : STRING var '::' sigtype { sLL $1 $> (epUniTok $3 ,(L (getLoc $1) (getStringLiteral $1), $2, $4)) } + | STRING_MULTI var '::' sigtype { sLL $1 $> (epUniTok $3 + ,(L (getLoc $1) + (getStringMultiLiteral $1), $2, $4)) } | var '::' sigtype { sLL $1 $> (epUniTok $2 ,(noLoc (StringLiteral NoSourceText nilFS Nothing), $1, $3)) } -- if the entity string is missing, it defaults to the empty string; @@ -4247,6 +4250,7 @@ getINCOHERENT_PRAGs (L _ (ITincoherent_prag src)) = src getCTYPEs (L _ (ITctype src)) = src getStringLiteral l = StringLiteral (getSTRINGs l) (getSTRING l) Nothing +getStringMultiLiteral l = StringLiteral (getSTRINGMULTIs l) (getSTRINGMULTI l) Nothing isUnicode :: Located Token -> Bool isUnicode (L _ (ITforall iu)) = iu == UnicodeSyntax ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -120,13 +120,17 @@ tcFunBindMatches ctxt fun_name mult matches invis_pat_tys exp_ty -- Makes sure that if the binding is unrestricted, it counts as -- consuming its rhs Many times. - do { traceTc "tcFunBindMatches 2" (vcat [ pprUserTypeCtxt ctxt, ppr invis_pat_tys - , ppr pat_tys $$ ppr rhs_ty ]) + do { traceTc "tcFunBindMatches 2" $ + vcat [ text "ctxt:" <+> pprUserTypeCtxt ctxt + , text "arity:" <+> ppr arity + , text "invis_pat_tys:" <+> ppr invis_pat_tys + , text "pat_tys:" <+> ppr pat_tys + , text "rhs_ty:" <+> ppr rhs_ty ] ; tcMatches tcBody (invis_pat_tys ++ pat_tys) rhs_ty matches } ; return (wrap_fun, r) } where - herald = ExpectedFunTyMatches (NameThing fun_name) matches + herald = ExpectedFunTyMatches (NameThing fun_name) matches funBindPrecondition :: MatchGroup GhcRn (LHsExpr GhcRn) -> Bool funBindPrecondition (MG { mg_alts = L _ alts }) ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -1490,8 +1490,10 @@ tcSplitForAllTyVarsReqTVBindersN n_req ty = split n_req ty ty [] where split n_req _orig_ty (ForAllTy b@(Bndr _ argf) ty) bs - | isVisibleForAllTyFlag argf, n_req > 0 = split (n_req - 1) ty ty (b:bs) - | otherwise = split n_req ty ty (b:bs) + | isVisibleForAllTyFlag argf, n_req > 0 -- Split off a visible forall + = split (n_req - 1) ty ty (b:bs) + | isInvisibleForAllTyFlag argf -- Split off an invisible forall, + = split n_req ty ty (b:bs) -- even if n_req=0, i.e. the trailing ones split n_req orig_ty ty bs | Just ty' <- coreView ty = split n_req orig_ty ty' bs split n_req orig_ty _ty bs = (n_req, reverse bs, orig_ty) @@ -1975,7 +1977,7 @@ isSigmaTy :: TcType -> Bool -- forall a. blah -- Eq a => blah -- ?x::Int => blah --- But not +-- But NOT -- forall a -> blah isSigmaTy (ForAllTy (Bndr _ af) _) = isInvisibleForAllTyFlag af isSigmaTy (FunTy { ft_af = af }) = isInvisibleFunArg af ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -648,6 +648,7 @@ data VarBndr var argf = Bndr var argf -- A 'ForAllTyBinder' is the binder of a ForAllTy -- It's convenient to define this synonym here rather its natural -- home in "GHC.Core.TyCo.Rep", because it's used in GHC.Core.DataCon.hs-boot +-- See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] -- -- A 'TyVarBinder' is a binder with only TyVar type ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag ===================================== docs/users_guide/9.14.1-notes.rst ===================================== @@ -38,6 +38,8 @@ Language That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`. +* Multiline strings are now accepted in foreign imports. (#25157) + Compiler ~~~~~~~~ ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE MultilineStrings #-} +module Main where + +import GHC.Prim +import GHC.JS.Prim +import Foreign.C +import System.IO + +foreign import javascript + """ + ((x) => x) + """ + toJSDouble :: Double -> JSVal + +foreign import javascript + """ + (function (x) { + console.log(x); + }) + """ + multiLog :: JSVal -> IO () + +foreign import javascript + """ + ((x) => + x + "" + ) + """ + jsToString :: JSVal -> JSVal + +foreign import ccall + """ + cos + """ mycos :: CDouble -> CDouble + +main :: IO () +main = do + hSetBuffering stdout NoBuffering + + multiLog $ toJSInt 5 + multiLog $ toJSString "Hello" + putStrLn $ fromJSString $ jsToString $ toJSInt (- 5) + multiLog $ jsToString $ toJSDouble 3.0 + print $ mycos 0 == 1 \ No newline at end of file ===================================== testsuite/tests/javascript/T25633.stdout ===================================== @@ -0,0 +1,5 @@ +5 +Hello +-5 +3 +True \ No newline at end of file ===================================== testsuite/tests/javascript/all.T ===================================== @@ -25,3 +25,5 @@ test('T24495', normal, makefile_test, ['T24495']) test('T23479', normal, makefile_test, ['T23479']) test('T24744', normal, makefile_test, ['T24744']) + +test('T25633', normal, compile_and_run, ['']) ===================================== testsuite/tests/polykinds/T25661.hs ===================================== @@ -0,0 +1,38 @@ +{-# Language TypeFamilyDependencies #-} +{-# Language RequiredTypeArguments #-} +module T25661 where + +import Data.Kind +import Control.Category (Category(id, (.))) +import Prelude hiding (id, (.)) + +type Cat :: Type -> Type +type Cat k = k -> k -> Type +-- type Op :: (k -> j -> Type) -> (j -> k -> Type) +-- newtype Op cat b a = Op (cat a b) + +-- instance Category cat => Category (Op @k @k cat) where +-- id = Op id +-- Op f . Op g = Op (g . f) + +type NaturalTransformation :: Cat s -> Cat t -> Cat (s -> t) +data NaturalTransformation src tgt f g where + -- NaturalTransformationId :: NaturalTransformation src tgt f f + NaturalTransformation :: (FunctorOf src tgt f, FunctorOf src tgt g) => { getNaturalTransformation :: forall x. f x `tgt` g x } -> NaturalTransformation src tgt f g + +type + FunctorOf :: Cat s -> Cat t -> (s -> t) -> Constraint +class (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f +instance (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f + +type + NewFunctor :: (s -> t) -> Constraint +class (Category (Source f), Category (Target f)) => NewFunctor (f :: s -> t) where + type Source (f :: s -> t) :: Cat s + type Target (f :: s -> t) :: Cat t + newmap :: Source f a a' -> Target f (f a) (f a') + + +newmapVis :: NewFunctor f => forall source -> source ~ Source f + => forall target -> target ~ Target f => source a a' -> target (f a) (f a') +newmapVis source = undefined ===================================== testsuite/tests/polykinds/T25661.stderr ===================================== @@ -0,0 +1,17 @@ +T25661.hs:38:20: error: [GHC-91028] + • Couldn't match expected type ‘forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a')’ + with actual type ‘a0’ + Cannot instantiate unification variable ‘a0’ + with a type involving polytypes: + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + • In the expression: undefined + In an equation for ‘newmapVis’: newmapVis source = undefined + • Relevant bindings include + newmapVis :: forall (source :: Cat s) -> + (source ~ Source f) => + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + (bound at T25661.hs:38:1) + ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -247,3 +247,4 @@ test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) test('T24686', normal, compile_fail, ['']) test('T24686a', normal, compile_fail, ['']) +test('T25661', normal, compile_fail, ['']) ===================================== testsuite/tests/simd/should_run/T25658.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\a _ -> a) ===================================== testsuite/tests/simd/should_run/T25658.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (0,11) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -25,6 +25,8 @@ test('word16x8_basic_baseline', [], compile_and_run, ['']) test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) +test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation + # Ensure we set the CPU features we have available. # # This is especially important with the LLVM backend, as LLVM can otherwise View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a97d26156d7b894cf11c29195d2bfa419d7eea60...f746630e040f2db25191b80eda4a9a76d7cd97e4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a97d26156d7b894cf11c29195d2bfa419d7eea60...f746630e040f2db25191b80eda4a9a76d7cd97e4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 04:53:37 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 17 Jan 2025 23:53:37 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] Fix a buglet in tcSplitForAllTyVarsReqTVBindersN Message-ID: <678b33d17bb4_24206a1a8f3584454a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ddd61473 by Simon Peyton Jones at 2025-01-17T23:53:26-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 7 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Var.hs - + testsuite/tests/polykinds/T25661.hs - + testsuite/tests/polykinds/T25661.stderr - testsuite/tests/polykinds/all.T Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -155,11 +155,13 @@ data Type | ForAllTy -- See Note [ForAllTy] {-# UNPACK #-} !ForAllTyBinder - Type -- ^ A Π type. - -- See Note [Why ForAllTy can quantify over a coercion variable] - -- INVARIANT: If the binder is a coercion variable, it must - -- be mentioned in the Type. - -- See Note [Unused coercion variable in ForAllTy] + -- ForAllTyBinder: see GHC.Types.Var + -- Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] + Type + -- INVARIANT: If the binder is a coercion variable, it must + -- be mentioned in the Type. + -- See Note [Unused coercion variable in ForAllTy] + -- See Note [Why ForAllTy can quantify over a coercion variable] | FunTy -- ^ FUN m t1 t2 Very common, so an important special case -- See Note [Function types] ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -120,13 +120,17 @@ tcFunBindMatches ctxt fun_name mult matches invis_pat_tys exp_ty -- Makes sure that if the binding is unrestricted, it counts as -- consuming its rhs Many times. - do { traceTc "tcFunBindMatches 2" (vcat [ pprUserTypeCtxt ctxt, ppr invis_pat_tys - , ppr pat_tys $$ ppr rhs_ty ]) + do { traceTc "tcFunBindMatches 2" $ + vcat [ text "ctxt:" <+> pprUserTypeCtxt ctxt + , text "arity:" <+> ppr arity + , text "invis_pat_tys:" <+> ppr invis_pat_tys + , text "pat_tys:" <+> ppr pat_tys + , text "rhs_ty:" <+> ppr rhs_ty ] ; tcMatches tcBody (invis_pat_tys ++ pat_tys) rhs_ty matches } ; return (wrap_fun, r) } where - herald = ExpectedFunTyMatches (NameThing fun_name) matches + herald = ExpectedFunTyMatches (NameThing fun_name) matches funBindPrecondition :: MatchGroup GhcRn (LHsExpr GhcRn) -> Bool funBindPrecondition (MG { mg_alts = L _ alts }) ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -1490,8 +1490,10 @@ tcSplitForAllTyVarsReqTVBindersN n_req ty = split n_req ty ty [] where split n_req _orig_ty (ForAllTy b@(Bndr _ argf) ty) bs - | isVisibleForAllTyFlag argf, n_req > 0 = split (n_req - 1) ty ty (b:bs) - | otherwise = split n_req ty ty (b:bs) + | isVisibleForAllTyFlag argf, n_req > 0 -- Split off a visible forall + = split (n_req - 1) ty ty (b:bs) + | isInvisibleForAllTyFlag argf -- Split off an invisible forall, + = split n_req ty ty (b:bs) -- even if n_req=0, i.e. the trailing ones split n_req orig_ty ty bs | Just ty' <- coreView ty = split n_req orig_ty ty' bs split n_req orig_ty _ty bs = (n_req, reverse bs, orig_ty) @@ -1975,7 +1977,7 @@ isSigmaTy :: TcType -> Bool -- forall a. blah -- Eq a => blah -- ?x::Int => blah --- But not +-- But NOT -- forall a -> blah isSigmaTy (ForAllTy (Bndr _ af) _) = isInvisibleForAllTyFlag af isSigmaTy (FunTy { ft_af = af }) = isInvisibleFunArg af ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -648,6 +648,7 @@ data VarBndr var argf = Bndr var argf -- A 'ForAllTyBinder' is the binder of a ForAllTy -- It's convenient to define this synonym here rather its natural -- home in "GHC.Core.TyCo.Rep", because it's used in GHC.Core.DataCon.hs-boot +-- See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] -- -- A 'TyVarBinder' is a binder with only TyVar type ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag ===================================== testsuite/tests/polykinds/T25661.hs ===================================== @@ -0,0 +1,38 @@ +{-# Language TypeFamilyDependencies #-} +{-# Language RequiredTypeArguments #-} +module T25661 where + +import Data.Kind +import Control.Category (Category(id, (.))) +import Prelude hiding (id, (.)) + +type Cat :: Type -> Type +type Cat k = k -> k -> Type +-- type Op :: (k -> j -> Type) -> (j -> k -> Type) +-- newtype Op cat b a = Op (cat a b) + +-- instance Category cat => Category (Op @k @k cat) where +-- id = Op id +-- Op f . Op g = Op (g . f) + +type NaturalTransformation :: Cat s -> Cat t -> Cat (s -> t) +data NaturalTransformation src tgt f g where + -- NaturalTransformationId :: NaturalTransformation src tgt f f + NaturalTransformation :: (FunctorOf src tgt f, FunctorOf src tgt g) => { getNaturalTransformation :: forall x. f x `tgt` g x } -> NaturalTransformation src tgt f g + +type + FunctorOf :: Cat s -> Cat t -> (s -> t) -> Constraint +class (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f +instance (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f + +type + NewFunctor :: (s -> t) -> Constraint +class (Category (Source f), Category (Target f)) => NewFunctor (f :: s -> t) where + type Source (f :: s -> t) :: Cat s + type Target (f :: s -> t) :: Cat t + newmap :: Source f a a' -> Target f (f a) (f a') + + +newmapVis :: NewFunctor f => forall source -> source ~ Source f + => forall target -> target ~ Target f => source a a' -> target (f a) (f a') +newmapVis source = undefined ===================================== testsuite/tests/polykinds/T25661.stderr ===================================== @@ -0,0 +1,17 @@ +T25661.hs:38:20: error: [GHC-91028] + • Couldn't match expected type ‘forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a')’ + with actual type ‘a0’ + Cannot instantiate unification variable ‘a0’ + with a type involving polytypes: + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + • In the expression: undefined + In an equation for ‘newmapVis’: newmapVis source = undefined + • Relevant bindings include + newmapVis :: forall (source :: Cat s) -> + (source ~ Source f) => + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + (bound at T25661.hs:38:1) + ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -247,3 +247,4 @@ test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) test('T24686', normal, compile_fail, ['']) test('T24686a', normal, compile_fail, ['']) +test('T25661', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ddd6147349f55ed6d38c7eea876fdacc69a040a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ddd6147349f55ed6d38c7eea876fdacc69a040a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 07:53:56 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 18 Jan 2025 02:53:56 -0500 Subject: [Git][ghc/ghc][master] Allow multiline strings in JS FFI (#25633) Message-ID: <678b5e1484fcb_355b2510138c667e9@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 5 changed files: - compiler/GHC/Parser.y - docs/users_guide/9.14.1-notes.rst - + testsuite/tests/javascript/T25633.hs - + testsuite/tests/javascript/T25633.stdout - testsuite/tests/javascript/all.T Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -2148,6 +2148,9 @@ fspec :: { Located (TokDcolon : STRING var '::' sigtype { sLL $1 $> (epUniTok $3 ,(L (getLoc $1) (getStringLiteral $1), $2, $4)) } + | STRING_MULTI var '::' sigtype { sLL $1 $> (epUniTok $3 + ,(L (getLoc $1) + (getStringMultiLiteral $1), $2, $4)) } | var '::' sigtype { sLL $1 $> (epUniTok $2 ,(noLoc (StringLiteral NoSourceText nilFS Nothing), $1, $3)) } -- if the entity string is missing, it defaults to the empty string; @@ -4247,6 +4250,7 @@ getINCOHERENT_PRAGs (L _ (ITincoherent_prag src)) = src getCTYPEs (L _ (ITctype src)) = src getStringLiteral l = StringLiteral (getSTRINGs l) (getSTRING l) Nothing +getStringMultiLiteral l = StringLiteral (getSTRINGMULTIs l) (getSTRINGMULTI l) Nothing isUnicode :: Located Token -> Bool isUnicode (L _ (ITforall iu)) = iu == UnicodeSyntax ===================================== docs/users_guide/9.14.1-notes.rst ===================================== @@ -38,6 +38,8 @@ Language That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`. +* Multiline strings are now accepted in foreign imports. (#25157) + Compiler ~~~~~~~~ ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE MultilineStrings #-} +module Main where + +import GHC.Prim +import GHC.JS.Prim +import Foreign.C +import System.IO + +foreign import javascript + """ + ((x) => x) + """ + toJSDouble :: Double -> JSVal + +foreign import javascript + """ + (function (x) { + console.log(x); + }) + """ + multiLog :: JSVal -> IO () + +foreign import javascript + """ + ((x) => + x + "" + ) + """ + jsToString :: JSVal -> JSVal + +foreign import ccall + """ + cos + """ mycos :: CDouble -> CDouble + +main :: IO () +main = do + hSetBuffering stdout NoBuffering + + multiLog $ toJSInt 5 + multiLog $ toJSString "Hello" + putStrLn $ fromJSString $ jsToString $ toJSInt (- 5) + multiLog $ jsToString $ toJSDouble 3.0 + print $ mycos 0 == 1 \ No newline at end of file ===================================== testsuite/tests/javascript/T25633.stdout ===================================== @@ -0,0 +1,5 @@ +5 +Hello +-5 +3 +True \ No newline at end of file ===================================== testsuite/tests/javascript/all.T ===================================== @@ -25,3 +25,5 @@ test('T24495', normal, makefile_test, ['T24495']) test('T23479', normal, makefile_test, ['T23479']) test('T24744', normal, makefile_test, ['T24744']) + +test('T25633', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14f8a7ec7ffd4368de84b6cc415a9a36ad396260 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14f8a7ec7ffd4368de84b6cc415a9a36ad396260 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 07:54:36 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 18 Jan 2025 02:54:36 -0500 Subject: [Git][ghc/ghc][master] Fix a buglet in tcSplitForAllTyVarsReqTVBindersN Message-ID: <678b5e3cea9a8_355b254119b4706cc@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 7 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Var.hs - + testsuite/tests/polykinds/T25661.hs - + testsuite/tests/polykinds/T25661.stderr - testsuite/tests/polykinds/all.T Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -155,11 +155,13 @@ data Type | ForAllTy -- See Note [ForAllTy] {-# UNPACK #-} !ForAllTyBinder - Type -- ^ A Π type. - -- See Note [Why ForAllTy can quantify over a coercion variable] - -- INVARIANT: If the binder is a coercion variable, it must - -- be mentioned in the Type. - -- See Note [Unused coercion variable in ForAllTy] + -- ForAllTyBinder: see GHC.Types.Var + -- Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] + Type + -- INVARIANT: If the binder is a coercion variable, it must + -- be mentioned in the Type. + -- See Note [Unused coercion variable in ForAllTy] + -- See Note [Why ForAllTy can quantify over a coercion variable] | FunTy -- ^ FUN m t1 t2 Very common, so an important special case -- See Note [Function types] ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -120,13 +120,17 @@ tcFunBindMatches ctxt fun_name mult matches invis_pat_tys exp_ty -- Makes sure that if the binding is unrestricted, it counts as -- consuming its rhs Many times. - do { traceTc "tcFunBindMatches 2" (vcat [ pprUserTypeCtxt ctxt, ppr invis_pat_tys - , ppr pat_tys $$ ppr rhs_ty ]) + do { traceTc "tcFunBindMatches 2" $ + vcat [ text "ctxt:" <+> pprUserTypeCtxt ctxt + , text "arity:" <+> ppr arity + , text "invis_pat_tys:" <+> ppr invis_pat_tys + , text "pat_tys:" <+> ppr pat_tys + , text "rhs_ty:" <+> ppr rhs_ty ] ; tcMatches tcBody (invis_pat_tys ++ pat_tys) rhs_ty matches } ; return (wrap_fun, r) } where - herald = ExpectedFunTyMatches (NameThing fun_name) matches + herald = ExpectedFunTyMatches (NameThing fun_name) matches funBindPrecondition :: MatchGroup GhcRn (LHsExpr GhcRn) -> Bool funBindPrecondition (MG { mg_alts = L _ alts }) ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -1490,8 +1490,10 @@ tcSplitForAllTyVarsReqTVBindersN n_req ty = split n_req ty ty [] where split n_req _orig_ty (ForAllTy b@(Bndr _ argf) ty) bs - | isVisibleForAllTyFlag argf, n_req > 0 = split (n_req - 1) ty ty (b:bs) - | otherwise = split n_req ty ty (b:bs) + | isVisibleForAllTyFlag argf, n_req > 0 -- Split off a visible forall + = split (n_req - 1) ty ty (b:bs) + | isInvisibleForAllTyFlag argf -- Split off an invisible forall, + = split n_req ty ty (b:bs) -- even if n_req=0, i.e. the trailing ones split n_req orig_ty ty bs | Just ty' <- coreView ty = split n_req orig_ty ty' bs split n_req orig_ty _ty bs = (n_req, reverse bs, orig_ty) @@ -1975,7 +1977,7 @@ isSigmaTy :: TcType -> Bool -- forall a. blah -- Eq a => blah -- ?x::Int => blah --- But not +-- But NOT -- forall a -> blah isSigmaTy (ForAllTy (Bndr _ af) _) = isInvisibleForAllTyFlag af isSigmaTy (FunTy { ft_af = af }) = isInvisibleFunArg af ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -648,6 +648,7 @@ data VarBndr var argf = Bndr var argf -- A 'ForAllTyBinder' is the binder of a ForAllTy -- It's convenient to define this synonym here rather its natural -- home in "GHC.Core.TyCo.Rep", because it's used in GHC.Core.DataCon.hs-boot +-- See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] -- -- A 'TyVarBinder' is a binder with only TyVar type ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag ===================================== testsuite/tests/polykinds/T25661.hs ===================================== @@ -0,0 +1,38 @@ +{-# Language TypeFamilyDependencies #-} +{-# Language RequiredTypeArguments #-} +module T25661 where + +import Data.Kind +import Control.Category (Category(id, (.))) +import Prelude hiding (id, (.)) + +type Cat :: Type -> Type +type Cat k = k -> k -> Type +-- type Op :: (k -> j -> Type) -> (j -> k -> Type) +-- newtype Op cat b a = Op (cat a b) + +-- instance Category cat => Category (Op @k @k cat) where +-- id = Op id +-- Op f . Op g = Op (g . f) + +type NaturalTransformation :: Cat s -> Cat t -> Cat (s -> t) +data NaturalTransformation src tgt f g where + -- NaturalTransformationId :: NaturalTransformation src tgt f f + NaturalTransformation :: (FunctorOf src tgt f, FunctorOf src tgt g) => { getNaturalTransformation :: forall x. f x `tgt` g x } -> NaturalTransformation src tgt f g + +type + FunctorOf :: Cat s -> Cat t -> (s -> t) -> Constraint +class (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f +instance (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f + +type + NewFunctor :: (s -> t) -> Constraint +class (Category (Source f), Category (Target f)) => NewFunctor (f :: s -> t) where + type Source (f :: s -> t) :: Cat s + type Target (f :: s -> t) :: Cat t + newmap :: Source f a a' -> Target f (f a) (f a') + + +newmapVis :: NewFunctor f => forall source -> source ~ Source f + => forall target -> target ~ Target f => source a a' -> target (f a) (f a') +newmapVis source = undefined ===================================== testsuite/tests/polykinds/T25661.stderr ===================================== @@ -0,0 +1,17 @@ +T25661.hs:38:20: error: [GHC-91028] + • Couldn't match expected type ‘forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a')’ + with actual type ‘a0’ + Cannot instantiate unification variable ‘a0’ + with a type involving polytypes: + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + • In the expression: undefined + In an equation for ‘newmapVis’: newmapVis source = undefined + • Relevant bindings include + newmapVis :: forall (source :: Cat s) -> + (source ~ Source f) => + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + (bound at T25661.hs:38:1) + ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -247,3 +247,4 @@ test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) test('T24686', normal, compile_fail, ['']) test('T24686a', normal, compile_fail, ['']) +test('T25661', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/854c2f753dddeaa31d2988704cedf651f9fb7958 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/854c2f753dddeaa31d2988704cedf651f9fb7958 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 10:06:00 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Sat, 18 Jan 2025 05:06:00 -0500 Subject: [Git][ghc/ghc][wip/structured-ghci-errors] 20 commits: warnings: Find out if a qualified name is in the interactive scope directly Message-ID: <678b7d08a3609_3a7a6fc0a58524e@gitlab.mail> sheaf pushed to branch wip/structured-ghci-errors at Glasgow Haskell Compiler / GHC Commits: f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - 30 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Ppr.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Errors/Ppr.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Iface/Errors/Ppr.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Rename/Unbound.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Infer.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/09ee56b9eb270dde86fa75a1c3d329f42012734c...bf4f5ad31ddeb87baad10de47f84081648f808dc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/09ee56b9eb270dde86fa75a1c3d329f42012734c...bf4f5ad31ddeb87baad10de47f84081648f808dc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 14:02:20 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Sat, 18 Jan 2025 09:02:20 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] 11 commits: Allow multiline strings in JS FFI (#25633) Message-ID: <678bb46c5a933_42110ac04a42931b@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 08342aae by Patrick at 2025-01-18T14:02:07+00:00 update kcConDecl to also consider the result type in newtype GADT instance - - - - - a055bc71 by Patrick at 2025-01-18T14:02:07+00:00 peek at the result kind - - - - - a5e7b190 by Patrick at 2025-01-18T14:02:07+00:00 test if gadt has UserSuppliedResultKind in lhs, we let tc_res_kind to unify with rhs result kind if not to gain more inference - - - - - 8cc81070 by Patrick at 2025-01-18T14:02:07+00:00 format and remove getTyConResultKind - - - - - fd990943 by Patrick at 2025-01-18T14:02:07+00:00 format - - - - - de5db767 by Patrick at 2025-01-18T14:02:07+00:00 add comment - - - - - 6fa933d6 by Patrick at 2025-01-18T14:02:07+00:00 cleanup - - - - - 6db17a97 by Patrick at 2025-01-18T14:02:07+00:00 cleanup - - - - - 6b7b1166 by Patrick at 2025-01-18T14:02:07+00:00 update T25611a - - - - - 15 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Parser.y - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Var.hs - docs/users_guide/9.14.1-notes.rst - testsuite/tests/indexed-types/should_compile/T25611a.hs - + testsuite/tests/javascript/T25633.hs - + testsuite/tests/javascript/T25633.stdout - testsuite/tests/javascript/all.T - + testsuite/tests/polykinds/T25661.hs - + testsuite/tests/polykinds/T25661.stderr - testsuite/tests/polykinds/all.T Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -155,11 +155,13 @@ data Type | ForAllTy -- See Note [ForAllTy] {-# UNPACK #-} !ForAllTyBinder - Type -- ^ A Π type. - -- See Note [Why ForAllTy can quantify over a coercion variable] - -- INVARIANT: If the binder is a coercion variable, it must - -- be mentioned in the Type. - -- See Note [Unused coercion variable in ForAllTy] + -- ForAllTyBinder: see GHC.Types.Var + -- Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] + Type + -- INVARIANT: If the binder is a coercion variable, it must + -- be mentioned in the Type. + -- See Note [Unused coercion variable in ForAllTy] + -- See Note [Why ForAllTy can quantify over a coercion variable] | FunTy -- ^ FUN m t1 t2 Very common, so an important special case -- See Note [Function types] ===================================== compiler/GHC/Parser.y ===================================== @@ -2148,6 +2148,9 @@ fspec :: { Located (TokDcolon : STRING var '::' sigtype { sLL $1 $> (epUniTok $3 ,(L (getLoc $1) (getStringLiteral $1), $2, $4)) } + | STRING_MULTI var '::' sigtype { sLL $1 $> (epUniTok $3 + ,(L (getLoc $1) + (getStringMultiLiteral $1), $2, $4)) } | var '::' sigtype { sLL $1 $> (epUniTok $2 ,(noLoc (StringLiteral NoSourceText nilFS Nothing), $1, $3)) } -- if the entity string is missing, it defaults to the empty string; @@ -4247,6 +4250,7 @@ getINCOHERENT_PRAGs (L _ (ITincoherent_prag src)) = src getCTYPEs (L _ (ITctype src)) = src getStringLiteral l = StringLiteral (getSTRINGs l) (getSTRING l) Nothing +getStringMultiLiteral l = StringLiteral (getSTRINGMULTIs l) (getSTRINGMULTI l) Nothing isUnicode :: Located Token -> Bool isUnicode (L _ (ITforall iu)) = iu == UnicodeSyntax ===================================== compiler/GHC/Tc/Gen/Match.hs ===================================== @@ -120,13 +120,17 @@ tcFunBindMatches ctxt fun_name mult matches invis_pat_tys exp_ty -- Makes sure that if the binding is unrestricted, it counts as -- consuming its rhs Many times. - do { traceTc "tcFunBindMatches 2" (vcat [ pprUserTypeCtxt ctxt, ppr invis_pat_tys - , ppr pat_tys $$ ppr rhs_ty ]) + do { traceTc "tcFunBindMatches 2" $ + vcat [ text "ctxt:" <+> pprUserTypeCtxt ctxt + , text "arity:" <+> ppr arity + , text "invis_pat_tys:" <+> ppr invis_pat_tys + , text "pat_tys:" <+> ppr pat_tys + , text "rhs_ty:" <+> ppr rhs_ty ] ; tcMatches tcBody (invis_pat_tys ++ pat_tys) rhs_ty matches } ; return (wrap_fun, r) } where - herald = ExpectedFunTyMatches (NameThing fun_name) matches + herald = ExpectedFunTyMatches (NameThing fun_name) matches funBindPrecondition :: MatchGroup GhcRn (LHsExpr GhcRn) -> Bool funBindPrecondition (MG { mg_alts = L _ alts }) ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -14,8 +14,8 @@ -- | Typecheck type and class declarations module GHC.Tc.TyCl ( + LHSUserSuppliedResultKind(..), tcTyAndClassDecls, - -- Functions used by GHC.Tc.TyCl.Instance to check -- data/type family instance declarations kcConDecls, tcConDecls, DataDeclInfo(..), @@ -1765,7 +1765,7 @@ kcTyClDecl :: TyClDecl GhcRn -> MonoTcTyCon -> TcM () -- kind inference (see GHC.Tc.TyCl Note [TcTyCon, MonoTcTyCon, and PolyTcTyCon]) kcTyClDecl (DataDecl { tcdLName = (L _ _name) - , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons } }) + , tcdDataDefn = HsDataDefn { dd_ctxt = ctxt, dd_cons = cons, dd_kindSig = kindSig } }) tycon = tcExtendNameTyVarEnv (tcTyConScopedTyVars tycon) $ -- NB: binding these tyvars isn't necessary for GADTs, but it does no @@ -1774,7 +1774,9 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name) -- (conceivably) shadowed. do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt - ; kcConDecls (tyConResKind tycon) cons + ; kcConDecls (tyConResKind tycon) (if (isJust kindSig) + then LHSUserSuppliedResultKind + else NoLHSUserSuppliedResultKind) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1834,12 +1836,18 @@ kcConGADTArgs exp_kind con_args = case con_args of RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds +-- Specifically for GADT style declarations +-- do we have lhs user supplied kind signature? +-- as in `data xxx :: UserSuppliedKind where ...` +data LHSUserSuppliedResultKind = LHSUserSuppliedResultKind | NoLHSUserSuppliedResultKind deriving Eq + kcConDecls :: TcKind -- Result kind of tycon -- Used only in H98 case + -> LHSUserSuppliedResultKind -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] -kcConDecls tc_res_kind cons - = traverse_ (wrapLocMA_ (kcConDecl new_or_data tc_res_kind)) cons +kcConDecls tc_res_kind usrk cons + = traverse_ (wrapLocMA_ (kcConDecl new_or_data usrk tc_res_kind)) cons where new_or_data = dataDefnConsNewOrData cons @@ -1848,8 +1856,8 @@ kcConDecls tc_res_kind cons -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData -> TcKind -> ConDecl GhcRn -> TcM () -kcConDecl new_or_data tc_res_kind +kcConDecl :: NewOrData -> LHSUserSuppliedResultKind -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl new_or_data _usrk tc_res_kind (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs , con_mb_cxt = ex_ctxt, con_args = args }) = addErrCtxt (DataConDefCtxt (NE.singleton name)) $ @@ -1865,7 +1873,7 @@ kcConDecl new_or_data tc_res_kind -- because that's done in tcConDecl } -kcConDecl new_or_data _tc_res_kind +kcConDecl new_or_data usrk tc_res_kind -- NB: _tc_res_kind is unused. See (KCD3) in -- Note [kcConDecls: kind-checking data type decls] (ConDeclGADT { con_names = names, con_bndrs = L _ outer_bndrs @@ -1877,10 +1885,11 @@ kcConDecl new_or_data _tc_res_kind bindOuterSigTKBndrs_Tv outer_bndrs $ -- Why "_Tv"? See Note [Using TyVarTvs for kind-checking GADTs] do { _ <- tcHsContext cxt - ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty) - ; con_res_kind <- newOpenTypeKind - ; _ <- tcCheckLHsTypeInContext res_ty (TheKind con_res_kind) - + ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty $$ ppr tc_res_kind) + ; con_res_kind <- if NewType == new_or_data && NoLHSUserSuppliedResultKind == usrk + then return tc_res_kind + else newOpenTypeKind + ; _ <- tcCheckLHsTypeInContext res_ty $ (TheKind con_res_kind) ; let arg_exp_kind = getArgExpKind new_or_data con_res_kind -- getArgExpKind: for newtypes, check that the argument kind -- is the same the kind of `res_ty`, the data con's return type ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -946,7 +946,11 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Add constraints from the data constructors -- Fix #25611 -- See DESIGN CHOICE in Note [Kind inference for data family instances] - ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind hs_cons + ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind (if (isJust m_ksig) + then LHSUserSuppliedResultKind + else NoLHSUserSuppliedResultKind) + hs_cons + -- Check that the result kind of the TyCon applied to its args -- is compatible with the explicit signature (or Type, if there ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -1490,8 +1490,10 @@ tcSplitForAllTyVarsReqTVBindersN n_req ty = split n_req ty ty [] where split n_req _orig_ty (ForAllTy b@(Bndr _ argf) ty) bs - | isVisibleForAllTyFlag argf, n_req > 0 = split (n_req - 1) ty ty (b:bs) - | otherwise = split n_req ty ty (b:bs) + | isVisibleForAllTyFlag argf, n_req > 0 -- Split off a visible forall + = split (n_req - 1) ty ty (b:bs) + | isInvisibleForAllTyFlag argf -- Split off an invisible forall, + = split n_req ty ty (b:bs) -- even if n_req=0, i.e. the trailing ones split n_req orig_ty ty bs | Just ty' <- coreView ty = split n_req orig_ty ty' bs split n_req orig_ty _ty bs = (n_req, reverse bs, orig_ty) @@ -1975,7 +1977,7 @@ isSigmaTy :: TcType -> Bool -- forall a. blah -- Eq a => blah -- ?x::Int => blah --- But not +-- But NOT -- forall a -> blah isSigmaTy (ForAllTy (Bndr _ af) _) = isInvisibleForAllTyFlag af isSigmaTy (FunTy { ft_af = af }) = isInvisibleFunArg af ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -648,6 +648,7 @@ data VarBndr var argf = Bndr var argf -- A 'ForAllTyBinder' is the binder of a ForAllTy -- It's convenient to define this synonym here rather its natural -- home in "GHC.Core.TyCo.Rep", because it's used in GHC.Core.DataCon.hs-boot +-- See Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] -- -- A 'TyVarBinder' is a binder with only TyVar type ForAllTyBinder = VarBndr TyCoVar ForAllTyFlag ===================================== docs/users_guide/9.14.1-notes.rst ===================================== @@ -38,6 +38,8 @@ Language That will break the combination of :extension:`OverloadedRecordUpdate` with :extension:`RebindableSyntax`. +* Multiline strings are now accepted in foreign imports. (#25157) + Compiler ~~~~~~~~ ===================================== testsuite/tests/indexed-types/should_compile/T25611a.hs ===================================== @@ -12,6 +12,6 @@ data family Fix0 :: (k -> Type) -> k newtype instance Fix0 f = In0 { out0 :: f (Fix0 f) } -- This is the GADT newtype instance case --- currently not enabled since !9116 (closed) impose `A newtype must not be a GADT` --- data family Fix2 :: (k -> Type) -> k --- newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f +-- enabled since !13809 +data family Fix2 :: (k -> Type) -> k +newtype instance Fix2 f where In2 :: f (Fix2 f) -> Fix2 f ===================================== testsuite/tests/javascript/T25633.hs ===================================== @@ -0,0 +1,44 @@ +{-# LANGUAGE MultilineStrings #-} +module Main where + +import GHC.Prim +import GHC.JS.Prim +import Foreign.C +import System.IO + +foreign import javascript + """ + ((x) => x) + """ + toJSDouble :: Double -> JSVal + +foreign import javascript + """ + (function (x) { + console.log(x); + }) + """ + multiLog :: JSVal -> IO () + +foreign import javascript + """ + ((x) => + x + "" + ) + """ + jsToString :: JSVal -> JSVal + +foreign import ccall + """ + cos + """ mycos :: CDouble -> CDouble + +main :: IO () +main = do + hSetBuffering stdout NoBuffering + + multiLog $ toJSInt 5 + multiLog $ toJSString "Hello" + putStrLn $ fromJSString $ jsToString $ toJSInt (- 5) + multiLog $ jsToString $ toJSDouble 3.0 + print $ mycos 0 == 1 \ No newline at end of file ===================================== testsuite/tests/javascript/T25633.stdout ===================================== @@ -0,0 +1,5 @@ +5 +Hello +-5 +3 +True \ No newline at end of file ===================================== testsuite/tests/javascript/all.T ===================================== @@ -25,3 +25,5 @@ test('T24495', normal, makefile_test, ['T24495']) test('T23479', normal, makefile_test, ['T23479']) test('T24744', normal, makefile_test, ['T24744']) + +test('T25633', normal, compile_and_run, ['']) ===================================== testsuite/tests/polykinds/T25661.hs ===================================== @@ -0,0 +1,38 @@ +{-# Language TypeFamilyDependencies #-} +{-# Language RequiredTypeArguments #-} +module T25661 where + +import Data.Kind +import Control.Category (Category(id, (.))) +import Prelude hiding (id, (.)) + +type Cat :: Type -> Type +type Cat k = k -> k -> Type +-- type Op :: (k -> j -> Type) -> (j -> k -> Type) +-- newtype Op cat b a = Op (cat a b) + +-- instance Category cat => Category (Op @k @k cat) where +-- id = Op id +-- Op f . Op g = Op (g . f) + +type NaturalTransformation :: Cat s -> Cat t -> Cat (s -> t) +data NaturalTransformation src tgt f g where + -- NaturalTransformationId :: NaturalTransformation src tgt f f + NaturalTransformation :: (FunctorOf src tgt f, FunctorOf src tgt g) => { getNaturalTransformation :: forall x. f x `tgt` g x } -> NaturalTransformation src tgt f g + +type + FunctorOf :: Cat s -> Cat t -> (s -> t) -> Constraint +class (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f +instance (NewFunctor f, Source f ~ src, Target f ~ tgt) => FunctorOf src tgt f + +type + NewFunctor :: (s -> t) -> Constraint +class (Category (Source f), Category (Target f)) => NewFunctor (f :: s -> t) where + type Source (f :: s -> t) :: Cat s + type Target (f :: s -> t) :: Cat t + newmap :: Source f a a' -> Target f (f a) (f a') + + +newmapVis :: NewFunctor f => forall source -> source ~ Source f + => forall target -> target ~ Target f => source a a' -> target (f a) (f a') +newmapVis source = undefined ===================================== testsuite/tests/polykinds/T25661.stderr ===================================== @@ -0,0 +1,17 @@ +T25661.hs:38:20: error: [GHC-91028] + • Couldn't match expected type ‘forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a')’ + with actual type ‘a0’ + Cannot instantiate unification variable ‘a0’ + with a type involving polytypes: + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + • In the expression: undefined + In an equation for ‘newmapVis’: newmapVis source = undefined + • Relevant bindings include + newmapVis :: forall (source :: Cat s) -> + (source ~ Source f) => + forall (target :: Cat t) -> + (target ~ Target f) => source a a' -> target (f a) (f a') + (bound at T25661.hs:38:1) + ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -247,3 +247,4 @@ test('T24083', normal, compile_fail, ['']) test('T24083a', normal, compile, ['']) test('T24686', normal, compile_fail, ['']) test('T24686a', normal, compile_fail, ['']) +test('T25661', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f82cd8a9b8fcb1fec11b10aaff4933dae3691e9d...6b7b1166491f48a5c8cdb12dc7e043189a07da0a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f82cd8a9b8fcb1fec11b10aaff4933dae3691e9d...6b7b1166491f48a5c8cdb12dc7e043189a07da0a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 14:04:22 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sat, 18 Jan 2025 09:04:22 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/T25653-9.12 Message-ID: <678bb4e69b6eb_42110ac04a434681@gitlab.mail> Ben Gamari deleted branch wip/T25653-9.12 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 14:04:39 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Sat, 18 Jan 2025 09:04:39 -0500 Subject: [Git][ghc/ghc][ghc-9.12] 4 commits: Revert "Division by constants optimization" Message-ID: <678bb4f6e83cd_421108b6e4c34832@gitlab.mail> Ben Gamari pushed to branch ghc-9.12 at Glasgow Haskell Compiler / GHC Commits: eb2859af by Ben Gamari at 2025-01-16T17:20:25-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - e7097cf5 by Ben Gamari at 2025-01-16T17:20:25-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - e6850133 by Ben Gamari at 2025-01-16T17:20:25-05:00 testsuite: Test shift correctness in mul2 test - - - - - 2a48b7b5 by Ben Gamari at 2025-01-16T17:20:25-05:00 testsuite: Add regression test for #25653 - - - - - 10 changed files: - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/StgToCmm/Prim.hs - + testsuite/tests/numeric/should_run/T25653.hs - + testsuite/tests/numeric/should_run/T25653.stdout - testsuite/tests/numeric/should_run/all.T Changes: ===================================== compiler/GHC/Cmm/Config.hs ===================================== @@ -24,8 +24,6 @@ data CmmConfig = CmmConfig , cmmExternalDynamicRefs :: !Bool -- ^ Generate code to link against dynamic libraries , cmmDoCmmSwitchPlans :: !Bool -- ^ Should the Cmm pass replace Stg switch statements , cmmSplitProcPoints :: !Bool -- ^ Should Cmm split proc points or not - , cmmAllowMul2 :: !Bool -- ^ Does this platform support mul2 - , cmmOptConstDivision :: !Bool -- ^ Should we optimize constant divisors } -- | retrieve the target Cmm platform ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -7,7 +7,6 @@ module GHC.Cmm.MachOp , pprMachOp, isCommutableMachOp, isAssociativeMachOp , isComparisonMachOp, maybeIntComparison, machOpResultType , machOpArgReps, maybeInvertComparison, isFloatComparison - , isCommutableCallishMachOp -- MachOp builders , mo_wordAdd, mo_wordSub, mo_wordEq, mo_wordNe,mo_wordMul, mo_wordSQuot @@ -846,17 +845,3 @@ machOpMemcpyishAlign op = case op of MO_Memmove align -> Just align MO_Memcmp align -> Just align _ -> Nothing - -isCommutableCallishMachOp :: CallishMachOp -> Bool -isCommutableCallishMachOp op = - case op of - MO_x64_Add -> True - MO_x64_Mul -> True - MO_x64_Eq -> True - MO_x64_Ne -> True - MO_x64_And -> True - MO_x64_Or -> True - MO_x64_Xor -> True - MO_S_Mul2 _ -> True - MO_U_Mul2 _ -> True - _ -> False ===================================== compiler/GHC/Cmm/Opt.hs ===================================== @@ -5,51 +5,27 @@ -- (c) The University of Glasgow 2006 -- ----------------------------------------------------------------------------- -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE PatternSynonyms #-} module GHC.Cmm.Opt ( constantFoldNode, constantFoldExpr, cmmMachOpFold, - cmmMachOpFoldM, - Opt, runOpt + cmmMachOpFoldM ) where import GHC.Prelude -import GHC.Cmm.Dataflow.Block import GHC.Cmm.Utils import GHC.Cmm -import GHC.Cmm.Config -import GHC.Types.Unique.DSM - import GHC.Utils.Misc + import GHC.Utils.Panic import GHC.Platform import Data.Maybe -import Data.Word -import GHC.Exts (oneShot) -import Control.Monad - -constantFoldNode :: CmmNode e x -> Opt (CmmNode e x) -constantFoldNode (CmmUnsafeForeignCall (PrimTarget op) res args) - = traverse constantFoldExprOpt args >>= cmmCallishMachOpFold op res -constantFoldNode node - = mapExpOpt constantFoldExprOpt node - -constantFoldExprOpt :: CmmExpr -> Opt CmmExpr -constantFoldExprOpt e = wrapRecExpOpt f e - where - f (CmmMachOp op args) - = do - cfg <- getConfig - case cmmMachOpFold (cmmPlatform cfg) op args of - CmmMachOp op' args' -> fromMaybe (CmmMachOp op' args') <$> cmmMachOpFoldOptM cfg op' args' - e -> pure e - f (CmmRegOff r 0) = pure (CmmReg r) - f e = pure e + + +constantFoldNode :: Platform -> CmmNode e x -> CmmNode e x +constantFoldNode platform = mapExp (constantFoldExpr platform) constantFoldExpr :: Platform -> CmmExpr -> CmmExpr constantFoldExpr platform = wrapRecExp f @@ -320,7 +296,7 @@ cmmMachOpFoldM platform cmp [CmmMachOp conv [x], CmmLit (CmmInt i _)] maybe_comparison (MO_S_Le _) rep False = Just (MO_U_Le rep) maybe_comparison _ _ _ = Nothing --- We can often do something with constants of 0, 1 and (-1) ... +-- We can often do something with constants of 0 and 1 ... -- See Note [Comparison operators] cmmMachOpFoldM platform mop [x, y@(CmmLit (CmmInt 0 _))] @@ -391,8 +367,6 @@ cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt n _))] MO_Mul rep | Just p <- exactLog2 n -> Just $! (cmmMachOpFold platform (MO_Shl rep) [x, CmmLit (CmmInt p $ wordWidth platform)]) - -- The optimization for division by power of 2 is technically duplicated, but since at least one other part of ghc uses - -- the pure `constantFoldExpr` this remains MO_U_Quot rep | Just p <- exactLog2 n -> Just $! (cmmMachOpFold platform (MO_U_Shr rep) [x, CmmLit (CmmInt p $ wordWidth platform)]) @@ -401,19 +375,46 @@ cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt n _))] Just $! (cmmMachOpFold platform (MO_And rep) [x, CmmLit (CmmInt (n - 1) rep)]) MO_S_Quot rep | Just p <- exactLog2 n, - CmmReg _ <- x -> + CmmReg _ <- x -> -- We duplicate x in signedQuotRemHelper, hence require + -- it is a reg. FIXME: remove this restriction. Just $! (cmmMachOpFold platform (MO_S_Shr rep) - [signedQuotRemHelper platform n x rep p, CmmLit (CmmInt p $ wordWidth platform)]) + [signedQuotRemHelper rep p, CmmLit (CmmInt p $ wordWidth platform)]) MO_S_Rem rep | Just p <- exactLog2 n, - CmmReg _ <- x -> + CmmReg _ <- x -> -- We duplicate x in signedQuotRemHelper, hence require + -- it is a reg. FIXME: remove this restriction. -- We replace (x `rem` 2^p) by (x - (x `quot` 2^p) * 2^p). -- Moreover, we fuse MO_S_Shr (last operation of MO_S_Quot) -- and MO_S_Shl (multiplication by 2^p) into a single MO_And operation. Just $! (cmmMachOpFold platform (MO_Sub rep) [x, cmmMachOpFold platform (MO_And rep) - [signedQuotRemHelper platform n x rep p, CmmLit (CmmInt (- n) rep)]]) + [signedQuotRemHelper rep p, CmmLit (CmmInt (- n) rep)]]) _ -> Nothing + where + -- In contrast with unsigned integers, for signed ones + -- shift right is not the same as quot, because it rounds + -- to minus infinity, whereas quot rounds toward zero. + -- To fix this up, we add one less than the divisor to the + -- dividend if it is a negative number. + -- + -- to avoid a test/jump, we use the following sequence: + -- x1 = x >> word_size-1 (all 1s if -ve, all 0s if +ve) + -- x2 = y & (divisor-1) + -- result = x + x2 + -- this could be done a bit more simply using conditional moves, + -- but we're processor independent here. + -- + -- we optimise the divide by 2 case slightly, generating + -- x1 = x >> word_size-1 (unsigned) + -- return = x + x1 + signedQuotRemHelper :: Width -> Integer -> CmmExpr + signedQuotRemHelper rep p = CmmMachOp (MO_Add rep) [x, x2] + where + bits = fromIntegral (widthInBits rep) - 1 + shr = if p == 1 then MO_U_Shr rep else MO_S_Shr rep + x1 = CmmMachOp shr [x, CmmLit (CmmInt bits $ wordWidth platform)] + x2 = if p == 1 then x1 else + CmmMachOp (MO_And rep) [x1, CmmLit (CmmInt (n-1) rep)] -- ToDo (#7116): optimise floating-point multiplication, e.g. x*2.0 -> x+x -- Unfortunately this needs a unique supply because x might not be a @@ -447,533 +448,3 @@ That's what the constant-folding operations on comparison operators do above. isPicReg :: CmmExpr -> Bool isPicReg (CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _))) = True isPicReg _ = False - -canOptimizeDivision :: CmmConfig -> Width -> Bool -canOptimizeDivision cfg rep = cmmOptConstDivision cfg && - -- we can either widen the arguments to simulate mul2 or use mul2 directly for the platform word size - (rep < wordWidth platform || (rep == wordWidth platform && cmmAllowMul2 cfg)) - where platform = cmmPlatform cfg - --- ----------------------------------------------------------------------------- --- Folding callish machops - -cmmCallishMachOpFold :: CallishMachOp -> [CmmFormal] -> [CmmActual] -> Opt (CmmNode O O) -cmmCallishMachOpFold op res args = - fromMaybe (CmmUnsafeForeignCall (PrimTarget op) res args) <$> (getConfig >>= \cfg -> cmmCallishMachOpFoldM cfg op res args) - -cmmCallishMachOpFoldM :: CmmConfig -> CallishMachOp -> [CmmFormal] -> [CmmActual] -> Opt (Maybe (CmmNode O O)) - --- If possible move the literals to the right, the following cases assume that to be the case -cmmCallishMachOpFoldM cfg op res [x@(CmmLit _),y] - | isCommutableCallishMachOp op && not (isLit y) = cmmCallishMachOpFoldM cfg op res [y,x] - --- Both arguments are literals, replace with the result -cmmCallishMachOpFoldM _ op res [CmmLit (CmmInt x _), CmmLit (CmmInt y _)] - = case op of - MO_S_Mul2 rep - | [rHiNeeded,rHi,rLo] <- res -> do - let resSz = widthInBits rep - resVal = (narrowS rep x) * (narrowS rep y) - high = resVal `shiftR` resSz - low = narrowS rep resVal - isHiNeeded = high /= low `shiftR` resSz - isHiNeededVal = if isHiNeeded then 1 else 0 - prependNode $! CmmAssign (CmmLocal rHiNeeded) (CmmLit $ CmmInt isHiNeededVal rep) - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt high rep) - pure . Just $! CmmAssign (CmmLocal rLo) (CmmLit $ CmmInt low rep) - MO_U_Mul2 rep - | [rHi,rLo] <- res -> do - let resSz = widthInBits rep - resVal = (narrowU rep x) * (narrowU rep y) - high = resVal `shiftR` resSz - low = narrowU rep resVal - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt high rep) - pure . Just $! CmmAssign (CmmLocal rLo) (CmmLit $ CmmInt low rep) - MO_S_QuotRem rep - | [rQuot, rRem] <- res, - y /= 0 -> do - let (q,r) = quotRem (narrowS rep x) (narrowS rep y) - prependNode $! CmmAssign (CmmLocal rQuot) (CmmLit $ CmmInt q rep) - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt r rep) - MO_U_QuotRem rep - | [rQuot, rRem] <- res, - y /= 0 -> do - let (q,r) = quotRem (narrowU rep x) (narrowU rep y) - prependNode $! CmmAssign (CmmLocal rQuot) (CmmLit $ CmmInt q rep) - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt r rep) - _ -> pure Nothing - --- 0, 1 or -1 as one of the constants - -cmmCallishMachOpFoldM _ op res [_, CmmLit (CmmInt 0 _)] - = case op of - -- x * 0 == 0 - MO_S_Mul2 rep - | [rHiNeeded, rHi, rLo] <- res -> do - prependNode $! CmmAssign (CmmLocal rHiNeeded) (CmmLit $ CmmInt 0 rep) - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rLo) (CmmLit $ CmmInt 0 rep) - -- x * 0 == 0 - MO_U_Mul2 rep - | [rHi, rLo] <- res -> do - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rLo) (CmmLit $ CmmInt 0 rep) - _ -> pure Nothing - -cmmCallishMachOpFoldM _ op res [CmmLit (CmmInt 0 _), _] - = case op of - -- 0 quotRem d == (0,0) - MO_S_QuotRem rep - | [rQuot, rRem] <- res -> do - prependNode $! CmmAssign (CmmLocal rQuot) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt 0 rep) - -- 0 quotRem d == (0,0) - MO_U_QuotRem rep - | [rQuot,rRem] <- res -> do - prependNode $! CmmAssign (CmmLocal rQuot) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt 0 rep) - _ -> pure Nothing - -cmmCallishMachOpFoldM cfg op res [x, CmmLit (CmmInt 1 _)] - = case op of - -- x * 1 == x -- Note: The high word needs to be a sign extension of the low word, so we use a sign extending shift - MO_S_Mul2 rep - | [rHiNeeded, rHi, rLo] <- res -> do - let platform = cmmPlatform cfg - wordRep = wordWidth platform - repInBits = toInteger $ widthInBits rep - prependNode $! CmmAssign (CmmLocal rHiNeeded) (CmmLit $ CmmInt 0 rep) - prependNode $! CmmAssign (CmmLocal rHi) (cmmMachOpFold platform (MO_S_Shr rep) [x, CmmLit $ CmmInt (repInBits - 1) wordRep]) - pure . Just $! CmmAssign (CmmLocal rLo) x - -- x * 1 == x - MO_U_Mul2 rep - | [rHi, rLo] <- res -> do - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rLo) x - -- x quotRem 1 == (x, 0) - MO_S_QuotRem rep - | [rQuot, rRem] <- res -> do - prependNode $! CmmAssign (CmmLocal rQuot) x - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt 0 rep) - -- x quotRem 1 == (x, 0) - MO_U_QuotRem rep - | [rQuot, rRem] <- res -> do - prependNode $! CmmAssign (CmmLocal rQuot) x - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt 0 rep) - _ -> pure Nothing - --- handle quotRem with a constant divisor - -cmmCallishMachOpFoldM cfg op res [n, CmmLit (CmmInt d' _)] - = case op of - MO_S_QuotRem rep - | Just p <- exactLog2 d, - [rQuot,rRem] <- res -> do - n' <- intoRegister n (cmmBits rep) - -- first prepend the optimized division by a power 2 - prependNode $! CmmAssign (CmmLocal rQuot) - (cmmMachOpFold platform (MO_S_Shr rep) - [signedQuotRemHelper platform d n' rep p, CmmLit (CmmInt p $ wordWidth platform)]) - -- then output an optimized remainder by a power of 2 - pure . Just $! CmmAssign (CmmLocal rRem) - (cmmMachOpFold platform (MO_Sub rep) - [n', cmmMachOpFold platform (MO_And rep) - [signedQuotRemHelper platform d n' rep p, CmmLit (CmmInt (- d) rep)]]) - | canOptimizeDivision cfg rep, - d /= (-1), d /= 0, d /= 1, - [rQuot,rRem] <- res -> do - -- we are definitely going to use n multiple times, so put it into a register - n' <- intoRegister n (cmmBits rep) - -- generate an optimized (signed) division of n by d - q <- generateDivisionBySigned platform cfg rep n' d - -- we also need the result multiple times to calculate the remainder - q' <- intoRegister q (cmmBits rep) - - prependNode $! CmmAssign (CmmLocal rQuot) q' - -- The remainder now becomes n - q * d - pure . Just $! CmmAssign (CmmLocal rRem) $ CmmMachOp (MO_Sub rep) [n', CmmMachOp (MO_Mul rep) [q', CmmLit $ CmmInt d rep]] - where - platform = cmmPlatform cfg - d = narrowS rep d' - MO_U_QuotRem rep - | Just p <- exactLog2 d, - [rQuot,rRem] <- res -> do - -- first prepend the optimized division by a power 2 - prependNode $! CmmAssign (CmmLocal rQuot) $ CmmMachOp (MO_U_Shr rep) [n, CmmLit (CmmInt p $ wordWidth platform)] - -- then output an optimized remainder by a power of 2 - pure . Just $! CmmAssign (CmmLocal rRem) $ CmmMachOp (MO_And rep) [n, CmmLit (CmmInt (d - 1) rep)] - | canOptimizeDivision cfg rep, - d /= 0, d /= 1, - [rQuot,rRem] <- res -> do - -- we are definitely going to use n multiple times, so put it into a register - n' <- intoRegister n (cmmBits rep) - -- generate an optimized (unsigned) division of n by d - q <- generateDivisionByUnsigned platform cfg rep n' d - -- we also need the result multiple times to calculate the remainder - q' <- intoRegister q (cmmBits rep) - - prependNode $! CmmAssign (CmmLocal rQuot) q' - -- The remainder now becomes n - q * d - pure . Just $! CmmAssign (CmmLocal rRem) $ CmmMachOp (MO_Sub rep) [n', CmmMachOp (MO_Mul rep) [q', CmmLit $ CmmInt d rep]] - where - platform = cmmPlatform cfg - d = narrowU rep d' - _ -> pure Nothing - -cmmCallishMachOpFoldM _ _ _ _ = pure Nothing - --- ----------------------------------------------------------------------------- --- Specialized constant folding for MachOps which sometimes need to expand into multiple nodes - -cmmMachOpFoldOptM :: CmmConfig -> MachOp -> [CmmExpr] -> Opt (Maybe CmmExpr) - -cmmMachOpFoldOptM cfg op [n, CmmLit (CmmInt d' _)] = - case op of - MO_S_Quot rep - -- recheck for power of 2 division. This may not be handled by cmmMachOpFoldM if n is not in a register - | Just p <- exactLog2 d -> do - n' <- intoRegister n (cmmBits rep) - pure . Just $! cmmMachOpFold platform (MO_S_Shr rep) - [ signedQuotRemHelper platform d n' rep p - , CmmLit (CmmInt p $ wordWidth platform) - ] - | canOptimizeDivision cfg rep, - d /= (-1), d /= 0, d /= 1 -> Just <$!> generateDivisionBySigned platform cfg rep n d - where d = narrowS rep d' - MO_S_Rem rep - -- recheck for power of 2 remainder. This may not be handled by cmmMachOpFoldM if n is not in a register - | Just p <- exactLog2 d -> do - n' <- intoRegister n (cmmBits rep) - pure . Just $! cmmMachOpFold platform (MO_Sub rep) - [ n' - , cmmMachOpFold platform (MO_And rep) - [ signedQuotRemHelper platform d n' rep p - , CmmLit (CmmInt (- d) rep) - ] - ] - | canOptimizeDivision cfg rep, - d /= (-1), d /= 0, d /= 1 -> do - n' <- intoRegister n (cmmBits rep) - -- first generate the division - q <- generateDivisionBySigned platform cfg rep n' d - -- then calculate the remainder by n - q * d - pure . Just $! CmmMachOp (MO_Sub rep) [n', CmmMachOp (MO_Mul rep) [q, CmmLit $ CmmInt d rep]] - where d = narrowS rep d' - MO_U_Quot rep - -- No need to recheck power of 2 division because cmmMachOpFoldM always handles that case - | canOptimizeDivision cfg rep, - d /= 0, d /= 1, Nothing <- exactLog2 d -> Just <$!> generateDivisionByUnsigned platform cfg rep n d - where d = narrowU rep d' - MO_U_Rem rep - -- No need to recheck power of 2 remainder because cmmMachOpFoldM always handles that case - | canOptimizeDivision cfg rep, - d /= 0, d /= 1, Nothing <- exactLog2 d -> do - n' <- intoRegister n (cmmBits rep) - -- first generate the division - q <- generateDivisionByUnsigned platform cfg rep n d - -- then calculate the remainder by n - q * d - pure . Just $! CmmMachOp (MO_Sub rep) [n', CmmMachOp (MO_Mul rep) [q, CmmLit $ CmmInt d rep]] - where d = narrowU rep d' - _ -> pure Nothing - where platform = cmmPlatform cfg - -cmmMachOpFoldOptM _ _ _ = pure Nothing - --- ----------------------------------------------------------------------------- --- Utils for prepending new nodes - --- Move an expression into a register to possibly use it multiple times -intoRegister :: CmmExpr -> CmmType -> Opt CmmExpr -intoRegister e@(CmmReg _) _ = pure e -intoRegister expr ty = do - u <- getUniqueM - let reg = LocalReg u ty - CmmReg (CmmLocal reg) <$ prependNode (CmmAssign (CmmLocal reg) expr) - -prependNode :: CmmNode O O -> Opt () -prependNode n = Opt $ \_ xs -> pure (xs ++ [n], ()) - --- ----------------------------------------------------------------------------- --- Division by constants utils - --- Helper for division by a power of 2 --- In contrast with unsigned integers, for signed ones --- shift right is not the same as quot, because it rounds --- to minus infinity, whereas quot rounds toward zero. --- To fix this up, we add one less than the divisor to the --- dividend if it is a negative number. --- --- to avoid a test/jump, we use the following sequence: --- x1 = x >> word_size-1 (all 1s if -ve, all 0s if +ve) --- x2 = y & (divisor-1) --- result = x + x2 --- this could be done a bit more simply using conditional moves, --- but we're processor independent here. --- --- we optimize the divide by 2 case slightly, generating --- x1 = x >> word_size-1 (unsigned) --- return = x + x1 -signedQuotRemHelper :: Platform -> Integer -> CmmExpr -> Width -> Integer -> CmmExpr -signedQuotRemHelper platform n x rep p = CmmMachOp (MO_Add rep) [x, x2] - where - bits = fromIntegral (widthInBits rep) - 1 - shr = if p == 1 then MO_U_Shr rep else MO_S_Shr rep - x1 = CmmMachOp shr [x, CmmLit (CmmInt bits $ wordWidth platform)] - x2 = if p == 1 then x1 else - CmmMachOp (MO_And rep) [x1, CmmLit (CmmInt (n-1) rep)] - -{- Note: [Division by constants] - -Integer division is floor(n / d), the goal is to find m,p -such that floor((m * n) / 2^p) = floor(n / d). - -The idea being: n/d = n * (1/d). But we cannot store 1/d in an integer without -some error, so we choose some 2^p / d such that the error ends up small and -thus vanishes when we divide by 2^p again. - -The algorithm below to generate these numbers is taken from Hacker's Delight -Second Edition Chapter 10 "Integer division by constants". The chapter also -contains proof that this method does indeed produce correct results. - -However this is a much more literal interpretation of the algorithm, -which we can use because of the unbounded Integer type. Hacker's Delight -also provides a much more complex algorithm which computes these numbers -without the need to exceed the word size, but that is not necessary here. --} - -generateDivisionBySigned :: Platform -> CmmConfig -> Width -> CmmExpr -> Integer -> Opt CmmExpr - --- Sanity checks, division will generate incorrect results or undesirable code for these cases --- cmmMachOpFoldM and cmmMachOpFoldOptM should have already handled these cases! -generateDivisionBySigned _ _ _ _ 0 = panic "generate signed division with 0" -generateDivisionBySigned _ _ _ _ 1 = panic "generate signed division with 1" -generateDivisionBySigned _ _ _ _ (-1) = panic "generate signed division with -1" -generateDivisionBySigned _ _ _ _ d | Just _ <- exactLog2 d = panic $ "generate signed division with " ++ show d - -generateDivisionBySigned platform _cfg rep n divisor = do - -- We only duplicate n' if we actually need to add/subtract it, so we may not need it in a register - n' <- if sign == 0 then pure n else intoRegister n resRep - - -- Set up mul2 - (shift', qExpr) <- mul2 n' - - -- add/subtract n if necessary - let qExpr' = case sign of - 1 -> CmmMachOp (MO_Add rep) [qExpr, n'] - -1 -> CmmMachOp (MO_Sub rep) [qExpr, n'] - _ -> qExpr - - qExpr'' <- intoRegister (cmmMachOpFold platform (MO_S_Shr rep) [qExpr', CmmLit $ CmmInt shift' wordRep]) resRep - - -- Lastly add the sign of the quotient to correct for negative results - pure $! cmmMachOpFold platform - (MO_Add rep) [qExpr'', cmmMachOpFold platform (MO_U_Shr rep) [qExpr'', CmmLit $ CmmInt (toInteger $ widthInBits rep - 1) wordRep]] - where - resRep = cmmBits rep - wordRep = wordWidth platform - (magic, sign, shift) = divisionMagicS rep divisor - -- generate the multiply with the magic number - mul2 n - -- Using mul2 for sub-word sizes regresses for signed integers only - | rep == wordWidth platform = do - (r1, r2, r3) <- (,,) <$> getUniqueM <*> getUniqueM <*> getUniqueM - let rg1 = LocalReg r1 resRep - resReg = LocalReg r2 resRep - rg3 = LocalReg r3 resRep - res <- CmmReg (CmmLocal resReg) <$ prependNode (CmmUnsafeForeignCall (PrimTarget (MO_S_Mul2 rep)) [rg1, resReg, rg3] [n, CmmLit $ CmmInt magic rep]) - pure (shift, res) - -- widen the register and multiply without the MUL2 instruction - -- if we don't need an additional add after this we can combine the shifts - | otherwise = pure (if sign == 0 then 0 else shift, res) - where - wordRep = wordWidth platform - -- (n * magic) >> widthInBits + (if sign == 0 then shift else 0) -- With conversion in between to not overflow - res = cmmMachOpFold platform (MO_SS_Conv wordRep rep) - [ cmmMachOpFold platform (MO_S_Shr wordRep) - [ cmmMachOpFold platform (MO_Mul wordRep) - [ cmmMachOpFold platform (MO_SS_Conv rep wordRep) [n] - , CmmLit $ CmmInt magic wordRep - ] - -- Check if we need to generate an add/subtract later. If not we can combine this with the postshift - , CmmLit $ CmmInt ((if sign == 0 then toInteger shift else 0) + (toInteger $ widthInBits rep)) wordRep - ] - ] - --- See hackers delight for how and why this works (chapter in note [Division by constants]) -divisionMagicS :: Width -> Integer -> (Integer, Integer, Integer) -divisionMagicS rep divisor = (magic, sign, toInteger $ p - wSz) - where - sign = if divisor > 0 - then if magic < 0 then 1 else 0 - else if magic < 0 then 0 else -1 - wSz = widthInBits rep - ad = abs divisor - t = (1 `shiftL` (wSz - 1)) + if divisor > 0 then 0 else 1 - anc = t - 1 - rem t ad - go p' - | twoP > anc * (ad - rem twoP ad) = p' - | otherwise = go (p' + 1) - where twoP = 1 `shiftL` p' - p = go wSz - am = (twoP + ad - rem twoP ad) `quot` ad - where twoP = 1 `shiftL` p - magic = narrowS rep $ if divisor > 0 then am else -am - -generateDivisionByUnsigned :: Platform -> CmmConfig -> Width -> CmmExpr -> Integer -> Opt CmmExpr --- Sanity checks, division will generate incorrect results or undesirable code for these cases --- cmmMachOpFoldM and cmmMachOpFoldOptM should have already handled these cases! -generateDivisionByUnsigned _ _ _ _ 0 = panic "generate signed division with 0" -generateDivisionByUnsigned _ _ _ _ 1 = panic "generate signed division with 1" -generateDivisionByUnsigned _ _ _ _ d | Just _ <- exactLog2 d = panic $ "generate signed division with " ++ show d - -generateDivisionByUnsigned platform cfg rep n divisor = do - -- We only duplicate n' if we actually need to add/subtract it, so we may not need it in a register - n' <- if not needsAdd -- Invariant: We also never preshift if we need an add, thus we don't need n in a register - then pure $! cmmMachOpFold platform (MO_U_Shr rep) [n, CmmLit $ CmmInt preShift wordRep] - else intoRegister n resRep - - -- Set up mul2 - (postShift', qExpr) <- mul2 n' - - -- add/subtract n if necessary - let qExpr' = if needsAdd - -- This is qExpr + (n - qExpr) / 2 = (qExpr + n) / 2 but with a guarantee that it'll not overflow - then cmmMachOpFold platform (MO_Add rep) - [ cmmMachOpFold platform (MO_U_Shr rep) - [ cmmMachOpFold platform (MO_Sub rep) [n', qExpr] - , CmmLit $ CmmInt 1 wordRep - ] - , qExpr - ] - else qExpr - -- If we already divided by 2 in the add, remember to shift one bit less - -- Hacker's Delight, Edition 2 Page 234: postShift > 0 if we needed an add, except if the divisor - -- is 1, which we checked for above - finalShift = if needsAdd then postShift' - 1 else postShift' - - -- apply the final postShift - pure $! cmmMachOpFold platform (MO_U_Shr rep) [qExpr', CmmLit $ CmmInt finalShift wordRep] - where - resRep = cmmBits rep - wordRep = wordWidth platform - (preShift, magic, needsAdd, postShift) = - let withPre = divisionMagicU rep True divisor - noPre = divisionMagicU rep False divisor - in case (withPre, noPre) of - -- Use whatever does not cause us to take the expensive case - ((_, _, False, _), (_, _, True, _)) -> withPre - -- If we cannot avoid the expensive case, don't bother with the pre shift - _ -> noPre - -- generate the multiply with the magic number - mul2 n - | rep == wordWidth platform || (cmmAllowMul2 cfg && needsAdd) = do - (r1, r2) <- (,) <$> getUniqueM <*> getUniqueM - let rg1 = LocalReg r1 resRep - resReg = LocalReg r2 resRep - res <- CmmReg (CmmLocal resReg) <$ prependNode (CmmUnsafeForeignCall (PrimTarget (MO_U_Mul2 rep)) [resReg, rg1] [n, CmmLit $ CmmInt magic rep]) - pure (postShift, res) - | otherwise = do - pure (if needsAdd then postShift else 0, res) - where - wordRep = wordWidth platform - -- (n * magic) >> widthInBits + (if sign == 0 then shift else 0) -- With conversion in between to not overflow - res = cmmMachOpFold platform (MO_UU_Conv wordRep rep) - [ cmmMachOpFold platform (MO_U_Shr wordRep) - [ cmmMachOpFold platform (MO_Mul wordRep) - [ cmmMachOpFold platform (MO_UU_Conv rep wordRep) [n] - , CmmLit $ CmmInt magic wordRep - ] - -- Check if we need to generate an add later. If not we can combine this with the postshift - , CmmLit $ CmmInt ((if needsAdd then 0 else postShift) + (toInteger $ widthInBits rep)) wordRep - ] - ] - --- See hackers delight for how and why this works (chapter in note [Division by constants]) --- The preshift isn't described there, but the idea is: --- If a divisor d has n trailing zeros, then d is a multiple of 2^n. Since we want to divide x by d --- we can also calculate (x / 2^n) / (d / 2^n) which may then not require an extra addition. --- --- The addition performs: quotient + dividend, but we need to avoid overflows, so we actually need to --- calculate: quotient + (dividend - quotient) / 2 = (quotient + dividend) / 2 --- Thus if the preshift can avoid all of this, we have 1 operation in place of 3. --- --- The decision to use the preshift is made somewhere else, here we only report if the addition is needed -divisionMagicU :: Width -> Bool -> Integer -> (Integer, Integer, Bool, Integer) -divisionMagicU rep doPreShift divisor = (toInteger zeros, magic, needsAdd, toInteger $ p - wSz) - where - wSz = widthInBits rep - zeros = if doPreShift then countTrailingZeros $ fromInteger @Word64 divisor else 0 - d = divisor `shiftR` zeros - ones = ((1 `shiftL` wSz) - 1) `shiftR` zeros - nc = ones - rem (ones - d) d - go p' - | twoP > nc * (d - 1 - rem (twoP - 1) d) = p' - | otherwise = go (p' + 1) - where twoP = 1 `shiftL` p' - p = go wSz - m = (twoP + d - 1 - rem (twoP - 1) d) `quot` d - where twoP = 1 `shiftL` p - needsAdd = d < 1 `shiftL` (p - wSz) - magic = if needsAdd then m - (ones + 1) else m - --- ----------------------------------------------------------------------------- --- Opt monad - -newtype Opt a = OptI { runOptI :: CmmConfig -> [CmmNode O O] -> UniqDSM ([CmmNode O O], a) } - --- | Pattern synonym for 'Opt', as described in Note [The one-shot state --- monad trick]. -pattern Opt :: (CmmConfig -> [CmmNode O O] -> UniqDSM ([CmmNode O O], a)) -> Opt a -pattern Opt f <- OptI f - where Opt f = OptI . oneShot $ \cfg -> oneShot $ \out -> f cfg out -{-# COMPLETE Opt #-} - -runOpt :: CmmConfig -> Opt a -> UniqDSM ([CmmNode O O], a) -runOpt cf (Opt g) = g cf [] - -getConfig :: Opt CmmConfig -getConfig = Opt $ \cf xs -> pure (xs, cf) - -instance Functor Opt where - fmap f (Opt g) = Opt $ \cf xs -> fmap (fmap f) (g cf xs) - -instance Applicative Opt where - pure a = Opt $ \_ xs -> pure (xs, a) - ff <*> fa = do - f <- ff - f <$> fa - -instance Monad Opt where - Opt g >>= f = Opt $ \cf xs -> do - (ys, a) <- g cf xs - runOptI (f a) cf ys - -instance MonadGetUnique Opt where - getUniqueM = Opt $ \_ xs -> (xs,) <$> getUniqueDSM - -mapForeignTargetOpt :: (CmmExpr -> Opt CmmExpr) -> ForeignTarget -> Opt ForeignTarget -mapForeignTargetOpt exp (ForeignTarget e c) = flip ForeignTarget c <$> exp e -mapForeignTargetOpt _ m@(PrimTarget _) = pure m - -wrapRecExpOpt :: (CmmExpr -> Opt CmmExpr) -> CmmExpr -> Opt CmmExpr -wrapRecExpOpt f (CmmMachOp op es) = traverse (wrapRecExpOpt f) es >>= f . CmmMachOp op -wrapRecExpOpt f (CmmLoad addr ty align) = wrapRecExpOpt f addr >>= \newAddr -> f (CmmLoad newAddr ty align) -wrapRecExpOpt f e = f e - -mapExpOpt :: (CmmExpr -> Opt CmmExpr) -> CmmNode e x -> Opt (CmmNode e x) -mapExpOpt _ f@(CmmEntry{}) = pure f -mapExpOpt _ m@(CmmComment _) = pure m -mapExpOpt _ m@(CmmTick _) = pure m -mapExpOpt f (CmmUnwind regs) = CmmUnwind <$> traverse (traverse (traverse f)) regs -mapExpOpt f (CmmAssign r e) = CmmAssign r <$> f e -mapExpOpt f (CmmStore addr e align) = CmmStore <$> f addr <*> f e <*> pure align -mapExpOpt f (CmmUnsafeForeignCall tgt fs as) = CmmUnsafeForeignCall <$> mapForeignTargetOpt f tgt <*> pure fs <*> traverse f as -mapExpOpt _ l@(CmmBranch _) = pure l -mapExpOpt f (CmmCondBranch e ti fi l) = f e >>= \newE -> pure (CmmCondBranch newE ti fi l) -mapExpOpt f (CmmSwitch e ids) = flip CmmSwitch ids <$> f e -mapExpOpt f n at CmmCall {cml_target=tgt} = f tgt >>= \newTgt -> pure n{cml_target = newTgt} -mapExpOpt f (CmmForeignCall tgt fs as succ ret_args updfr intrbl) - = do - newTgt <- mapForeignTargetOpt f tgt - newAs <- traverse f as - pure $ CmmForeignCall newTgt fs newAs succ ret_args updfr intrbl ===================================== compiler/GHC/Cmm/Pipeline.hs ===================================== @@ -137,12 +137,9 @@ cpsTop logger platform cfg dus proc = dump Opt_D_dump_cmm_sp "Layout Stack" g ----------- Sink and inline assignments -------------------------------- - (g, dus) <- {-# SCC "sink" #-} -- See Note [Sinking after stack layout] - if cmmOptSink cfg - then pure $ runUniqueDSM dus $ cmmSink cfg g - else return (g, dus) - dump Opt_D_dump_cmm_sink "Sink assignments" g - + g <- {-# SCC "sink" #-} -- See Note [Sinking after stack layout] + condPass (cmmOptSink cfg) (cmmSink platform) g + Opt_D_dump_cmm_sink "Sink assignments" ------------- CAF analysis ---------------------------------------------- let cafEnv = {-# SCC "cafAnal" #-} cafAnal platform call_pps l g ===================================== compiler/GHC/Cmm/Sink.hs ===================================== @@ -20,8 +20,6 @@ import GHC.Platform.Regs import GHC.Platform import GHC.Types.Unique.FM -import GHC.Types.Unique.DSM -import GHC.Cmm.Config import Data.List (partition) import Data.Maybe @@ -152,10 +150,9 @@ type Assignments = [Assignment] -- y = e2 -- x = e1 -cmmSink :: CmmConfig -> CmmGraph -> UniqDSM CmmGraph -cmmSink cfg graph = ofBlockList (g_entry graph) <$> sink mapEmpty blocks +cmmSink :: Platform -> CmmGraph -> CmmGraph +cmmSink platform graph = ofBlockList (g_entry graph) $ sink mapEmpty $ blocks where - platform = cmmPlatform cfg liveness = cmmLocalLivenessL platform graph getLive l = mapFindWithDefault emptyLRegSet l liveness @@ -163,41 +160,11 @@ cmmSink cfg graph = ofBlockList (g_entry graph) <$> sink mapEmpty blocks join_pts = findJoinPoints blocks - sink :: LabelMap Assignments -> [CmmBlock] -> UniqDSM [CmmBlock] - sink _ [] = pure [] - sink sunk (b:bs) = do - -- Now sink and inline in this block - (prepend, last_fold) <- runOpt cfg $ constantFoldNode last - - (middle', assigs) <- walk cfg (ann_middles ++ annotate platform live_middle prepend) (mapFindWithDefault [] lbl sunk) - - let (final_last, assigs') = tryToInline platform live last_fold assigs - -- Now, drop any assignments that we will not sink any further. - (dropped_last, assigs'') = dropAssignments platform drop_if init_live_sets assigs' - drop_if :: (LocalReg, CmmExpr, AbsMem) - -> [LRegSet] -> (Bool, [LRegSet]) - drop_if a@(r,rhs,_) live_sets = (should_drop, live_sets') - where - should_drop = conflicts platform a final_last - || not (isTrivial platform rhs) && live_in_multi live_sets r - || r `elemLRegSet` live_in_joins - - live_sets' | should_drop = live_sets - | otherwise = map upd live_sets - - upd set | r `elemLRegSet` set = set `unionLRegSet` live_rhs - | otherwise = set - - live_rhs = foldRegsUsed platform (flip insertLRegSet) emptyLRegSet rhs - - final_middle = foldl' blockSnoc middle' dropped_last - - sunk' = mapUnion sunk $ - mapFromList [ (l, filterAssignments platform (getLive l) assigs'') - | l <- succs ] - - (blockJoin first final_middle final_last :) <$> sink sunk' bs - + sink :: LabelMap Assignments -> [CmmBlock] -> [CmmBlock] + sink _ [] = [] + sink sunk (b:bs) = + -- pprTrace "sink" (ppr lbl) $ + blockJoin first final_middle final_last : sink sunk' bs where lbl = entryLabel b (first, middle, last) = blockSplit b @@ -211,6 +178,11 @@ cmmSink cfg graph = ofBlockList (g_entry graph) <$> sink mapEmpty blocks live_middle = gen_killL platform last live ann_middles = annotate platform live_middle (blockToList middle) + -- Now sink and inline in this block + (middle', assigs) = walk platform ann_middles (mapFindWithDefault [] lbl sunk) + fold_last = constantFoldNode platform last + (final_last, assigs') = tryToInline platform live fold_last assigs + -- We cannot sink into join points (successors with more than -- one predecessor), so identify the join points and the set -- of registers live in them. @@ -228,6 +200,31 @@ cmmSink cfg graph = ofBlockList (g_entry graph) <$> sink mapEmpty blocks (_one:_two:_) -> True _ -> False + -- Now, drop any assignments that we will not sink any further. + (dropped_last, assigs'') = dropAssignments platform drop_if init_live_sets assigs' + + drop_if :: (LocalReg, CmmExpr, AbsMem) + -> [LRegSet] -> (Bool, [LRegSet]) + drop_if a@(r,rhs,_) live_sets = (should_drop, live_sets') + where + should_drop = conflicts platform a final_last + || not (isTrivial platform rhs) && live_in_multi live_sets r + || r `elemLRegSet` live_in_joins + + live_sets' | should_drop = live_sets + | otherwise = map upd live_sets + + upd set | r `elemLRegSet` set = set `unionLRegSet` live_rhs + | otherwise = set + + live_rhs = foldRegsUsed platform (flip insertLRegSet) emptyLRegSet rhs + + final_middle = foldl' blockSnoc middle' dropped_last + + sunk' = mapUnion sunk $ + mapFromList [ (l, filterAssignments platform (getLive l) assigs'') + | l <- succs ] + {- TODO: enable this later, when we have some good tests in place to measure the effect and tune it. @@ -302,7 +299,7 @@ filterAssignments platform live assigs = reverse (go assigs []) -- * a list of assignments that will be placed *after* that block. -- -walk :: CmmConfig +walk :: Platform -> [(LRegSet, CmmNode O O)] -- nodes of the block, annotated with -- the set of registers live *after* -- this node. @@ -312,39 +309,36 @@ walk :: CmmConfig -- Earlier assignments may refer -- to later ones. - -> UniqDSM ( Block CmmNode O O -- The new block - , Assignments -- Assignments to sink further - ) + -> ( Block CmmNode O O -- The new block + , Assignments -- Assignments to sink further + ) -walk cfg nodes assigs = go nodes emptyBlock assigs +walk platform nodes assigs = go nodes emptyBlock assigs where - platform = cmmPlatform cfg - go [] block as = pure (block, as) + go [] block as = (block, as) go ((live,node):ns) block as -- discard nodes representing dead assignment | shouldDiscard node live = go ns block as - | otherwise = do - (prepend, node1) <- runOpt cfg $ constantFoldNode node - if not (null prepend) - then go (annotate platform live (prepend ++ [node1]) ++ ns) block as - else do - let -- Inline assignments - (node2, as1) = tryToInline platform live node1 as - -- Drop any earlier assignments conflicting with node2 - (dropped, as') = dropAssignmentsSimple platform - (\a -> conflicts platform a node2) as1 - -- Walk over the rest of the block. Includes dropped assignments - block' = foldl' blockSnoc block dropped `blockSnoc` node2 - - (prepend2, node3) <- runOpt cfg $ constantFoldNode node2 - if | not (null prepend2) -> go (annotate platform live (prepend2 ++ [node3]) ++ ns) block as - -- sometimes only after simplification we can tell we can discard the node. - -- See Note [Discard simplified nodes] - | noOpAssignment node3 -> go ns block as - -- Pick up interesting assignments - | Just a <- shouldSink platform node3 -> go ns block (a : as1) - -- Try inlining, drop assignments and move on - | otherwise -> go ns block' as' + -- sometimes only after simplification we can tell we can discard the node. + -- See Note [Discard simplified nodes] + | noOpAssignment node2 = go ns block as + -- Pick up interesting assignments + | Just a <- shouldSink platform node2 = go ns block (a : as1) + -- Try inlining, drop assignments and move on + | otherwise = go ns block' as' + where + -- Simplify node + node1 = constantFoldNode platform node + + -- Inline assignments + (node2, as1) = tryToInline platform live node1 as + + -- Drop any earlier assignments conflicting with node2 + (dropped, as') = dropAssignmentsSimple platform + (\a -> conflicts platform a node2) as1 + + -- Walk over the rest of the block. Includes dropped assignments + block' = foldl' blockSnoc block dropped `blockSnoc` node2 {- Note [Discard simplified nodes] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Driver/Config/Cmm.hs ===================================== @@ -24,17 +24,5 @@ initCmmConfig dflags = CmmConfig , cmmDoCmmSwitchPlans = not (backendHasNativeSwitch (backend dflags)) , cmmSplitProcPoints = not (backendSupportsUnsplitProcPoints (backend dflags)) || not (platformTablesNextToCode platform) - , cmmAllowMul2 = (ncg && x86ish) || llvm - , cmmOptConstDivision = not llvm } where platform = targetPlatform dflags - -- Copied from StgToCmm - (ncg, llvm) = case backendPrimitiveImplementation (backend dflags) of - GenericPrimitives -> (False, False) - NcgPrimitives -> (True, False) - LlvmPrimitives -> (False, True) - JSPrimitives -> (False, False) - x86ish = case platformArch platform of - ArchX86 -> True - ArchX86_64 -> True - _ -> False ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1571,28 +1571,28 @@ emitPrimOp cfg primop = CastDoubleToWord64Op -> translateBitcasts (MO_FW_Bitcast W64) CastWord64ToDoubleOp -> translateBitcasts (MO_WF_Bitcast W64) - IntQuotRemOp -> opCallishHandledLater $ - if allowQuotRem + IntQuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_S_QuotRem (wordWidth platform)) else Right (genericIntQuotRemOp (wordWidth platform)) - Int8QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Int8QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_S_QuotRem W8) else Right (genericIntQuotRemOp W8) - Int16QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Int16QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_S_QuotRem W16) else Right (genericIntQuotRemOp W16) - Int32QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Int32QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_S_QuotRem W32) else Right (genericIntQuotRemOp W32) - WordQuotRemOp -> opCallishHandledLater $ - if allowQuotRem + WordQuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_U_QuotRem (wordWidth platform)) else Right (genericWordQuotRemOp (wordWidth platform)) @@ -1601,18 +1601,18 @@ emitPrimOp cfg primop = then Left (MO_U_QuotRem2 (wordWidth platform)) else Right (genericWordQuotRem2Op platform) - Word8QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Word8QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_U_QuotRem W8) else Right (genericWordQuotRemOp W8) - Word16QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Word16QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_U_QuotRem W16) else Right (genericWordQuotRemOp W16) - Word32QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Word32QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_U_QuotRem W32) else Right (genericWordQuotRemOp W32) @@ -1835,6 +1835,23 @@ emitPrimOp cfg primop = pure $ map (CmmReg . CmmLocal) regs alwaysExternal = \_ -> PrimopCmmEmit_External + -- Note [QuotRem optimization] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- `quot` and `rem` with constant divisor can be implemented with fast bit-ops + -- (shift, .&.). + -- + -- Currently we only support optimization (performed in GHC.Cmm.Opt) when the + -- constant is a power of 2. #9041 tracks the implementation of the general + -- optimization. + -- + -- `quotRem` can be optimized in the same way. However as it returns two values, + -- it is implemented as a "callish" primop which is harder to match and + -- to transform later on. For simplicity, the current implementation detects cases + -- that can be optimized (see `quotRemCanBeOptimized`) and converts STG quotRem + -- primop into two CMM quot and rem primops. + quotRemCanBeOptimized = \case + [_, CmmLit (CmmInt n _) ] -> isJust (exactLog2 n) + _ -> False allowQuotRem = stgToCmmAllowQuotRemInstr cfg allowQuotRem2 = stgToCmmAllowQuotRem2 cfg ===================================== testsuite/tests/numeric/should_run/T25653.hs ===================================== @@ -0,0 +1,10 @@ +module Main (main) where + +import Data.Word (Word8) + +myMod :: Word8 -> Word8 +myMod i = mod i 7 +{-# NOINLINE myMod #-} + +main :: IO () +main = print $ myMod 5 ===================================== testsuite/tests/numeric/should_run/T25653.stdout ===================================== @@ -0,0 +1 @@ +5 ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -86,3 +86,4 @@ test('foundation', [when(js_arch(), run_timeout_multiplier(2)), js_fragile(24259 test('T24066', normal, compile_and_run, ['']) test('div01', normal, compile_and_run, ['']) test('T24245', normal, compile_and_run, ['']) +test('T25653', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/daf659b6e3c8f2a84100fbee797cd9d457c00df5...2a48b7b51af4f31d0569ad614932facd5db2136b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/daf659b6e3c8f2a84100fbee797cd9d457c00df5...2a48b7b51af4f31d0569ad614932facd5db2136b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 14:28:20 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 18 Jan 2025 09:28:20 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Fix a buglet in tcSplitForAllTyVarsReqTVBindersN Message-ID: <678bba844f11a_769ea3a5700155bb@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - ae9cce49 by Ben Gamari at 2025-01-18T09:28:03-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 059baf51 by Ben Gamari at 2025-01-18T09:28:03-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - d52617fc by Ben Gamari at 2025-01-18T09:28:03-05:00 testsuite: Test shift correctness in mul2 test - - - - - 014b619f by Ben Gamari at 2025-01-18T09:28:03-05:00 testsuite: Add regression test for #25653 - - - - - 30 changed files: - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Ppr.hs - compiler/GHC/HsToCore/Errors/Ppr.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Iface/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - compiler/GHC/Types/Var.hs - docs/users_guide/9.14.1-notes.rst - ghc/GHCi/UI.hs - ghc/GHCi/UI/Exception.hs - ghc/GHCi/UI/Info.hs - ghc/GHCi/UI/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ddd6147349f55ed6d38c7eea876fdacc69a040a2...014b619f9d23c7911845a908763d8388a018d690 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ddd6147349f55ed6d38c7eea876fdacc69a040a2...014b619f9d23c7911845a908763d8388a018d690 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 17:38:35 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 18 Jan 2025 12:38:35 -0500 Subject: [Git][ghc/ghc][master] 2 commits: Generalise GHC diagnostic code infrastructure Message-ID: <678be71be1707_981bc1831e5822315@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - 30 changed files: - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Ppr.hs - compiler/GHC/HsToCore/Errors/Ppr.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Iface/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/9.14.1-notes.rst - ghc/GHCi/UI.hs - ghc/GHCi/UI/Exception.hs - ghc/GHCi/UI/Info.hs - ghc/GHCi/UI/Monad.hs - + ghc/GHCi/UI/Print.hs - ghc/ghc-bin.cabal.in - linters/lint-codes/LintCodes/Static.hs - linters/lint-codes/Main.hs - testsuite/tests/driver/multipleHomeUnits/multiGHCi.stderr - testsuite/tests/ghc-e/should_fail/T18441fail0.stderr - testsuite/tests/ghc-e/should_fail/T18441fail1.stderr - testsuite/tests/ghc-e/should_fail/T18441fail10.stderr - testsuite/tests/ghc-e/should_fail/T18441fail11.stderr - testsuite/tests/ghc-e/should_fail/T18441fail14.stderr - testsuite/tests/ghc-e/should_fail/T18441fail15.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/854c2f753dddeaa31d2988704cedf651f9fb7958...bf4f5ad31ddeb87baad10de47f84081648f808dc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/854c2f753dddeaa31d2988704cedf651f9fb7958...bf4f5ad31ddeb87baad10de47f84081648f808dc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 18 17:39:21 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 18 Jan 2025 12:39:21 -0500 Subject: [Git][ghc/ghc][master] 4 commits: Revert "Division by constants optimization" Message-ID: <678be7498fc47_981bc1831e4424953@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 10 changed files: - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/StgToCmm/Prim.hs - + testsuite/tests/numeric/should_run/T25653.hs - + testsuite/tests/numeric/should_run/T25653.stdout - testsuite/tests/numeric/should_run/all.T Changes: ===================================== compiler/GHC/Cmm/Config.hs ===================================== @@ -24,8 +24,6 @@ data CmmConfig = CmmConfig , cmmExternalDynamicRefs :: !Bool -- ^ Generate code to link against dynamic libraries , cmmDoCmmSwitchPlans :: !Bool -- ^ Should the Cmm pass replace Stg switch statements , cmmSplitProcPoints :: !Bool -- ^ Should Cmm split proc points or not - , cmmAllowMul2 :: !Bool -- ^ Does this platform support mul2 - , cmmOptConstDivision :: !Bool -- ^ Should we optimize constant divisors } -- | retrieve the target Cmm platform ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -7,7 +7,6 @@ module GHC.Cmm.MachOp , pprMachOp, isCommutableMachOp, isAssociativeMachOp , isComparisonMachOp, maybeIntComparison, machOpResultType , machOpArgReps, maybeInvertComparison, isFloatComparison - , isCommutableCallishMachOp -- MachOp builders , mo_wordAdd, mo_wordSub, mo_wordEq, mo_wordNe,mo_wordMul, mo_wordSQuot @@ -846,17 +845,3 @@ machOpMemcpyishAlign op = case op of MO_Memmove align -> Just align MO_Memcmp align -> Just align _ -> Nothing - -isCommutableCallishMachOp :: CallishMachOp -> Bool -isCommutableCallishMachOp op = - case op of - MO_x64_Add -> True - MO_x64_Mul -> True - MO_x64_Eq -> True - MO_x64_Ne -> True - MO_x64_And -> True - MO_x64_Or -> True - MO_x64_Xor -> True - MO_S_Mul2 _ -> True - MO_U_Mul2 _ -> True - _ -> False ===================================== compiler/GHC/Cmm/Opt.hs ===================================== @@ -5,52 +5,27 @@ -- (c) The University of Glasgow 2006 -- ----------------------------------------------------------------------------- -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE PatternSynonyms #-} module GHC.Cmm.Opt ( constantFoldNode, constantFoldExpr, cmmMachOpFold, - cmmMachOpFoldM, - Opt, runOpt + cmmMachOpFoldM ) where import GHC.Prelude -import GHC.Cmm.Dataflow.Block import GHC.Cmm.Utils import GHC.Cmm -import GHC.Cmm.Config -import GHC.Types.Unique.DSM - import GHC.Utils.Misc + import GHC.Utils.Panic import GHC.Platform import Data.Maybe -import Data.Word -import GHC.Exts (oneShot) -import Control.Monad - -constantFoldNode :: CmmNode e x -> Opt (CmmNode e x) -constantFoldNode (CmmUnsafeForeignCall (PrimTarget op) res args) - = traverse constantFoldExprOpt args >>= cmmCallishMachOpFold op res -constantFoldNode node - = mapExpOpt constantFoldExprOpt node - -constantFoldExprOpt :: CmmExpr -> Opt CmmExpr -constantFoldExprOpt e = wrapRecExpOpt f e - where - f (CmmMachOp op args) - = do - cfg <- getConfig - case cmmMachOpFold (cmmPlatform cfg) op args of - CmmMachOp op' args' -> fromMaybe (CmmMachOp op' args') <$> cmmMachOpFoldOptM cfg op' args' - e -> pure e - f (CmmRegOff r 0) = pure (CmmReg r) - f (CmmLit (CmmInt x rep)) = pure (CmmLit $ CmmInt (narrowU rep x) rep) - f e = pure e + + +constantFoldNode :: Platform -> CmmNode e x -> CmmNode e x +constantFoldNode platform = mapExp (constantFoldExpr platform) constantFoldExpr :: Platform -> CmmExpr -> CmmExpr constantFoldExpr platform = wrapRecExp f @@ -321,7 +296,7 @@ cmmMachOpFoldM platform cmp [CmmMachOp conv [x], CmmLit (CmmInt i _)] maybe_comparison (MO_S_Le _) rep False = Just (MO_U_Le rep) maybe_comparison _ _ _ = Nothing --- We can often do something with constants of 0, 1 and (-1) ... +-- We can often do something with constants of 0 and 1 ... -- See Note [Comparison operators] cmmMachOpFoldM platform mop [x, y@(CmmLit (CmmInt 0 _))] @@ -392,8 +367,6 @@ cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt n _))] MO_Mul rep | Just p <- exactLog2 n -> Just $! (cmmMachOpFold platform (MO_Shl rep) [x, CmmLit (CmmInt p $ wordWidth platform)]) - -- The optimization for division by power of 2 is technically duplicated, but since at least one other part of ghc uses - -- the pure `constantFoldExpr` this remains MO_U_Quot rep | Just p <- exactLog2 n -> Just $! (cmmMachOpFold platform (MO_U_Shr rep) [x, CmmLit (CmmInt p $ wordWidth platform)]) @@ -402,19 +375,46 @@ cmmMachOpFoldM platform mop [x, (CmmLit (CmmInt n _))] Just $! (cmmMachOpFold platform (MO_And rep) [x, CmmLit (CmmInt (n - 1) rep)]) MO_S_Quot rep | Just p <- exactLog2 n, - CmmReg _ <- x -> + CmmReg _ <- x -> -- We duplicate x in signedQuotRemHelper, hence require + -- it is a reg. FIXME: remove this restriction. Just $! (cmmMachOpFold platform (MO_S_Shr rep) - [signedQuotRemHelper platform n x rep p, CmmLit (CmmInt p $ wordWidth platform)]) + [signedQuotRemHelper rep p, CmmLit (CmmInt p $ wordWidth platform)]) MO_S_Rem rep | Just p <- exactLog2 n, - CmmReg _ <- x -> + CmmReg _ <- x -> -- We duplicate x in signedQuotRemHelper, hence require + -- it is a reg. FIXME: remove this restriction. -- We replace (x `rem` 2^p) by (x - (x `quot` 2^p) * 2^p). -- Moreover, we fuse MO_S_Shr (last operation of MO_S_Quot) -- and MO_S_Shl (multiplication by 2^p) into a single MO_And operation. Just $! (cmmMachOpFold platform (MO_Sub rep) [x, cmmMachOpFold platform (MO_And rep) - [signedQuotRemHelper platform n x rep p, CmmLit (CmmInt (- n) rep)]]) + [signedQuotRemHelper rep p, CmmLit (CmmInt (- n) rep)]]) _ -> Nothing + where + -- In contrast with unsigned integers, for signed ones + -- shift right is not the same as quot, because it rounds + -- to minus infinity, whereas quot rounds toward zero. + -- To fix this up, we add one less than the divisor to the + -- dividend if it is a negative number. + -- + -- to avoid a test/jump, we use the following sequence: + -- x1 = x >> word_size-1 (all 1s if -ve, all 0s if +ve) + -- x2 = y & (divisor-1) + -- result = x + x2 + -- this could be done a bit more simply using conditional moves, + -- but we're processor independent here. + -- + -- we optimise the divide by 2 case slightly, generating + -- x1 = x >> word_size-1 (unsigned) + -- return = x + x1 + signedQuotRemHelper :: Width -> Integer -> CmmExpr + signedQuotRemHelper rep p = CmmMachOp (MO_Add rep) [x, x2] + where + bits = fromIntegral (widthInBits rep) - 1 + shr = if p == 1 then MO_U_Shr rep else MO_S_Shr rep + x1 = CmmMachOp shr [x, CmmLit (CmmInt bits $ wordWidth platform)] + x2 = if p == 1 then x1 else + CmmMachOp (MO_And rep) [x1, CmmLit (CmmInt (n-1) rep)] -- ToDo (#7116): optimise floating-point multiplication, e.g. x*2.0 -> x+x -- Unfortunately this needs a unique supply because x might not be a @@ -448,533 +448,3 @@ That's what the constant-folding operations on comparison operators do above. isPicReg :: CmmExpr -> Bool isPicReg (CmmReg (CmmGlobal (GlobalRegUse PicBaseReg _))) = True isPicReg _ = False - -canOptimizeDivision :: CmmConfig -> Width -> Bool -canOptimizeDivision cfg rep = cmmOptConstDivision cfg && - -- we can either widen the arguments to simulate mul2 or use mul2 directly for the platform word size - (rep < wordWidth platform || (rep == wordWidth platform && cmmAllowMul2 cfg)) - where platform = cmmPlatform cfg - --- ----------------------------------------------------------------------------- --- Folding callish machops - -cmmCallishMachOpFold :: CallishMachOp -> [CmmFormal] -> [CmmActual] -> Opt (CmmNode O O) -cmmCallishMachOpFold op res args = - fromMaybe (CmmUnsafeForeignCall (PrimTarget op) res args) <$> (getConfig >>= \cfg -> cmmCallishMachOpFoldM cfg op res args) - -cmmCallishMachOpFoldM :: CmmConfig -> CallishMachOp -> [CmmFormal] -> [CmmActual] -> Opt (Maybe (CmmNode O O)) - --- If possible move the literals to the right, the following cases assume that to be the case -cmmCallishMachOpFoldM cfg op res [x@(CmmLit _),y] - | isCommutableCallishMachOp op && not (isLit y) = cmmCallishMachOpFoldM cfg op res [y,x] - --- Both arguments are literals, replace with the result -cmmCallishMachOpFoldM _ op res [CmmLit (CmmInt x _), CmmLit (CmmInt y _)] - = case op of - MO_S_Mul2 rep - | [rHiNeeded,rHi,rLo] <- res -> do - let resSz = widthInBits rep - resVal = (narrowS rep x) * (narrowS rep y) - high = resVal `shiftR` resSz - low = narrowS rep resVal - isHiNeeded = high /= low `shiftR` resSz - isHiNeededVal = if isHiNeeded then 1 else 0 - prependNode $! CmmAssign (CmmLocal rHiNeeded) (CmmLit $ CmmInt isHiNeededVal rep) - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt high rep) - pure . Just $! CmmAssign (CmmLocal rLo) (CmmLit $ CmmInt low rep) - MO_U_Mul2 rep - | [rHi,rLo] <- res -> do - let resSz = widthInBits rep - resVal = (narrowU rep x) * (narrowU rep y) - high = resVal `shiftR` resSz - low = narrowU rep resVal - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt high rep) - pure . Just $! CmmAssign (CmmLocal rLo) (CmmLit $ CmmInt low rep) - MO_S_QuotRem rep - | [rQuot, rRem] <- res, - y /= 0 -> do - let (q,r) = quotRem (narrowS rep x) (narrowS rep y) - prependNode $! CmmAssign (CmmLocal rQuot) (CmmLit $ CmmInt q rep) - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt r rep) - MO_U_QuotRem rep - | [rQuot, rRem] <- res, - y /= 0 -> do - let (q,r) = quotRem (narrowU rep x) (narrowU rep y) - prependNode $! CmmAssign (CmmLocal rQuot) (CmmLit $ CmmInt q rep) - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt r rep) - _ -> pure Nothing - --- 0, 1 or -1 as one of the constants - -cmmCallishMachOpFoldM _ op res [_, CmmLit (CmmInt 0 _)] - = case op of - -- x * 0 == 0 - MO_S_Mul2 rep - | [rHiNeeded, rHi, rLo] <- res -> do - prependNode $! CmmAssign (CmmLocal rHiNeeded) (CmmLit $ CmmInt 0 rep) - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rLo) (CmmLit $ CmmInt 0 rep) - -- x * 0 == 0 - MO_U_Mul2 rep - | [rHi, rLo] <- res -> do - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rLo) (CmmLit $ CmmInt 0 rep) - _ -> pure Nothing - -cmmCallishMachOpFoldM _ op res [CmmLit (CmmInt 0 _), _] - = case op of - -- 0 quotRem d == (0,0) - MO_S_QuotRem rep - | [rQuot, rRem] <- res -> do - prependNode $! CmmAssign (CmmLocal rQuot) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt 0 rep) - -- 0 quotRem d == (0,0) - MO_U_QuotRem rep - | [rQuot,rRem] <- res -> do - prependNode $! CmmAssign (CmmLocal rQuot) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt 0 rep) - _ -> pure Nothing - -cmmCallishMachOpFoldM cfg op res [x, CmmLit (CmmInt 1 _)] - = case op of - -- x * 1 == x -- Note: The high word needs to be a sign extension of the low word, so we use a sign extending shift - MO_S_Mul2 rep - | [rHiNeeded, rHi, rLo] <- res -> do - let platform = cmmPlatform cfg - wordRep = wordWidth platform - repInBits = toInteger $ widthInBits rep - prependNode $! CmmAssign (CmmLocal rHiNeeded) (CmmLit $ CmmInt 0 rep) - prependNode $! CmmAssign (CmmLocal rHi) (cmmMachOpFold platform (MO_S_Shr rep) [x, CmmLit $ CmmInt (repInBits - 1) wordRep]) - pure . Just $! CmmAssign (CmmLocal rLo) x - -- x * 1 == x - MO_U_Mul2 rep - | [rHi, rLo] <- res -> do - prependNode $! CmmAssign (CmmLocal rHi) (CmmLit $ CmmInt 0 rep) - pure . Just $! CmmAssign (CmmLocal rLo) x - -- x quotRem 1 == (x, 0) - MO_S_QuotRem rep - | [rQuot, rRem] <- res -> do - prependNode $! CmmAssign (CmmLocal rQuot) x - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt 0 rep) - -- x quotRem 1 == (x, 0) - MO_U_QuotRem rep - | [rQuot, rRem] <- res -> do - prependNode $! CmmAssign (CmmLocal rQuot) x - pure . Just $! CmmAssign (CmmLocal rRem) (CmmLit $ CmmInt 0 rep) - _ -> pure Nothing - --- handle quotRem with a constant divisor - -cmmCallishMachOpFoldM cfg op res [n, CmmLit (CmmInt d' _)] - = case op of - MO_S_QuotRem rep - | Just p <- exactLog2 d, - [rQuot,rRem] <- res -> do - n' <- intoRegister n (cmmBits rep) - -- first prepend the optimized division by a power 2 - prependNode $! CmmAssign (CmmLocal rQuot) - (cmmMachOpFold platform (MO_S_Shr rep) - [signedQuotRemHelper platform d n' rep p, CmmLit (CmmInt p $ wordWidth platform)]) - -- then output an optimized remainder by a power of 2 - pure . Just $! CmmAssign (CmmLocal rRem) - (cmmMachOpFold platform (MO_Sub rep) - [n', cmmMachOpFold platform (MO_And rep) - [signedQuotRemHelper platform d n' rep p, CmmLit (CmmInt (- d) rep)]]) - | canOptimizeDivision cfg rep, - d /= (-1), d /= 0, d /= 1, - [rQuot,rRem] <- res -> do - -- we are definitely going to use n multiple times, so put it into a register - n' <- intoRegister n (cmmBits rep) - -- generate an optimized (signed) division of n by d - q <- generateDivisionBySigned platform cfg rep n' d - -- we also need the result multiple times to calculate the remainder - q' <- intoRegister q (cmmBits rep) - - prependNode $! CmmAssign (CmmLocal rQuot) q' - -- The remainder now becomes n - q * d - pure . Just $! CmmAssign (CmmLocal rRem) $ CmmMachOp (MO_Sub rep) [n', CmmMachOp (MO_Mul rep) [q', CmmLit $ CmmInt d rep]] - where - platform = cmmPlatform cfg - d = narrowS rep d' - MO_U_QuotRem rep - | Just p <- exactLog2 d, - [rQuot,rRem] <- res -> do - -- first prepend the optimized division by a power 2 - prependNode $! CmmAssign (CmmLocal rQuot) $ CmmMachOp (MO_U_Shr rep) [n, CmmLit (CmmInt p $ wordWidth platform)] - -- then output an optimized remainder by a power of 2 - pure . Just $! CmmAssign (CmmLocal rRem) $ CmmMachOp (MO_And rep) [n, CmmLit (CmmInt (d - 1) rep)] - | canOptimizeDivision cfg rep, - d /= 0, d /= 1, - [rQuot,rRem] <- res -> do - -- we are definitely going to use n multiple times, so put it into a register - n' <- intoRegister n (cmmBits rep) - -- generate an optimized (unsigned) division of n by d - q <- generateDivisionByUnsigned platform cfg rep n' d - -- we also need the result multiple times to calculate the remainder - q' <- intoRegister q (cmmBits rep) - - prependNode $! CmmAssign (CmmLocal rQuot) q' - -- The remainder now becomes n - q * d - pure . Just $! CmmAssign (CmmLocal rRem) $ CmmMachOp (MO_Sub rep) [n', CmmMachOp (MO_Mul rep) [q', CmmLit $ CmmInt d rep]] - where - platform = cmmPlatform cfg - d = narrowU rep d' - _ -> pure Nothing - -cmmCallishMachOpFoldM _ _ _ _ = pure Nothing - --- ----------------------------------------------------------------------------- --- Specialized constant folding for MachOps which sometimes need to expand into multiple nodes - -cmmMachOpFoldOptM :: CmmConfig -> MachOp -> [CmmExpr] -> Opt (Maybe CmmExpr) - -cmmMachOpFoldOptM cfg op [n, CmmLit (CmmInt d' _)] = - case op of - MO_S_Quot rep - -- recheck for power of 2 division. This may not be handled by cmmMachOpFoldM if n is not in a register - | Just p <- exactLog2 d -> do - n' <- intoRegister n (cmmBits rep) - pure . Just $! cmmMachOpFold platform (MO_S_Shr rep) - [ signedQuotRemHelper platform d n' rep p - , CmmLit (CmmInt p $ wordWidth platform) - ] - | canOptimizeDivision cfg rep, - d /= (-1), d /= 0, d /= 1 -> Just <$!> generateDivisionBySigned platform cfg rep n d - where d = narrowS rep d' - MO_S_Rem rep - -- recheck for power of 2 remainder. This may not be handled by cmmMachOpFoldM if n is not in a register - | Just p <- exactLog2 d -> do - n' <- intoRegister n (cmmBits rep) - pure . Just $! cmmMachOpFold platform (MO_Sub rep) - [ n' - , cmmMachOpFold platform (MO_And rep) - [ signedQuotRemHelper platform d n' rep p - , CmmLit (CmmInt (- d) rep) - ] - ] - | canOptimizeDivision cfg rep, - d /= (-1), d /= 0, d /= 1 -> do - n' <- intoRegister n (cmmBits rep) - -- first generate the division - q <- generateDivisionBySigned platform cfg rep n' d - -- then calculate the remainder by n - q * d - pure . Just $! CmmMachOp (MO_Sub rep) [n', CmmMachOp (MO_Mul rep) [q, CmmLit $ CmmInt d rep]] - where d = narrowS rep d' - MO_U_Quot rep - -- No need to recheck power of 2 division because cmmMachOpFoldM always handles that case - | canOptimizeDivision cfg rep, - d /= 0, d /= 1, Nothing <- exactLog2 d -> Just <$!> generateDivisionByUnsigned platform cfg rep n d - where d = narrowU rep d' - MO_U_Rem rep - -- No need to recheck power of 2 remainder because cmmMachOpFoldM always handles that case - | canOptimizeDivision cfg rep, - d /= 0, d /= 1, Nothing <- exactLog2 d -> do - n' <- intoRegister n (cmmBits rep) - -- first generate the division - q <- generateDivisionByUnsigned platform cfg rep n d - -- then calculate the remainder by n - q * d - pure . Just $! CmmMachOp (MO_Sub rep) [n', CmmMachOp (MO_Mul rep) [q, CmmLit $ CmmInt d rep]] - where d = narrowU rep d' - _ -> pure Nothing - where platform = cmmPlatform cfg - -cmmMachOpFoldOptM _ _ _ = pure Nothing - --- ----------------------------------------------------------------------------- --- Utils for prepending new nodes - --- Move an expression into a register to possibly use it multiple times -intoRegister :: CmmExpr -> CmmType -> Opt CmmExpr -intoRegister e@(CmmReg _) _ = pure e -intoRegister expr ty = do - u <- getUniqueM - let reg = LocalReg u ty - CmmReg (CmmLocal reg) <$ prependNode (CmmAssign (CmmLocal reg) expr) - -prependNode :: CmmNode O O -> Opt () -prependNode n = Opt $ \_ xs -> pure (xs ++ [n], ()) - --- ----------------------------------------------------------------------------- --- Division by constants utils - --- Helper for division by a power of 2 --- In contrast with unsigned integers, for signed ones --- shift right is not the same as quot, because it rounds --- to minus infinity, whereas quot rounds toward zero. --- To fix this up, we add one less than the divisor to the --- dividend if it is a negative number. --- --- to avoid a test/jump, we use the following sequence: --- x1 = x >> word_size-1 (all 1s if -ve, all 0s if +ve) --- x2 = y & (divisor-1) --- result = x + x2 --- this could be done a bit more simply using conditional moves, --- but we're processor independent here. --- --- we optimize the divide by 2 case slightly, generating --- x1 = x >> word_size-1 (unsigned) --- return = x + x1 -signedQuotRemHelper :: Platform -> Integer -> CmmExpr -> Width -> Integer -> CmmExpr -signedQuotRemHelper platform n x rep p = CmmMachOp (MO_Add rep) [x, x2] - where - bits = fromIntegral (widthInBits rep) - 1 - shr = if p == 1 then MO_U_Shr rep else MO_S_Shr rep - x1 = CmmMachOp shr [x, CmmLit (CmmInt bits $ wordWidth platform)] - x2 = if p == 1 then x1 else - CmmMachOp (MO_And rep) [x1, CmmLit (CmmInt (n-1) rep)] - -{- Note: [Division by constants] - -Integer division is floor(n / d), the goal is to find m,p -such that floor((m * n) / 2^p) = floor(n / d). - -The idea being: n/d = n * (1/d). But we cannot store 1/d in an integer without -some error, so we choose some 2^p / d such that the error ends up small and -thus vanishes when we divide by 2^p again. - -The algorithm below to generate these numbers is taken from Hacker's Delight -Second Edition Chapter 10 "Integer division by constants". The chapter also -contains proof that this method does indeed produce correct results. - -However this is a much more literal interpretation of the algorithm, -which we can use because of the unbounded Integer type. Hacker's Delight -also provides a much more complex algorithm which computes these numbers -without the need to exceed the word size, but that is not necessary here. --} - -generateDivisionBySigned :: Platform -> CmmConfig -> Width -> CmmExpr -> Integer -> Opt CmmExpr - --- Sanity checks, division will generate incorrect results or undesirable code for these cases --- cmmMachOpFoldM and cmmMachOpFoldOptM should have already handled these cases! -generateDivisionBySigned _ _ _ _ 0 = panic "generate signed division with 0" -generateDivisionBySigned _ _ _ _ 1 = panic "generate signed division with 1" -generateDivisionBySigned _ _ _ _ (-1) = panic "generate signed division with -1" -generateDivisionBySigned _ _ _ _ d | Just _ <- exactLog2 d = panic $ "generate signed division with " ++ show d - -generateDivisionBySigned platform _cfg rep n divisor = do - -- We only duplicate n' if we actually need to add/subtract it, so we may not need it in a register - n' <- if sign == 0 then pure n else intoRegister n resRep - - -- Set up mul2 - (shift', qExpr) <- mul2 n' - - -- add/subtract n if necessary - let qExpr' = case sign of - 1 -> CmmMachOp (MO_Add rep) [qExpr, n'] - -1 -> CmmMachOp (MO_Sub rep) [qExpr, n'] - _ -> qExpr - - qExpr'' <- intoRegister (cmmMachOpFold platform (MO_S_Shr rep) [qExpr', CmmLit $ CmmInt shift' wordRep]) resRep - - -- Lastly add the sign of the quotient to correct for negative results - pure $! cmmMachOpFold platform - (MO_Add rep) [qExpr'', cmmMachOpFold platform (MO_U_Shr rep) [qExpr'', CmmLit $ CmmInt (toInteger $ widthInBits rep - 1) wordRep]] - where - resRep = cmmBits rep - wordRep = wordWidth platform - (magic, sign, shift) = divisionMagicS rep divisor - -- generate the multiply with the magic number - mul2 n - -- Using mul2 for sub-word sizes regresses for signed integers only - | rep == wordWidth platform = do - (r1, r2, r3) <- (,,) <$> getUniqueM <*> getUniqueM <*> getUniqueM - let rg1 = LocalReg r1 resRep - resReg = LocalReg r2 resRep - rg3 = LocalReg r3 resRep - res <- CmmReg (CmmLocal resReg) <$ prependNode (CmmUnsafeForeignCall (PrimTarget (MO_S_Mul2 rep)) [rg1, resReg, rg3] [n, CmmLit $ CmmInt magic rep]) - pure (shift, res) - -- widen the register and multiply without the MUL2 instruction - -- if we don't need an additional add after this we can combine the shifts - | otherwise = pure (if sign == 0 then 0 else shift, res) - where - wordRep = wordWidth platform - -- (n * magic) >> widthInBits + (if sign == 0 then shift else 0) -- With conversion in between to not overflow - res = cmmMachOpFold platform (MO_SS_Conv wordRep rep) - [ cmmMachOpFold platform (MO_S_Shr wordRep) - [ cmmMachOpFold platform (MO_Mul wordRep) - [ cmmMachOpFold platform (MO_SS_Conv rep wordRep) [n] - , CmmLit $ CmmInt magic wordRep - ] - -- Check if we need to generate an add/subtract later. If not we can combine this with the postshift - , CmmLit $ CmmInt ((if sign == 0 then toInteger shift else 0) + (toInteger $ widthInBits rep)) wordRep - ] - ] - --- See hackers delight for how and why this works (chapter in note [Division by constants]) -divisionMagicS :: Width -> Integer -> (Integer, Integer, Integer) -divisionMagicS rep divisor = (magic, sign, toInteger $ p - wSz) - where - sign = if divisor > 0 - then if magic < 0 then 1 else 0 - else if magic < 0 then 0 else -1 - wSz = widthInBits rep - ad = abs divisor - t = (1 `shiftL` (wSz - 1)) + if divisor > 0 then 0 else 1 - anc = t - 1 - rem t ad - go p' - | twoP > anc * (ad - rem twoP ad) = p' - | otherwise = go (p' + 1) - where twoP = 1 `shiftL` p' - p = go wSz - am = (twoP + ad - rem twoP ad) `quot` ad - where twoP = 1 `shiftL` p - magic = narrowS rep $ if divisor > 0 then am else -am - -generateDivisionByUnsigned :: Platform -> CmmConfig -> Width -> CmmExpr -> Integer -> Opt CmmExpr --- Sanity checks, division will generate incorrect results or undesirable code for these cases --- cmmMachOpFoldM and cmmMachOpFoldOptM should have already handled these cases! -generateDivisionByUnsigned _ _ _ _ 0 = panic "generate signed division with 0" -generateDivisionByUnsigned _ _ _ _ 1 = panic "generate signed division with 1" -generateDivisionByUnsigned _ _ _ _ d | Just _ <- exactLog2 d = panic $ "generate signed division with " ++ show d - -generateDivisionByUnsigned platform cfg rep n divisor = do - -- We only duplicate n' if we actually need to add/subtract it, so we may not need it in a register - n' <- if not needsAdd -- Invariant: We also never preshift if we need an add, thus we don't need n in a register - then pure $! cmmMachOpFold platform (MO_U_Shr rep) [n, CmmLit $ CmmInt preShift wordRep] - else intoRegister n resRep - - -- Set up mul2 - (postShift', qExpr) <- mul2 n' - - -- add/subtract n if necessary - let qExpr' = if needsAdd - -- This is qExpr + (n - qExpr) / 2 = (qExpr + n) / 2 but with a guarantee that it'll not overflow - then cmmMachOpFold platform (MO_Add rep) - [ cmmMachOpFold platform (MO_U_Shr rep) - [ cmmMachOpFold platform (MO_Sub rep) [n', qExpr] - , CmmLit $ CmmInt 1 wordRep - ] - , qExpr - ] - else qExpr - -- If we already divided by 2 in the add, remember to shift one bit less - -- Hacker's Delight, Edition 2 Page 234: postShift > 0 if we needed an add, except if the divisor - -- is 1, which we checked for above - finalShift = if needsAdd then postShift' - 1 else postShift' - - -- apply the final postShift - pure $! cmmMachOpFold platform (MO_U_Shr rep) [qExpr', CmmLit $ CmmInt finalShift wordRep] - where - resRep = cmmBits rep - wordRep = wordWidth platform - (preShift, magic, needsAdd, postShift) = - let withPre = divisionMagicU rep True divisor - noPre = divisionMagicU rep False divisor - in case (withPre, noPre) of - -- Use whatever does not cause us to take the expensive case - ((_, _, False, _), (_, _, True, _)) -> withPre - -- If we cannot avoid the expensive case, don't bother with the pre shift - _ -> noPre - -- generate the multiply with the magic number - mul2 n - | rep == wordWidth platform || (cmmAllowMul2 cfg && needsAdd) = do - (r1, r2) <- (,) <$> getUniqueM <*> getUniqueM - let rg1 = LocalReg r1 resRep - resReg = LocalReg r2 resRep - res <- CmmReg (CmmLocal resReg) <$ prependNode (CmmUnsafeForeignCall (PrimTarget (MO_U_Mul2 rep)) [resReg, rg1] [n, CmmLit $ CmmInt magic rep]) - pure (postShift, res) - | otherwise = do - pure (if needsAdd then postShift else 0, res) - where - wordRep = wordWidth platform - -- (n * magic) >> widthInBits + (if sign == 0 then shift else 0) -- With conversion in between to not overflow - res = cmmMachOpFold platform (MO_UU_Conv wordRep rep) - [ cmmMachOpFold platform (MO_U_Shr wordRep) - [ cmmMachOpFold platform (MO_Mul wordRep) - [ cmmMachOpFold platform (MO_UU_Conv rep wordRep) [n] - , CmmLit $ CmmInt magic wordRep - ] - -- Check if we need to generate an add later. If not we can combine this with the postshift - , CmmLit $ CmmInt ((if needsAdd then 0 else postShift) + (toInteger $ widthInBits rep)) wordRep - ] - ] - --- See hackers delight for how and why this works (chapter in note [Division by constants]) --- The preshift isn't described there, but the idea is: --- If a divisor d has n trailing zeros, then d is a multiple of 2^n. Since we want to divide x by d --- we can also calculate (x / 2^n) / (d / 2^n) which may then not require an extra addition. --- --- The addition performs: quotient + dividend, but we need to avoid overflows, so we actually need to --- calculate: quotient + (dividend - quotient) / 2 = (quotient + dividend) / 2 --- Thus if the preshift can avoid all of this, we have 1 operation in place of 3. --- --- The decision to use the preshift is made somewhere else, here we only report if the addition is needed -divisionMagicU :: Width -> Bool -> Integer -> (Integer, Integer, Bool, Integer) -divisionMagicU rep doPreShift divisor = (toInteger zeros, magic, needsAdd, toInteger $ p - wSz) - where - wSz = widthInBits rep - zeros = if doPreShift then countTrailingZeros $ fromInteger @Word64 divisor else 0 - d = divisor `shiftR` zeros - ones = ((1 `shiftL` wSz) - 1) `shiftR` zeros - nc = ones - rem (ones - d) d - go p' - | twoP > nc * (d - 1 - rem (twoP - 1) d) = p' - | otherwise = go (p' + 1) - where twoP = 1 `shiftL` p' - p = go wSz - m = (twoP + d - 1 - rem (twoP - 1) d) `quot` d - where twoP = 1 `shiftL` p - needsAdd = d < 1 `shiftL` (p - wSz) - magic = if needsAdd then m - (ones + 1) else m - --- ----------------------------------------------------------------------------- --- Opt monad - -newtype Opt a = OptI { runOptI :: CmmConfig -> [CmmNode O O] -> UniqDSM ([CmmNode O O], a) } - --- | Pattern synonym for 'Opt', as described in Note [The one-shot state --- monad trick]. -pattern Opt :: (CmmConfig -> [CmmNode O O] -> UniqDSM ([CmmNode O O], a)) -> Opt a -pattern Opt f <- OptI f - where Opt f = OptI . oneShot $ \cfg -> oneShot $ \out -> f cfg out -{-# COMPLETE Opt #-} - -runOpt :: CmmConfig -> Opt a -> UniqDSM ([CmmNode O O], a) -runOpt cf (Opt g) = g cf [] - -getConfig :: Opt CmmConfig -getConfig = Opt $ \cf xs -> pure (xs, cf) - -instance Functor Opt where - fmap f (Opt g) = Opt $ \cf xs -> fmap (fmap f) (g cf xs) - -instance Applicative Opt where - pure a = Opt $ \_ xs -> pure (xs, a) - ff <*> fa = do - f <- ff - f <$> fa - -instance Monad Opt where - Opt g >>= f = Opt $ \cf xs -> do - (ys, a) <- g cf xs - runOptI (f a) cf ys - -instance MonadGetUnique Opt where - getUniqueM = Opt $ \_ xs -> (xs,) <$> getUniqueDSM - -mapForeignTargetOpt :: (CmmExpr -> Opt CmmExpr) -> ForeignTarget -> Opt ForeignTarget -mapForeignTargetOpt exp (ForeignTarget e c) = flip ForeignTarget c <$> exp e -mapForeignTargetOpt _ m@(PrimTarget _) = pure m - -wrapRecExpOpt :: (CmmExpr -> Opt CmmExpr) -> CmmExpr -> Opt CmmExpr -wrapRecExpOpt f (CmmMachOp op es) = traverse (wrapRecExpOpt f) es >>= f . CmmMachOp op -wrapRecExpOpt f (CmmLoad addr ty align) = wrapRecExpOpt f addr >>= \newAddr -> f (CmmLoad newAddr ty align) -wrapRecExpOpt f e = f e - -mapExpOpt :: (CmmExpr -> Opt CmmExpr) -> CmmNode e x -> Opt (CmmNode e x) -mapExpOpt _ f@(CmmEntry{}) = pure f -mapExpOpt _ m@(CmmComment _) = pure m -mapExpOpt _ m@(CmmTick _) = pure m -mapExpOpt f (CmmUnwind regs) = CmmUnwind <$> traverse (traverse (traverse f)) regs -mapExpOpt f (CmmAssign r e) = CmmAssign r <$> f e -mapExpOpt f (CmmStore addr e align) = CmmStore <$> f addr <*> f e <*> pure align -mapExpOpt f (CmmUnsafeForeignCall tgt fs as) = CmmUnsafeForeignCall <$> mapForeignTargetOpt f tgt <*> pure fs <*> traverse f as -mapExpOpt _ l@(CmmBranch _) = pure l -mapExpOpt f (CmmCondBranch e ti fi l) = f e >>= \newE -> pure (CmmCondBranch newE ti fi l) -mapExpOpt f (CmmSwitch e ids) = flip CmmSwitch ids <$> f e -mapExpOpt f n at CmmCall {cml_target=tgt} = f tgt >>= \newTgt -> pure n{cml_target = newTgt} -mapExpOpt f (CmmForeignCall tgt fs as succ ret_args updfr intrbl) - = do - newTgt <- mapForeignTargetOpt f tgt - newAs <- traverse f as - pure $ CmmForeignCall newTgt fs newAs succ ret_args updfr intrbl ===================================== compiler/GHC/Cmm/Pipeline.hs ===================================== @@ -137,12 +137,9 @@ cpsTop logger platform cfg dus proc = dump Opt_D_dump_cmm_sp "Layout Stack" g ----------- Sink and inline assignments -------------------------------- - (g, dus) <- {-# SCC "sink" #-} -- See Note [Sinking after stack layout] - if cmmOptSink cfg - then pure $ runUniqueDSM dus $ cmmSink cfg g - else return (g, dus) - dump Opt_D_dump_cmm_sink "Sink assignments" g - + g <- {-# SCC "sink" #-} -- See Note [Sinking after stack layout] + condPass (cmmOptSink cfg) (cmmSink platform) g + Opt_D_dump_cmm_sink "Sink assignments" ------------- CAF analysis ---------------------------------------------- let cafEnv = {-# SCC "cafAnal" #-} cafAnal platform call_pps l g ===================================== compiler/GHC/Cmm/Sink.hs ===================================== @@ -20,8 +20,6 @@ import GHC.Platform.Regs import GHC.Platform import GHC.Types.Unique.FM -import GHC.Types.Unique.DSM -import GHC.Cmm.Config import Data.List (partition) import Data.Maybe @@ -152,10 +150,9 @@ type Assignments = [Assignment] -- y = e2 -- x = e1 -cmmSink :: CmmConfig -> CmmGraph -> UniqDSM CmmGraph -cmmSink cfg graph = ofBlockList (g_entry graph) <$> sink mapEmpty blocks +cmmSink :: Platform -> CmmGraph -> CmmGraph +cmmSink platform graph = ofBlockList (g_entry graph) $ sink mapEmpty $ blocks where - platform = cmmPlatform cfg liveness = cmmLocalLivenessL platform graph getLive l = mapFindWithDefault emptyLRegSet l liveness @@ -163,41 +160,11 @@ cmmSink cfg graph = ofBlockList (g_entry graph) <$> sink mapEmpty blocks join_pts = findJoinPoints blocks - sink :: LabelMap Assignments -> [CmmBlock] -> UniqDSM [CmmBlock] - sink _ [] = pure [] - sink sunk (b:bs) = do - -- Now sink and inline in this block - (prepend, last_fold) <- runOpt cfg $ constantFoldNode last - - (middle', assigs) <- walk cfg (ann_middles ++ annotate platform live_middle prepend) (mapFindWithDefault [] lbl sunk) - - let (final_last, assigs') = tryToInline platform live last_fold assigs - -- Now, drop any assignments that we will not sink any further. - (dropped_last, assigs'') = dropAssignments platform drop_if init_live_sets assigs' - drop_if :: (LocalReg, CmmExpr, AbsMem) - -> [LRegSet] -> (Bool, [LRegSet]) - drop_if a@(r,rhs,_) live_sets = (should_drop, live_sets') - where - should_drop = conflicts platform a final_last - || not (isTrivial platform rhs) && live_in_multi live_sets r - || r `elemLRegSet` live_in_joins - - live_sets' | should_drop = live_sets - | otherwise = map upd live_sets - - upd set | r `elemLRegSet` set = set `unionLRegSet` live_rhs - | otherwise = set - - live_rhs = foldRegsUsed platform (flip insertLRegSet) emptyLRegSet rhs - - final_middle = foldl' blockSnoc middle' dropped_last - - sunk' = mapUnion sunk $ - mapFromList [ (l, filterAssignments platform (getLive l) assigs'') - | l <- succs ] - - (blockJoin first final_middle final_last :) <$> sink sunk' bs - + sink :: LabelMap Assignments -> [CmmBlock] -> [CmmBlock] + sink _ [] = [] + sink sunk (b:bs) = + -- pprTrace "sink" (ppr lbl) $ + blockJoin first final_middle final_last : sink sunk' bs where lbl = entryLabel b (first, middle, last) = blockSplit b @@ -211,6 +178,11 @@ cmmSink cfg graph = ofBlockList (g_entry graph) <$> sink mapEmpty blocks live_middle = gen_killL platform last live ann_middles = annotate platform live_middle (blockToList middle) + -- Now sink and inline in this block + (middle', assigs) = walk platform ann_middles (mapFindWithDefault [] lbl sunk) + fold_last = constantFoldNode platform last + (final_last, assigs') = tryToInline platform live fold_last assigs + -- We cannot sink into join points (successors with more than -- one predecessor), so identify the join points and the set -- of registers live in them. @@ -228,6 +200,31 @@ cmmSink cfg graph = ofBlockList (g_entry graph) <$> sink mapEmpty blocks (_one:_two:_) -> True _ -> False + -- Now, drop any assignments that we will not sink any further. + (dropped_last, assigs'') = dropAssignments platform drop_if init_live_sets assigs' + + drop_if :: (LocalReg, CmmExpr, AbsMem) + -> [LRegSet] -> (Bool, [LRegSet]) + drop_if a@(r,rhs,_) live_sets = (should_drop, live_sets') + where + should_drop = conflicts platform a final_last + || not (isTrivial platform rhs) && live_in_multi live_sets r + || r `elemLRegSet` live_in_joins + + live_sets' | should_drop = live_sets + | otherwise = map upd live_sets + + upd set | r `elemLRegSet` set = set `unionLRegSet` live_rhs + | otherwise = set + + live_rhs = foldRegsUsed platform (flip insertLRegSet) emptyLRegSet rhs + + final_middle = foldl' blockSnoc middle' dropped_last + + sunk' = mapUnion sunk $ + mapFromList [ (l, filterAssignments platform (getLive l) assigs'') + | l <- succs ] + {- TODO: enable this later, when we have some good tests in place to measure the effect and tune it. @@ -302,7 +299,7 @@ filterAssignments platform live assigs = reverse (go assigs []) -- * a list of assignments that will be placed *after* that block. -- -walk :: CmmConfig +walk :: Platform -> [(LRegSet, CmmNode O O)] -- nodes of the block, annotated with -- the set of registers live *after* -- this node. @@ -312,39 +309,36 @@ walk :: CmmConfig -- Earlier assignments may refer -- to later ones. - -> UniqDSM ( Block CmmNode O O -- The new block - , Assignments -- Assignments to sink further - ) + -> ( Block CmmNode O O -- The new block + , Assignments -- Assignments to sink further + ) -walk cfg nodes assigs = go nodes emptyBlock assigs +walk platform nodes assigs = go nodes emptyBlock assigs where - platform = cmmPlatform cfg - go [] block as = pure (block, as) + go [] block as = (block, as) go ((live,node):ns) block as -- discard nodes representing dead assignment | shouldDiscard node live = go ns block as - | otherwise = do - (prepend, node1) <- runOpt cfg $ constantFoldNode node - if not (null prepend) - then go (annotate platform live (prepend ++ [node1]) ++ ns) block as - else do - let -- Inline assignments - (node2, as1) = tryToInline platform live node1 as - -- Drop any earlier assignments conflicting with node2 - (dropped, as') = dropAssignmentsSimple platform - (\a -> conflicts platform a node2) as1 - -- Walk over the rest of the block. Includes dropped assignments - block' = foldl' blockSnoc block dropped `blockSnoc` node2 - - (prepend2, node3) <- runOpt cfg $ constantFoldNode node2 - if | not (null prepend2) -> go (annotate platform live (prepend2 ++ [node3]) ++ ns) block as - -- sometimes only after simplification we can tell we can discard the node. - -- See Note [Discard simplified nodes] - | noOpAssignment node3 -> go ns block as - -- Pick up interesting assignments - | Just a <- shouldSink platform node3 -> go ns block (a : as1) - -- Try inlining, drop assignments and move on - | otherwise -> go ns block' as' + -- sometimes only after simplification we can tell we can discard the node. + -- See Note [Discard simplified nodes] + | noOpAssignment node2 = go ns block as + -- Pick up interesting assignments + | Just a <- shouldSink platform node2 = go ns block (a : as1) + -- Try inlining, drop assignments and move on + | otherwise = go ns block' as' + where + -- Simplify node + node1 = constantFoldNode platform node + + -- Inline assignments + (node2, as1) = tryToInline platform live node1 as + + -- Drop any earlier assignments conflicting with node2 + (dropped, as') = dropAssignmentsSimple platform + (\a -> conflicts platform a node2) as1 + + -- Walk over the rest of the block. Includes dropped assignments + block' = foldl' blockSnoc block dropped `blockSnoc` node2 {- Note [Discard simplified nodes] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Driver/Config/Cmm.hs ===================================== @@ -24,17 +24,5 @@ initCmmConfig dflags = CmmConfig , cmmDoCmmSwitchPlans = not (backendHasNativeSwitch (backend dflags)) , cmmSplitProcPoints = not (backendSupportsUnsplitProcPoints (backend dflags)) || not (platformTablesNextToCode platform) - , cmmAllowMul2 = (ncg && x86ish) || llvm - , cmmOptConstDivision = not llvm } where platform = targetPlatform dflags - -- Copied from StgToCmm - (ncg, llvm) = case backendPrimitiveImplementation (backend dflags) of - GenericPrimitives -> (False, False) - NcgPrimitives -> (True, False) - LlvmPrimitives -> (False, True) - JSPrimitives -> (False, False) - x86ish = case platformArch platform of - ArchX86 -> True - ArchX86_64 -> True - _ -> False ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -1571,28 +1571,28 @@ emitPrimOp cfg primop = CastDoubleToWord64Op -> translateBitcasts (MO_FW_Bitcast W64) CastWord64ToDoubleOp -> translateBitcasts (MO_WF_Bitcast W64) - IntQuotRemOp -> opCallishHandledLater $ - if allowQuotRem + IntQuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_S_QuotRem (wordWidth platform)) else Right (genericIntQuotRemOp (wordWidth platform)) - Int8QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Int8QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_S_QuotRem W8) else Right (genericIntQuotRemOp W8) - Int16QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Int16QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_S_QuotRem W16) else Right (genericIntQuotRemOp W16) - Int32QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Int32QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_S_QuotRem W32) else Right (genericIntQuotRemOp W32) - WordQuotRemOp -> opCallishHandledLater $ - if allowQuotRem + WordQuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_U_QuotRem (wordWidth platform)) else Right (genericWordQuotRemOp (wordWidth platform)) @@ -1601,18 +1601,18 @@ emitPrimOp cfg primop = then Left (MO_U_QuotRem2 (wordWidth platform)) else Right (genericWordQuotRem2Op platform) - Word8QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Word8QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_U_QuotRem W8) else Right (genericWordQuotRemOp W8) - Word16QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Word16QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_U_QuotRem W16) else Right (genericWordQuotRemOp W16) - Word32QuotRemOp -> opCallishHandledLater $ - if allowQuotRem + Word32QuotRemOp -> \args -> flip opCallishHandledLater args $ + if allowQuotRem && not (quotRemCanBeOptimized args) then Left (MO_U_QuotRem W32) else Right (genericWordQuotRemOp W32) @@ -1835,6 +1835,23 @@ emitPrimOp cfg primop = pure $ map (CmmReg . CmmLocal) regs alwaysExternal = \_ -> PrimopCmmEmit_External + -- Note [QuotRem optimization] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- `quot` and `rem` with constant divisor can be implemented with fast bit-ops + -- (shift, .&.). + -- + -- Currently we only support optimization (performed in GHC.Cmm.Opt) when the + -- constant is a power of 2. #9041 tracks the implementation of the general + -- optimization. + -- + -- `quotRem` can be optimized in the same way. However as it returns two values, + -- it is implemented as a "callish" primop which is harder to match and + -- to transform later on. For simplicity, the current implementation detects cases + -- that can be optimized (see `quotRemCanBeOptimized`) and converts STG quotRem + -- primop into two CMM quot and rem primops. + quotRemCanBeOptimized = \case + [_, CmmLit (CmmInt n _) ] -> isJust (exactLog2 n) + _ -> False allowQuotRem = stgToCmmAllowQuotRemInstr cfg allowQuotRem2 = stgToCmmAllowQuotRem2 cfg ===================================== testsuite/tests/numeric/should_run/T25653.hs ===================================== @@ -0,0 +1,10 @@ +module Main (main) where + +import Data.Word (Word8) + +myMod :: Word8 -> Word8 +myMod i = mod i 7 +{-# NOINLINE myMod #-} + +main :: IO () +main = print $ myMod 5 ===================================== testsuite/tests/numeric/should_run/T25653.stdout ===================================== @@ -0,0 +1 @@ +5 ===================================== testsuite/tests/numeric/should_run/all.T ===================================== @@ -86,3 +86,4 @@ test('foundation', [when(js_arch(), run_timeout_multiplier(2)), js_fragile(24259 test('T24066', normal, compile_and_run, ['']) test('div01', normal, compile_and_run, ['']) test('T24245', normal, compile_and_run, ['']) +test('T25653', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bf4f5ad31ddeb87baad10de47f84081648f808dc...163aa50aad7a24912c5cc0ade3ef80b108e99f1a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bf4f5ad31ddeb87baad10de47f84081648f808dc...163aa50aad7a24912c5cc0ade3ef80b108e99f1a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 08:04:08 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 20 Jan 2025 03:04:08 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25657 Message-ID: <678e0378a55da_1e1db6132417c99689@gitlab.mail> Simon Peyton Jones pushed new branch wip/T25657 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25657 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 08:29:18 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 20 Jan 2025 03:29:18 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] 15 commits: Generalise GHC diagnostic code infrastructure Message-ID: <678e095e3f55a_1e1db619268901072e3@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 64d03998 by Patrick at 2025-01-20T08:29:14+00:00 update kcConDecl to also consider the result type in newtype GADT instance - - - - - 1a83d4bd by Patrick at 2025-01-20T08:29:14+00:00 peek at the result kind - - - - - 0fa4448b by Patrick at 2025-01-20T08:29:14+00:00 test if gadt has UserSuppliedResultKind in lhs, we let tc_res_kind to unify with rhs result kind if not to gain more inference - - - - - 5ce5771c by Patrick at 2025-01-20T08:29:14+00:00 format and remove getTyConResultKind - - - - - bc161de8 by Patrick at 2025-01-20T08:29:14+00:00 format - - - - - 3f5adde9 by Patrick at 2025-01-20T08:29:14+00:00 add comment - - - - - 1975e48a by Patrick at 2025-01-20T08:29:14+00:00 cleanup - - - - - 18b253a5 by Patrick at 2025-01-20T08:29:14+00:00 cleanup - - - - - e98fb6d0 by Patrick at 2025-01-20T08:29:14+00:00 update T25611a - - - - - 30 changed files: - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Ppr.hs - compiler/GHC/HsToCore/Errors/Ppr.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Iface/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/Errors/Types.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Types/Error.hs - compiler/GHC/Types/Error/Codes.hs - docs/users_guide/9.14.1-notes.rst - ghc/GHCi/UI.hs - ghc/GHCi/UI/Exception.hs - ghc/GHCi/UI/Info.hs - ghc/GHCi/UI/Monad.hs - + ghc/GHCi/UI/Print.hs - ghc/ghc-bin.cabal.in The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6b7b1166491f48a5c8cdb12dc7e043189a07da0a...e98fb6d06af7496f1903d8cc48e52d4fc5b5dde1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6b7b1166491f48a5c8cdb12dc7e043189a07da0a...e98fb6d06af7496f1903d8cc48e52d4fc5b5dde1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 08:57:15 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 20 Jan 2025 03:57:15 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] rename and add note Message-ID: <678e0feb3e4c_2c77a74d6b4c6407d@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 370ccc3e by Patrick at 2025-01-20T16:56:59+08:00 rename and add note - - - - - 2 changed files: - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -14,7 +14,7 @@ -- | Typecheck type and class declarations module GHC.Tc.TyCl ( - LHSUserSuppliedResultKind(..), + UserHeaderKindSig(..), tcTyAndClassDecls, -- Functions used by GHC.Tc.TyCl.Instance to check -- data/type family instance declarations @@ -1775,8 +1775,8 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name) do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt ; kcConDecls (tyConResKind tycon) (if (isJust kindSig) - then LHSUserSuppliedResultKind - else NoLHSUserSuppliedResultKind) cons + then UserHeaderKindSig + else NoUserHeaderKindSig) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1836,14 +1836,21 @@ kcConGADTArgs exp_kind con_args = case con_args of RecConGADT _ (L _ flds) -> kcConArgTys exp_kind $ map (hsLinear . cd_fld_type . unLoc) flds --- Specifically for GADT style declarations --- do we have lhs user supplied kind signature? --- as in `data xxx :: UserSuppliedKind where ...` -data LHSUserSuppliedResultKind = LHSUserSuppliedResultKind | NoLHSUserSuppliedResultKind deriving Eq + +{- Note [Header kind signatures for GADTs] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Specifically for GADT style declarations +Do we have user supplied header kind signature? +as in `data xxx :: UserHeaderKindSig where ...` +If not and it is newtype we can infer the kind of the data type +from the data constructors +-} +-- see Note [Header kind signatures for GADTs] +data UserHeaderKindSig = UserHeaderKindSig | NoUserHeaderKindSig deriving Eq kcConDecls :: TcKind -- Result kind of tycon -- Used only in H98 case - -> LHSUserSuppliedResultKind + -> UserHeaderKindSig -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] kcConDecls tc_res_kind usrk cons @@ -1856,7 +1863,7 @@ kcConDecls tc_res_kind usrk cons -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData -> LHSUserSuppliedResultKind -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl :: NewOrData -> UserHeaderKindSig -> TcKind -> ConDecl GhcRn -> TcM () kcConDecl new_or_data _usrk tc_res_kind (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs , con_mb_cxt = ex_ctxt, con_args = args }) @@ -1886,7 +1893,7 @@ kcConDecl new_or_data usrk tc_res_kind -- Why "_Tv"? See Note [Using TyVarTvs for kind-checking GADTs] do { _ <- tcHsContext cxt ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty $$ ppr tc_res_kind) - ; con_res_kind <- if NewType == new_or_data && NoLHSUserSuppliedResultKind == usrk + ; con_res_kind <- if NewType == new_or_data && NoUserHeaderKindSig == usrk then return tc_res_kind else newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty $ (TheKind con_res_kind) ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -947,8 +947,8 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Fix #25611 -- See DESIGN CHOICE in Note [Kind inference for data family instances] ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind (if (isJust m_ksig) - then LHSUserSuppliedResultKind - else NoLHSUserSuppliedResultKind) + then UserHeaderKindSig + else NoUserHeaderKindSig) hs_cons View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/370ccc3e1a4fec17f1046b1e89f9c4e7e05f7f28 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/370ccc3e1a4fec17f1046b1e89f9c4e7e05f7f28 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 08:59:35 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 20 Jan 2025 03:59:35 -0500 Subject: [Git][ghc/ghc][wip/T25657] Wibble Message-ID: <678e107732d54_2c77a77c1d5c67832@gitlab.mail> Simon Peyton Jones pushed to branch wip/T25657 at Glasgow Haskell Compiler / GHC Commits: 165c93bf by Simon Peyton Jones at 2025-01-20T08:59:23+00:00 Wibble - - - - - 1 changed file: - compiler/GHC/Core/FamInstEnv.hs Changes: ===================================== compiler/GHC/Core/FamInstEnv.hs ===================================== @@ -1228,10 +1228,10 @@ findBranch branches target_tys -> Maybe (BranchIndex, [Type], [Coercion]) go (index, branch) other = let (CoAxBranch { cab_tvs = tpl_tvs, cab_cvs = tpl_cvs - , cab_lhs = tpl_lhs - , cab_incomps = incomps }) = branch - in_scope = mkInScopeSet (unionVarSets $ - map (tyCoVarsOfTypes . coAxBranchLHS) incomps) +-- , cab_incomps = incomps + , cab_lhs = tpl_lhs }) = branch +-- in_scope = mkInScopeSet (unionVarSets $ +-- map (tyCoVarsOfTypes . coAxBranchLHS) incomps) -- See Note [Flattening type-family applications when matching instances] -- in GHC.Core.Unify -- flattened_target = flattenTys in_scope target_tys View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/165c93bfba2388df16dffe19a51d2d7b171d3bd3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/165c93bfba2388df16dffe19a51d2d7b171d3bd3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 09:19:47 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Mon, 20 Jan 2025 04:19:47 -0500 Subject: [Git][ghc/ghc][wip/T25657] Wibble Message-ID: <678e1533dbf2_3020f32af134265cb@gitlab.mail> Simon Peyton Jones pushed to branch wip/T25657 at Glasgow Haskell Compiler / GHC Commits: f94b5a22 by Simon Peyton Jones at 2025-01-20T09:19:33+00:00 Wibble - - - - - 1 changed file: - compiler/GHC/Core/Lint.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -2782,8 +2782,8 @@ lintBranch this_co fam_tc branch arg_kinds subst = zipTvSubst tvs tys `composeTCvSubst` zipCvSubst cvs co_args target = Type.substTys subst (coAxBranchLHS branch) - in_scope = mkInScopeSet $ - unionVarSets (map (tyCoVarsOfTypes . coAxBranchLHS) incomps) +-- in_scope = mkInScopeSet $ +-- unionVarSets (map (tyCoVarsOfTypes . coAxBranchLHS) incomps) -- flattened_target = flattenTys in_scope target check_no_conflict :: [Type] -> [CoAxBranch] -> Maybe CoAxBranch View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f94b5a22a94aa536a1f52c0a105e60bbf0469cc3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f94b5a22a94aa536a1f52c0a105e60bbf0469cc3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 10:02:25 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 20 Jan 2025 05:02:25 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] 25 commits: warnings: Find out if a qualified name is in the interactive scope directly Message-ID: <678e1f3125f4c_328bb75a0a8c41833@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - ea25a9ae by Matthew Pickering at 2025-01-20T10:02:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 30 changed files: - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Ppr.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Errors/Ppr.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Iface/Errors/Ppr.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec787af64ebe0782cc2db5c1093745737ea6c76f...ea25a9ae47b1a51475f55437fe67a20e09087593 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec787af64ebe0782cc2db5c1093745737ea6c76f...ea25a9ae47b1a51475f55437fe67a20e09087593 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 10:41:56 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Mon, 20 Jan 2025 05:41:56 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/fix-hie-yaml Message-ID: <678e287493fa1_328bb7bb80a047127@gitlab.mail> Cheng Shao pushed new branch wip/fix-hie-yaml at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fix-hie-yaml You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 11:23:21 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Mon, 20 Jan 2025 06:23:21 -0500 Subject: [Git][ghc/ghc][wip/mpickering/get-link-deps] driver: Store an ExternalModuleGraph in the EPS Message-ID: <678e3229d38ea_3a06705c44f095350@gitlab.mail> Matthew Pickering pushed to branch wip/mpickering/get-link-deps at Glasgow Haskell Compiler / GHC Commits: 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Unit/External.hs - + compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/Graph.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr - testsuite/tests/backpack/should_compile/bkp61.stderr - testsuite/tests/backpack/should_fail/bkpfail07.stderr - testsuite/tests/backpack/should_fail/bkpfail09.stderr - testsuite/tests/backpack/should_fail/bkpfail12.stderr - testsuite/tests/backpack/should_fail/bkpfail13.stderr - testsuite/tests/backpack/should_fail/bkpfail14.stderr - testsuite/tests/backpack/should_fail/bkpfail15.stderr - testsuite/tests/backpack/should_fail/bkpfail21.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44778963fff5d8cc5a58f572ea26e3ab6b287f76 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44778963fff5d8cc5a58f572ea26e3ab6b287f76 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 11:29:48 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 20 Jan 2025 06:29:48 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] 21 commits: Add flags for switching off speculative evaluation. Message-ID: <678e33acda84a_3a06708cf528959c2@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - ea25a9ae by Matthew Pickering at 2025-01-20T10:02:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 44d1d344 by Rodrigo Mesquita at 2025-01-20T11:29:36+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Ppr.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Decls.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7abb46d6586934ced5a43c49d18a6b8d7b24d5fa...44d1d344f41782e85d6ecd97a4b0da62bb7ef930 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7abb46d6586934ced5a43c49d18a6b8d7b24d5fa...44d1d344f41782e85d6ecd97a4b0da62bb7ef930 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 13:06:29 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 20 Jan 2025 08:06:29 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] driver: Store the HomePackageTable in a mutable reference Message-ID: <678e4a55371b3_3119829223c52345@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: f46b55c3 by Rodrigo Mesquita at 2025-01-20T13:06:19+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f46b55c33689b53282a815236cd04208d2f83925 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f46b55c33689b53282a815236cd04208d2f83925 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 13:32:35 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 20 Jan 2025 08:32:35 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Revert "Division by constants optimization" Message-ID: <678e50739cff7_31198920c70546d4@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 0d161a57 by Cheng Shao at 2025-01-20T08:32:27-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 30 changed files: - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/Unit/External.hs - + compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/Graph.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - hie.yaml - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/014b619f9d23c7911845a908763d8388a018d690...0d161a577fd9116ea029cebf4ef60af28f98b508 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/014b619f9d23c7911845a908763d8388a018d690...0d161a577fd9116ea029cebf4ef60af28f98b508 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 14:32:54 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Mon, 20 Jan 2025 09:32:54 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] driver: Store the HomePackageTable in a mutable reference Message-ID: <678e5e965ad10_a85de573000811@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: d6410d63 by Rodrigo Mesquita at 2025-01-20T14:31:59+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d6410d636a142c4539afaaa7b77ccd8cd35ff6a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d6410d636a142c4539afaaa7b77ccd8cd35ff6a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 16:53:02 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 20 Jan 2025 11:53:02 -0500 Subject: [Git][ghc/ghc][master] driver: Store an ExternalModuleGraph in the EPS Message-ID: <678e7f6e8a3d4_14efdd90c2984381a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 30 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Unit/External.hs - + compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/Graph.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr - testsuite/tests/backpack/should_compile/bkp61.stderr - testsuite/tests/backpack/should_fail/bkpfail07.stderr - testsuite/tests/backpack/should_fail/bkpfail09.stderr - testsuite/tests/backpack/should_fail/bkpfail12.stderr - testsuite/tests/backpack/should_fail/bkpfail13.stderr - testsuite/tests/backpack/should_fail/bkpfail14.stderr - testsuite/tests/backpack/should_fail/bkpfail15.stderr - testsuite/tests/backpack/should_fail/bkpfail21.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44778963fff5d8cc5a58f572ea26e3ab6b287f76 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/44778963fff5d8cc5a58f572ea26e3ab6b287f76 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 16:53:40 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 20 Jan 2025 11:53:40 -0500 Subject: [Git][ghc/ghc][master] hie: fix hie.yaml to use default hie-bios script Message-ID: <678e7f947bf61_14efdd95685c470a6@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 1 changed file: - hie.yaml Changes: ===================================== hie.yaml ===================================== @@ -5,4 +5,4 @@ # cradle: {bios: {program: "./hadrian/hie-bios.bat"}} # # The format is documented here - https://github.com/mpickering/hie-bios -cradle: {bios: {program: "./hadrian/hie-bios.bat"}} +cradle: {bios: {program: "./hadrian/hie-bios"}} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3c0acfc4b2e99ca01923d25ab9209fe9d21016c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3c0acfc4b2e99ca01923d25ab9209fe9d21016c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 18:52:25 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Mon, 20 Jan 2025 13:52:25 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] 12 commits: driver: Store an ExternalModuleGraph in the EPS Message-ID: <678e9b691d54f_1fe92487d99473881@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 1ef54f86 by Patrick at 2025-01-20T18:52:22+00:00 update kcConDecl to also consider the result type in newtype GADT instance - - - - - f53f514f by Patrick at 2025-01-20T18:52:22+00:00 peek at the result kind - - - - - 4bc78319 by Patrick at 2025-01-20T18:52:22+00:00 test if gadt has UserSuppliedResultKind in lhs, we let tc_res_kind to unify with rhs result kind if not to gain more inference - - - - - 879894ca by Patrick at 2025-01-20T18:52:22+00:00 format and remove getTyConResultKind - - - - - f92cb619 by Patrick at 2025-01-20T18:52:22+00:00 format - - - - - 744c6d52 by Patrick at 2025-01-20T18:52:22+00:00 add comment - - - - - 7cc65698 by Patrick at 2025-01-20T18:52:22+00:00 cleanup - - - - - 18c9c462 by Patrick at 2025-01-20T18:52:22+00:00 cleanup - - - - - a6c0ed8f by Patrick at 2025-01-20T18:52:22+00:00 update T25611a - - - - - 1cdef684 by Patrick at 2025-01-20T18:52:22+00:00 rename and add note - - - - - 30 changed files: - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs - compiler/GHC/Unit/External.hs - + compiler/GHC/Unit/Module/External/Graph.hs - compiler/GHC/Unit/Module/Graph.hs - + compiler/GHC/Unit/Module/ModNodeKey.hs - compiler/ghc.cabal.in - hie.yaml - testsuite/tests/backpack/reexport/bkpreex02.stderr - testsuite/tests/backpack/reexport/bkpreex03.stdout - testsuite/tests/backpack/should_compile/bkp09.stderr - testsuite/tests/backpack/should_compile/bkp14.stderr - testsuite/tests/backpack/should_compile/bkp15.stderr - testsuite/tests/backpack/should_compile/bkp31.stderr - testsuite/tests/backpack/should_compile/bkp32.stderr - testsuite/tests/backpack/should_compile/bkp47.stderr - testsuite/tests/backpack/should_compile/bkp51.stderr - testsuite/tests/backpack/should_compile/bkp61.stderr - testsuite/tests/backpack/should_fail/bkpfail07.stderr - testsuite/tests/backpack/should_fail/bkpfail09.stderr - testsuite/tests/backpack/should_fail/bkpfail12.stderr - testsuite/tests/backpack/should_fail/bkpfail13.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/370ccc3e1a4fec17f1046b1e89f9c4e7e05f7f28...1cdef6841ac7d3ce7753df7125f70e5e509f3b5f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/370ccc3e1a4fec17f1046b1e89f9c4e7e05f7f28...1cdef6841ac7d3ce7753df7125f70e5e509f3b5f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 20 21:39:40 2025 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Mon, 20 Jan 2025 16:39:40 -0500 Subject: [Git][ghc/ghc][wip/int-index/list-tuple-cleanup] 570 commits: git: remove a.out and include it in .gitignore Message-ID: <678ec29c600c5_2fa5b6c0b0c174e3@gitlab.mail> Vladislav Zavialov pushed to branch wip/int-index/list-tuple-cleanup at Glasgow Haskell Compiler / GHC Commits: f0408eeb by Cheng Shao at 2024-08-23T10:37:10-04:00 git: remove a.out and include it in .gitignore a.out is a configure script byproduct. It was mistakenly checked into the tree in !13118. This patch removes it, and include it in .gitignore to prevent a similar error in the future. - - - - - 1f95c5e4 by Matthew Pickering at 2024-08-23T10:37:46-04:00 docs: Fix code-block syntax on old sphinx version This code-block directive breaks the deb9 sphinx build. Fixes #25201 - - - - - 27dceb42 by Sylvain Henry at 2024-08-26T11:05:11-04:00 JS: add basic support for POSIX *at functions (#25190) openat/fstatat/unlinkat/dup are now used in the recent release of the `directory` and `file-io` packages. As such, these functions are (indirectly) used in the following tests one we'll bump the `directory` submodule (see !13122): - openFile008 - jsOptimizer - T20509 - bkpcabal02 - bkpcabal03 - bkpcabal04 - - - - - c68be356 by Matthew Pickering at 2024-08-26T11:05:11-04:00 Update directory submodule to latest master The primary reason for this bump is to fix the warning from `ghc-pkg check`: ``` Warning: include-dirs: /data/home/ubuntu/.ghcup/ghc/9.6.2/lib/ghc-9.6.2/lib/../lib/aarch64-linux-ghc-9.6.2/directory-1.3.8.1/include doesn't exist or isn't a directory ``` This also requires adding the `file-io` package as a boot library (which is discussed in #25145) Fixes #23594 #25145 - - - - - 4ee094d4 by Matthew Pickering at 2024-08-26T11:05:47-04:00 Fix aarch64-alpine target platform description We are producing bindists where the target triple is aarch64-alpine-linux when it should be aarch64-unknown-linux This is because the bootstrapped compiler originally set the target triple to `aarch64-alpine-linux` which is when propagated forwards by setting `bootstrap_target` from the bootstrap compiler target. In order to break this chain we explicitly specify build/host/target for aarch64-alpine. This requires a new configure flag `--enable-ignore-` which just switches off a validation check that the target platform of the bootstrap compiler is the same as the build platform. It is the same, but the name is just wrong. These commits can be removed when the bootstrap compiler has the correct target triple (I looked into patching this on ci-images, but it looked hard to do correctly as the build/host platform is not in the settings file). Fixes #25200 - - - - - e0e0f2b2 by Matthew Pickering at 2024-08-26T11:05:47-04:00 Bump nixpkgs commit for gen_ci script - - - - - 63a27091 by doyougnu at 2024-08-26T20:39:30-04:00 rts: win32: emit additional debugging information -- migration from haskell.nix - - - - - aaab3d10 by Vladislav Zavialov at 2024-08-26T20:40:06-04:00 Only export defaults when NamedDefaults are enabled (#25206) This is a reinterpretation of GHC Proposal #409 that avoids a breaking change introduced in fa0dbaca6c "Implements the Exportable Named Default proposal" Consider a module M that has no explicit export list: module M where default (Rational) Should it export the default (Rational)? The proposal says "yes", and there's a test case for that: default/DefaultImport04.hs However, as it turns out, this change in behavior breaks existing programs, e.g. the colour-2.3.6 package can no longer be compiled, as reported in #25206. In this patch, we make implicit exports of defaults conditional on the NamedDefaults extension. This fix is unintrusive and compliant with the existing proposal text (i.e. it does not require a proposal amendment). Should the proposal be amended, we can go for a simpler solution, such as requiring all defaults to be exported explicitly. Test case: testsuite/tests/default/T25206.hs - - - - - 3a5bebf8 by Matthew Pickering at 2024-08-28T14:16:42-04:00 simplifier: Fix space leak during demand analysis The lazy structure (a list) in a strict field in `DmdType` is not fully forced which leads to a very large thunk build-up. It seems there is likely still more work to be done here as it seems we may be trading space usage for work done. For now, this is the right choice as rather than using all the memory on my computer, compilation just takes a little bit longer. See #25196 - - - - - c2525e9e by Ryan Scott at 2024-08-28T14:17:17-04:00 Add missing parenthesizeHsType in cvtp's InvisP case We need to ensure that when we convert an `InvisP` (invisible type pattern) to a `Pat`, we parenthesize it (at precedence `appPrec`) so that patterns such as `@(a :: k)` will parse correctly when roundtripped back through the parser. Fixes #25209. - - - - - 1499764f by Sjoerd Visscher at 2024-08-29T16:52:56+02:00 Haddock: Add no-compilation flag This flag makes sure to avoid recompilation of the code when generating documentation by only reading the .hi and .hie files, and throw an error if it can't find them. - - - - - 768fe644 by Andreas Klebinger at 2024-09-03T13:15:20-04:00 Add functions to check for weakly pinned arrays. This commit adds `isByteArrayWeaklyPinned#` and `isMutableByteArrayWeaklyPinned#` primops. These check if a bytearray is *weakly* pinned. Which means it can still be explicitly moved by the user via compaction but won't be moved by the RTS. This moves us one more stop closer to nailing down #22255. - - - - - b16605e7 by Arsen Arsenović at 2024-09-03T13:16:05-04:00 ghc-toolchain: Don't leave stranded a.outs when testing for -g0 This happened because, when ghc-toolchain tests for -g0, it does so by compiling an empty program. This compilation creates an a.out. Since we create a temporary directory, lets place the test program compilation in it also, so that it gets cleaned up. Fixes: 25b0b40467d0a12601497117c0ad14e1fcab0b74 Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/25203 - - - - - 83e70b14 by Torsten Schmits at 2024-09-03T13:16:41-04:00 Build foreign objects for TH with interpreter's way when loading from iface Fixes #25211 When linking bytecode for TH from interface core bindings with `-fprefer-byte-code`, foreign sources are loaded from the interface as well and compiled to object code in an ad-hoc manner. The results are then loaded by the interpreter, whose way may differ from the current build's target way. This patch ensures that foreign objects are compiled with the interpreter's way. - - - - - 0d3bc2fa by Cheng Shao at 2024-09-04T07:20:06-04:00 rts: fix checkClosure error message This patch fixes an error message in checkClosure() when the closure has already been evacuated. The previous logic was meant to print the evacuated closure's type in the error message, but it was completely wrong, given info was not really an info table, but a tagged pointer that points to the closure's new address. - - - - - fb0a4e5c by Sven Tennie at 2024-09-04T07:20:43-04:00 MO_AcquireFence: Less restrictive barrier GCC and CLang translate the built-in `atomic_thread_fence(memory_order_acquire)` to `dmb ishld`, which is a bit less restrictive than `dmb ish` (which also implies stores.) - - - - - a45f1488 by Fendor at 2024-09-04T20:22:00-04:00 testsuite: Add support to capture performance metrics via 'perf' Performance metrics collected via 'perf' can be more accurate for run-time performance than GHC's rts, due to the usage of hardware counters. We allow performance tests to also record PMU events according to 'perf list'. - - - - - ce61fca5 by Fendor at 2024-09-04T20:22:00-04:00 gitlab-ci: Add nightly job for running the testsuite with perf profiling support - - - - - 6dfb9471 by Fendor at 2024-09-04T20:22:00-04:00 Enable perf profiling for compiler performance tests - - - - - da306610 by sheaf at 2024-09-04T20:22:41-04:00 RecordCon lookup: don't allow a TyCon This commit adds extra logic when looking up a record constructor. If GHC.Rename.Env.lookupOccRnConstr returns a TyCon (as it may, due to the logic explained in Note [Pattern to type (P2T) conversion]), we emit an error saying that the data constructor is not in scope. This avoids the compiler falling over shortly thereafter, in the call to 'lookupConstructorInfo' inside 'GHC.Rename.Env.lookupRecFieldOcc', because the record constructor would not have been a ConLike. Fixes #25056 - - - - - 9c354beb by Matthew Pickering at 2024-09-04T20:23:16-04:00 Use deterministic names for temporary files When there are multiple threads they can race to create a temporary file, in some situations the thread will create ghc_1.c and in some it will create ghc_2.c. This filename ends up in the debug info for object files after compiling a C file, therefore contributes to object nondeterminism. In order to fix this we store a prefix in `TmpFs` which serves to namespace temporary files. The prefix is populated from the counter in TmpFs when the TmpFs is forked. Therefore the TmpFs must be forked outside the thread which consumes it, in a deterministic order, so each thread always receives a TmpFs with the same prefix. This assumes that after the initial TmpFs is created, all other TmpFs are created from forking the original TmpFs. Which should have been try anyway as otherwise there would be file collisions and non-determinism. Fixes #25224 - - - - - 59906975 by Hécate Kleidukos at 2024-09-05T10:57:15-04:00 Silence x-partial in Haddock.Backends.Xhtml This is an unfortunate consequence of two mechanisms: * GHC provides (possibly-empty) lists of names * The functions that retrieve those names are not equipped to do error reporting, and thus accept these lists at face value. They will have to be attached an effect for error reporting in a later refactoring - - - - - 8afbab62 by Hécate Kleidukos at 2024-09-05T10:57:15-04:00 hadrian: Support loading haddock in ghci There is one tricky aspect with wired-in packages where the boot package is built with `-this-unit-id ghc` but the dependency is reported as `-package-id ghc-9.6...`. This has never been fixed in GHC as the situation of loading wired-in packages into the multi-repl seems like quite a niche feature that is always just easier to workaround. - - - - - 6cac9eb8 by Matthew Pickering at 2024-09-05T10:57:15-04:00 hadrian/multi: Load all targets when ./hadrian/ghci-multi is called This seems to make a bit more sense than just loading `ghc` component (and dependencies). - - - - - 7d84df86 by Matthew Pickering at 2024-09-05T10:57:51-04:00 ci: Beef up determinism interface test There have recently been some determinism issues with the simplifier and documentation. We enable more things to test in the ABI test to check that we produce interface files deterministically. - - - - - 5456e02e by Sylvain Henry at 2024-09-06T11:57:01+02:00 Transform some StgRhsClosure into StgRhsCon after unarisation (#25166) Before unarisation we may have code like: Test.foo :: Test.D [GblId, Unf=OtherCon []] = \u [] case (# |_| #) [GHC.Types.(##)] of sat_sAw [Occ=Once1] { __DEFAULT -> Test.D [GHC.Types.True sat_sAw]; }; After unarisation we get: Test.foo :: Test.D [GblId, Unf=OtherCon []] = {} \u [] Test.D [GHC.Types.True 2#]; Notice that it's still an Updatable closure for no reason anymore. This patch transforms appropriate StgRhsClosures into StgRhsCons after unarisation, allowing these closures to be statically allocated. Now we get the expected: Test.foo :: Test.D [GblId, Unf=OtherCon []] = Test.D! [GHC.Types.True 2#]; Fix #25166 To avoid duplicating code, this patch refactors the mk(Top)StgRhs functions and put them in a GHC.Stg.Make module alongside the new mk(Top)StgRhsCon_maybe functions. - - - - - 958b4518 by Hécate Kleidukos at 2024-09-06T16:40:56-04:00 haddock: Add missing requirements.txt for the online manual - - - - - 573f9833 by Sven Tennie at 2024-09-08T09:58:21+00:00 AArch64: Implement takeRegRegMoveInstr This has likely been forgotten. - - - - - 20b0de7d by Hécate Kleidukos at 2024-09-08T14:19:28-04:00 haddock: Configuration fix for ReadTheDocs - - - - - 03055c71 by Sylvain Henry at 2024-09-09T14:58:15-04:00 JS: fake support for native adjustors (#25159) The JS backend doesn't support adjustors (I believe) and in any case if it ever supports them it will be a native support, not one via libffi. - - - - - 5bf0e6bc by Sylvain Henry at 2024-09-09T14:58:56-04:00 JS: remove redundant h$lstat It was introduced a second time by mistake in 27dceb42376c34b99a38e36a33b2abc346ed390f (cf #25190) - - - - - ffbc2ab0 by Simon Peyton Jones at 2024-09-10T00:40:37-04:00 Refactor only newSysLocalDs * Change newSysLocalDs to take a scaled type * Add newSysLocalMDs that takes a type and makes a ManyTy local Lots of files touched, nothing deep. - - - - - 7124e4ad by Simon Peyton Jones at 2024-09-10T00:40:37-04:00 Don't introduce 'nospec' on the LHS of a RULE This patch address #25160. The main payload is: * When desugaring the LHS of a RULE, do not introduce the `nospec` call for non-canonical evidence. See GHC.Core.InstEnv Note [Coherence and specialisation: overview] The `nospec` call usually introdued in `dsHsWrapper`, but we don't want it on the LHS of a RULE (that's what caused #25160). So now `dsHsWrapper` takes a flag to say if it's on the LHS of a RULE. See wrinkle (NC1) in `Note [Desugaring non-canonical evidence]` in GHC.HsToCore.Binds. But I think this flag will go away again when I have finished with my (entirely separate) speciaise-on-values patch (#24359). All this meant I had to re-understand the `nospec` stuff and coherence, and that in turn made me do some refactoring, and add a lot of new documentation The big change is that in GHC.Core.InstEnv, I changed the /type synonym/ `Canonical` into a /data type/ `CanonicalEvidence` and documented it a lot better. That in turn made me realise that CalLStacks were being treated with a bit of a hack, which I documented in `Note [CallStack and ExecptionContext hack]`. - - - - - 663daf8d by Simon Peyton Jones at 2024-09-10T00:40:37-04:00 Add defaulting of equalities This MR adds one new defaulting strategy to the top-level defaulting story: see Note [Defaulting equalities] in GHC.Tc.Solver. This resolves #25029 and #25125, which showed that users were accidentally relying on a GHC bug, which was fixed by commit 04f5bb85c8109843b9ac2af2a3e26544d05e02f4 Author: Simon Peyton Jones <simon.peytonjones at gmail.com> Date: Wed Jun 12 17:44:59 2024 +0100 Fix untouchability test This MR fixes #24938. The underlying problem was tha the test for "does this implication bring in scope any equalities" was plain wrong. This fix gave rise to a number of user complaints; but the improved defaulting story of this MR largely resolves them. On the way I did a bit of refactoring, of course * Completely restructure the extremely messy top-level defaulting code. The new code is in GHC.Tc.Solver.tryDefaulting, and is much, much, much esaier to grok. - - - - - e28cd021 by Andrzej Rybczak at 2024-09-10T00:41:18-04:00 Don't name a binding pattern It's a keyword when PatternSynonyms are set. - - - - - b09571e2 by Simon Peyton Jones at 2024-09-10T00:41:54-04:00 Do not use an error thunk for an absent dictionary In worker/wrapper we were using an error thunk for an absent dictionary, but that works very badly for -XDictsStrict, or even (as #24934 showed) in some complicated cases involving strictness analysis and unfoldings. This MR just uses RubbishLit for dictionaries. Simple. No test case, sadly because our only repro case is rather complicated. - - - - - 8bc9f5f6 by Hécate Kleidukos at 2024-09-10T00:42:34-04:00 haddock: Remove support for applehelp format in the Manual - - - - - 9ca15506 by doyougnu at 2024-09-10T10:46:38-04:00 RTS linker: add support for hidden symbols (#25191) Add linker support for hidden symbols. We basically treat them as weak symbols. Patch upstreamed from haskell.nix Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Moritz Angermann <moritz.angermann at gmail.com> - - - - - 3b2dc826 by Sven Tennie at 2024-09-10T10:47:14-04:00 Fix C warnings (#25237) GCC 14 treats the fixed warnings as errors by default. I.e. we're gaining GCC 14 compatibility with these fixes. - - - - - 05715994 by Sylvain Henry at 2024-09-10T10:47:55-04:00 JS: fix codegen of static string data Before this patch, when string literals are made trivial, we would generate `h$("foo")` instead of `h$str("foo")`. This was introduced by mistake in 6bd850e887b82c5a28bdacf5870d3dc2fc0f5091. - - - - - 949ebced by Hécate Kleidukos at 2024-09-10T19:19:40-04:00 haddock: Re-organise cross-OS compatibility layer - - - - - 84ac9a99 by Hécate Kleidukos at 2024-09-10T19:19:40-04:00 haddock: Remove CPP for obsolete GHC and Cabal versions - - - - - 370d1599 by Hécate Kleidukos at 2024-09-10T19:19:40-04:00 haddock: Move the changelog file to the 'extra-doc-files' section in the cabal file - - - - - cfbff65a by Simon Peyton Jones at 2024-09-10T19:20:16-04:00 Add ZonkAny and document it This MR fixed #24817 by adding ZonkAny, which takes a Nat argument. See Note [Any types] in GHC.Builtin.Types, especially wrinkle (Any4). - - - - - 0167e472 by Matthew Pickering at 2024-09-11T02:41:42-04:00 hadrian: Make sure ffi headers are built before using a compiler When we are using ffi adjustors then we rely on `ffi.h` and `ffitarget.h` files during code generation when compiling stubs. Therefore we need to add this dependency to the build system (which this patch does). Reproducer, configure with `--enable-libffi-adjustors` and then build "_build/stage1/libraries/ghc-prim/build/GHC/Types.p_o". Observe that this fails before this patch and works afterwards. Fixes #24864 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> - - - - - 0f696958 by Rodrigo Mesquita at 2024-09-11T02:42:18-04:00 base: Deprecate BCO primops exports from GHC.Exts See https://github.com/haskell/core-libraries-committee/issues/212. These reexports will be removed in GHC 9.14. - - - - - cf0e7729 by Alan Zimmerman at 2024-09-11T02:42:54-04:00 EPA: Remove Anchor = EpaLocation synonym This just causes confusion. - - - - - 8e462f4d by Andrew Lelechenko at 2024-09-11T22:20:37-04:00 Bump submodule deepseq to 1.5.1.0 - - - - - aa4500ae by Sebastian Graf at 2024-09-11T22:21:13-04:00 User's guide: Fix the "no-backtracking" example of -XOrPatterns (#25250) Fixes #25250. - - - - - 1c479c01 by Sven Tennie at 2024-09-12T10:39:38+00:00 RISCV64: Add Native Code Generator (NCG) This architecture wasn't supported before. Co-authored-by: Moritz Angermann <moritz.angermann at gmail.com> - - - - - 51b678e1 by Sven Tennie at 2024-09-12T10:39:38+00:00 Adjust test timings for slower computers Increase the delays a bit to be able to run these tests on slower computers. The reference was a Lichee Pi 4a RISCV64 machine. - - - - - a0e41741 by Sven Tennie at 2024-09-12T10:39:38+00:00 RISCV64: Add RTS linker This architecture wasn't supported before. Co-authored-by: Moritz Angermann <moritz.angermann at gmail.com> - - - - - d365b1d4 by Sven Tennie at 2024-09-12T10:39:38+00:00 RISCV64: Ignore divbyzero test The architecture's behaviour differs from the test's expectations. See comment in code why this is okay. - - - - - abf3d699 by Sven Tennie at 2024-09-12T10:39:38+00:00 RISCV64: Enable MulMayOflo_full test It works and thus can be tested. - - - - - 38c7ea8c by Sven Tennie at 2024-09-12T10:39:38+00:00 RISCV64: LibffiAdjustor: Ensure code caches are flushed RISCV64 needs a specific code flushing sequence (involving fence.i) when new code is created/loaded. - - - - - 7edc6965 by Sven Tennie at 2024-09-12T10:39:38+00:00 RISCV64: Add additional linker symbols for builtins We're relying on some GCC/Clang builtins. These need to be visible to the linker (and not be stripped away.) - - - - - 92ad3d42 by Sven Tennie at 2024-09-12T10:39:38+00:00 RISCV64: Add GHCi support As we got a RTS linker for this architecture now, we can enable GHCi for it. - - - - - a145f701 by Sven Tennie at 2024-09-12T10:39:38+00:00 RISCV64: Set codeowners of the NCG - - - - - 8e6d58cf by Sven Tennie at 2024-09-12T10:39:38+00:00 Add test for C calling convention Ensure that parameters and return values are correctly processed. A dedicated test (like this) helps to get the subtleties of calling conventions easily right. The test is failing for WASM32 and marked as fragile to not forget to investigate this (#25249). - - - - - fff55592 by Torsten Schmits at 2024-09-12T21:50:34-04:00 finder: Add `IsBootInterface` to finder cache keys - - - - - cdf530df by Alan Zimmerman at 2024-09-12T21:51:10-04:00 EPA: Sync ghc-exactprint to GHC - - - - - 1374349b by Sebastian Graf at 2024-09-13T07:52:11-04:00 DmdAnal: Fast path for `multDmdType` (#25196) This is in order to counter a regression exposed by SpecConstr. Fixes #25196. - - - - - 80769bc9 by Andrew Lelechenko at 2024-09-13T07:52:47-04:00 Bump submodule array to 0.5.8.0 - - - - - 49ac3fb8 by Sylvain Henry at 2024-09-16T10:33:01-04:00 Linker: add support for extra built-in symbols (#25155) See added Note [Extra RTS symbols] and new user guide entry. Co-authored-by: Hamish Mackenzie <Hamish.K.Mackenzie at gmail.com> Co-authored-by: Moritz Angermann <moritz.angermann at gmail.com> - - - - - 3939a8bf by Samuel Thibault at 2024-09-16T10:33:44-04:00 GNU/Hurd: Add getExecutablePath support GNU/Hurd exposes it as /proc/self/exe just like on Linux. - - - - - d3b19851 by Sylvain Henry at 2024-09-17T11:03:28-04:00 RTS: expose closure_sizeW_ (#25252) C code using the closure_sizeW macro can't be linked with the RTS linker without this patch. It fails with: ghc-9.11.20240911: Failed to lookup symbol: closure_sizeW_ Fix #25252 Co-authored-by: Hamish Mackenzie <Hamish.K.Mackenzie at gmail.com> Co-authored-by: Moritz Angermann <moritz.angermann at gmail.com> - - - - - 137bf74d by Sebastian Graf at 2024-09-17T11:04:05-04:00 HsExpr: Inline `HsWrap` into `WrapExpr` This nice refactoring was suggested by Simon during review: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13261#note_583374 Fixes #25264. - - - - - 7fd9e5e2 by Sebastian Graf at 2024-09-17T11:04:05-04:00 Pmc: Improve Desugaring of overloaded list patterns (#25257) This actually makes things simpler. Fixes #25257. - - - - - e4169ba9 by Ben Gamari at 2024-09-18T07:55:28-04:00 configure: Correctly report when subsections-via-symbols is disabled As noted in #24962, currently subsections-via-symbols is disabled on AArch64/Darwin due to alleged breakage. However, `configure` reports to the user that it is enabled. Fix this. - - - - - 9d20a787 by Mario Blažević at 2024-09-18T07:56:08-04:00 Modified the default export implementation to match the amended spec - - - - - 35eb4f42 by Sylvain Henry at 2024-09-18T07:57:00-04:00 FFI: don't ppr Id/Var symbols with debug info (#25255) Even if `-dpp-debug` is enabled we should still generate valid C code. So we disable debug info printing when rendering with Code style. - - - - - 9e96dad8 by Sebastian Graf at 2024-09-21T17:47:59-04:00 Demand: Combine examples into Note (#25107) Just a leftover from !13060. Fixes #25107. - - - - - 21aaa34b by sheaf at 2024-09-21T17:48:36-04:00 Use x86_64-unknown-windows-gnu target for LLVM on Windows - - - - - 992a7624 by sheaf at 2024-09-21T17:48:36-04:00 LLVM: use -relocation-model=pic on Windows This is necessary to avoid the segfaults reported in #22487. Fixes #22487 - - - - - c50d29be by Ryan Hendrickson at 2024-09-21T17:49:15-04:00 compiler: Use type abstractions when deriving For deriving newtype and deriving via, in order to bring type variables needed for the coercions into scope, GHC generates type signatures for derived class methods. As a simplification, drop the type signatures and instead use type abstractions to bring method type variables into scope. - - - - - f04fd0ae by Zubin Duggal at 2024-09-21T17:49:51-04:00 driver: Ensure we run driverPlugin for staticPlugins (#25217) driverPlugins are only run when the plugin state changes. This meant they were never run for static plugins, as their state never changes. We need to keep track of whether a static plugin has been initialised to ensure we run static driver plugins at least once. This necessitates an additional field in the `StaticPlugin` constructor as this state has to be bundled with the plugin itself, as static plugins have no name/identifier we can use to otherwise reference them - - - - - 620becd7 by Andreas Klebinger at 2024-09-21T17:50:27-04:00 Allow unknown fd device types for setNonBlockingMode. This allows fds with a unknown device type to have blocking mode set. This happens for example for fds from the inotify subsystem. Fixes #25199. - - - - - c76e25b3 by Hécate Kleidukos at 2024-09-21T17:51:07-04:00 Use Hackage version of Cabal 3.14.0.0 for Hadrian. We remove the vendored Cabal submodule. Also update the bootstrap plans Fixes #25086 - - - - - 6c83fd7f by Zubin Duggal at 2024-09-21T17:51:07-04:00 ci: Ensure we source ci.sh in any jobs that run commands outside of ci.sh ci.sh sets up the toolchain environment, including paths for the cabal directory, the toolchain binaries etc. If we run any commands outside of ci.sh, unless we source ci.sh we will use the wrong values for these environment variables. In particular, I ran into an issue where the cabal invocation `hadrian/ghci` was using an old index state despite `ci.sh setup` updating and setting the correct index state. This is because `ci.sh` sets the `CABAL_DIR` to a different place, which is where the index was downloaded to, but we were using the default cabal directory outside ci.sh The solution is to source the correct environment `ci.sh` using `. ci.sh setup` - - - - - 9586998d by Sven Tennie at 2024-09-21T17:51:43-04:00 ghc-toolchain: Set -fuse-ld even for ld.bfd This reflects the behaviour of the autoconf scripts. - - - - - d7016e0d by Sylvain Henry at 2024-09-21T17:52:24-04:00 Parser: be more careful when lexing extended literals (#25258) Previously we would lex invalid prefixes like "8#Int3" as [8#Int, 3]. A side-effect of this patch is that we now allow negative unsigned extended literals. They trigger an overflow warning later anyway. - - - - - ca67d7cb by Zubin Duggal at 2024-09-22T02:34:06-04:00 rts: Ensure we dump new Cost Centres added by freshly loaded objects to the eventlog. To do this, we keep track of the ID of the last cost centre we dumped in DUMPED_CC_ID, and call dumpCostCentresToEventLog from refreshProfilingCCSs, which will dump all the new cost centres up to the one we already dumped in DUMPED_CC_ID. Fixes #24148 - - - - - c0df5aa9 by Alan Zimmerman at 2024-09-22T02:34:42-04:00 EPA: Replace AnnsModule am_main with EpTokens Working towards removing `AddEpAnn` - - - - - 2a551cd5 by Matthew Pickering at 2024-09-24T16:33:50+05:30 ci: Run abi-test on test-abi label - - - - - ab4039ac by Rodrigo Mesquita at 2024-09-24T16:33:50+05:30 testsuite: Add a test for object determinism Extends the abi_test with an object determinism check Also includes a standalone test to be run by developers manually when debugging issues with determinism. - - - - - d62c18d8 by Rodrigo Mesquita at 2024-09-24T16:33:50+05:30 determinism: Sampling uniques in the CG To achieve object determinism, the passes processing Cmm and the rest of the code generation pipeline musn't create new uniques which are non-deterministic. This commit changes occurrences of non-deterministic unique sampling within these code generation passes by a deterministic unique sampling strategy by propagating and threading through a deterministic incrementing counter in them. The threading is done implicitly with `UniqDSM` and `UniqDSMT`. Secondly, the `DUniqSupply` used to run a `UniqDSM` must be threaded through all passes to guarantee uniques in different passes are unique amongst them altogether. Specifically, the same `DUniqSupply` must be threaded through the CG Streaming pipeline, starting with Driver.Main calling `StgToCmm.codeGen`, `cmmPipeline`, `cmmToRawCmm`, and `codeOutput` in sequence. To thread resources through the `Stream` abstraction, we use the `UniqDSMT` transformer on top of `IO` as the Monad underlying the Stream. `UniqDSMT` will thread the `DUniqSupply` through every pass applied to the `Stream`, for every element. We use @type CgStream = Stream (UniqDSMT IO)@ for the Stream used in code generation which that carries through the deterministic unique supply. See Note [Deterministic Uniques in the CG] - - - - - 3bbe4af4 by Rodrigo Mesquita at 2024-09-24T16:33:50+05:30 determinism: Cmm unique renaming pass To achieve object determinism, we need to prevent the non-deterministic uniques from leaking into the object code. We can do this by deterministically renaming the non-external uniques in the Cmm groups that are yielded right after StgToCmm. The key to deterministic renaming is observing that the order of declarations, instructions, and data in the Cmm groups are already deterministic (modulo other determinism bugs), regardless of the uniques. We traverse the Cmm AST in this deterministic order and rename the uniques, incrementally, in the order they are found, thus making them deterministic. This renaming is guarded by -fobject-determinism which is disabled by default for now. This is one of the key passes for object determinism. Read about the overview of object determinism and a more detailed explanation of this pass in: * Note [Object determinism] * Note [Renaming uniques deterministically] Significantly closes the gap to #12935 - - - - - 8357ed50 by Rodrigo Mesquita at 2024-09-24T16:33:50+05:30 determinism: DCmmGroup vs CmmGroup Part of our strategy in producing deterministic objects, namely, renaming all Cmm uniques in order, depend on the object code produced having a deterministic order (say, A_closure always comes before B_closure). However, the use of LabelMaps in the Cmm representation invalidated this requirement because the LabelMaps elements would already be in a non-deterministic order (due to the original uniques), and the renaming in sequence wouldn't work because of that non-deterministic order. Therefore, we now start off with lists in CmmGroup (which preserve the original order), and convert them into LabelMaps (for performance in the code generator) after the uniques of the list elements have been renamed. See Note [DCmmGroup vs CmmGroup or: Deterministic Info Tables] and #12935. Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - 0e675fb8 by Rodrigo Mesquita at 2024-09-24T16:33:50+05:30 determinism: Don't print unique in pprFullName This unique was leaking as part of the profiling description in info tables when profiling was enabled, despite not providing information relevant to the profile. - - - - - 340f58b0 by Rodrigo Mesquita at 2024-09-24T16:33:50+05:30 determinism: UDFM for distinct-constructor-tables In order to produce deterministic objects when compiling with -distinct-constructor-tables, we also have to update the data constructor map to be backed by a deterministic unique map (UDFM) rather than a non-deterministic one (UniqMap). - - - - - 282f37a0 by Rodrigo Mesquita at 2024-09-24T16:33:50+05:30 determinism: InfoTableMap uniques in generateCgIPEStub Fixes object determinism when using -finfo-table-map Make sure to also deterministically rename the IPE map (as per Note [Renaming uniques deterministically]), and to use a deterministic unique supply when creating new labels for the IPE information to guarantee deterministic objects when IPE information is requested. Note that the Cmm group produced in generateCgIPEStub must /not/ be renamed because renaming uniques is not idempotent, and the references to the previously renamed code in the IPE Cmm group would be renamed twice and become invalid references to non-existent symbols. We do need to det-rename the InfoTableMap that is created in the conversion from Core to Stg. This is not a problem since that map won't refer any already renamed names (since it was created before the renaming). - - - - - 7b37afc9 by Zubin Duggal at 2024-09-24T16:33:50+05:30 ci: Allow abi-test to fail. We are not fully deterministic yet, see #12935 for work that remains to be done. - - - - - a63ee33a by Simon Peyton Jones at 2024-09-25T17:08:24-04:00 Add Given injectivity for built-in type families Ticket #24845 asks (reasonably enough) that if we have [G] a+b ~ 0 then we also know [G] a ~ 0, b ~ 0 and similar injectivity-like facts for other built-in type families. The status quo was that we never generate evidence for injectivity among Givens -- but it is quite reasonnable to do so. All we need is to have /evidence/ for the new constraints This MR implements that goal. I also took the opportunity to * Address #24978: refactoring UnivCo * Fix #25248, which was a consequences of the previous formulation of UnivCo As a result this MR touches a lot of code. The big things are: * Coercion constructor UnivCo now takes a [Coercion] as argument to express the coercions on which the UnivCo depends. A nice consequence is that UnivCoProvenance now has no free variables, simpler in a number of places. * Coercion constructors AxiomInstCo and AxiomRuleCo are combined into AxiomCo. The new AxiomCo, carries a (slightly oddly named) CoAxiomRule, which itself is a sum type of the various forms of built-in axiom. See Note [CoAxiomRule] in GHC.Core.Coercion.Axiom A merit of this is that we can separate the case of open and closed type families, and eliminate the redundant `BranchIndex` in the former case. * Much better representation for data BuiltInSynFamily, which means we no longer need to enumerate built-in axioms as well as built-in tycons. * There is a massive refactor in GHC.Builtin.Types.Literals, which contains all the built-in axioms for type-level operations (arithmetic, append, cons etc). A big change is that instead of redundantly having (a) a hand-written matcher, and (b) a template-based "proves" function, which were hard to keep in sync, the two are derive from one set of human-supplied info. See GHC.Builtin.Types.Literals.mkRewriteAxiom, and friends. * Significant changes in GHC.Tc.Solver.Equality to account for the new opportunity for Given/Given equalities. Smaller things * Improve pretty-printing to avoid parens around atomic coercions. * Do proper eqType in findMatchingIrreds, not `eqTypeNoKindCheck`. Looks like a bug, Richard agrees. * coercionLKind and coercionRKind are hot functions. I refactored the implementation (which I had to change anyway) to increase sharing. See Note [coercionKind performance] in GHC.Core.Coercion * I wrote a new Note [Finding orphan names] in GHC.Core.FVs about orphan names * I improved the `is_concrete` flag in GHC.Core.Type.buildSynTyCon, to avoid calling tyConsOfType. I forget exactly why I did this, but it's definitely better now. * I moved some code from GHC.Tc.Types.Constraint into GHC.Tc.Types.CtLocEnv and I renamed the module GHC.Tc.Types.CtLocEnv to GHC.Tc.Types.CtLoc - - - - - dd8ef342 by Ryan Scott at 2024-09-25T17:09:01-04:00 Resolve ambiguous method-bound type variables in vanilla defaults and GND When defining an instance of a class with a "vanilla" default, such as in the following example (from #14266): ```hs class A t where f :: forall x m. Monoid x => t m -> m f = <blah> instance A [] ``` We have to reckon with the fact that the type of `x` (bound by the type signature for the `f` method) is ambiguous. If we don't deal with the ambiguity somehow, then when we generate the following code: ```hs instance A [] where f = $dmf @[] -- NB: the type of `x` is still ambiguous ``` Then the generated code will not typecheck. (Issue #25148 is a more recent example of the same problem.) To fix this, we bind the type variables from the method's original type signature using `TypeAbstractions` and instantiate `$dmf` with them using `TypeApplications`: ```hs instance A [] where f @x @m = $dmf @[] @x @m -- `x` is no longer ambiguous ``` Note that we only do this for vanilla defaults and not for generic defaults (i.e., defaults using `DefaultSignatures`). For the full details, see `Note [Default methods in instances] (Wrinkle: Ambiguous types from vanilla method type signatures)`. The same problem arose in the code generated by `GeneralizedNewtypeDeriving`, as we also fix it here using the same technique. This time, we can take advantage of the fact that `GeneralizedNewtypeDeriving`-generated code _already_ brings method-bound type variables into scope via `TypeAbstractions` (after !13190), so it is very straightforward to visibly apply the type variables on the right-hand sides of equations. See `Note [GND and ambiguity]`. Fixes #14266. Fixes #25148. - - - - - 0a4da5d2 by ARATA Mizuki at 2024-09-25T17:09:41-04:00 Document primitive string literals and desugaring of string literals Fixes #17474 and #17974 Co-authored-by: Matthew Craven <5086-clyring at users.noreply.gitlab.haskell.org> - - - - - ad0731ad by Zubin Duggal at 2024-09-25T17:10:18-04:00 rts: Fix segfault when using non-moving GC with profiling `nonMovingCollect()` swaps out the `static_flag` value used as a sentinel for `gct->scavenged_static_objects`, but the subsequent call `resetStaticObjectForProfiling()` sees the old value of `static_flag` used as the sentinel and segfaults. So we must call `resetStaticObjectForProfiling()` before calling `nonMovingCollect()` as otherwise it looks for the incorrect sentinel value Fixes #25232 and #23958 Also teach the testsuite driver about nonmoving profiling ways and stop disabling metric collection when nonmoving GC is enabled. - - - - - e7a26d7a by Sylvain Henry at 2024-09-25T17:11:00-04:00 Fix interaction between fork and kqueue (#24672) A kqueue file descriptor isn't inherited by a child created with fork. As such we mustn't try to close this file descriptor as we would close a random one, e.g. the one used by timerfd. Fix #24672 - - - - - 6863503c by Simon Peyton Jones at 2024-09-25T17:11:37-04:00 Improve GHC.Tc.Solver.defaultEquality This MR improves GHC.Tc.Solver.defaultEquality to solve #25251. The main change is to use checkTyEqRhs to check the equality, so that we do promotion properly. But within that we needed a small enhancement to LC_Promote. See Note [Defaulting equalites] (DE4) and (DE5) The tricky case is (alas) hard to trigger, so I have not added a regression test. - - - - - 97a6c6c3 by Sylvain Henry at 2024-09-25T17:12:18-04:00 JS: fix h$withCStringOnHeap helper (#25288) strlen returns the length of the string without the \0 terminating byte, hence CString weren't properly allocated on the heap (ending \0 byte was missing). - - - - - 5f7c20bc by Ben Gamari at 2024-09-26T04:14:05-04:00 base: Propagate `error` CallStack to thrown exception Previously `errorCallWithCallStackException` failed to propagate its `CallStack` argument, which represents the call-chain of the preceding `error` call, to the exception that it returned. Consequently, the call-stack of `error` calls were quite useless. Unfortunately, this is the second time that I have fixed this but it seems the first must have been lost in rebasing. Fixes a bug in the implementation of CLC proposal 164 <https://github.com/haskell/core-libraries-committee/issues/164> Fixes #24807. - - - - - c20d5186 by Matthew Pickering at 2024-09-26T04:14:42-04:00 driver: Fix -working-dir for foreign files -working-dir definitely needs more serious testing, there are some easy ways to test this. * Modify Cabal to call ghc using -working-dir rather than changing directory. * Modify the testsuite to run ghc using `-working-dir` rather than running GHC with cwd = temporary directory. However this will have to wait until after 9.12. Fixes #25150 - - - - - 88eaa7ac by Sylvain Henry at 2024-09-26T04:15:24-04:00 Enum deriving: reuse predError, succError, toEnumError Reuse predError, succError, and toEnumError when deriving Enum instances to avoid generating different error strings per instance. E.g. before this patch for every instance for a type FOO we would generate a string: "pred{FOO}: tried to take `pred' of first tag in enumeration"# - - - - - e9fa1163 by Sylvain Henry at 2024-09-26T04:15:24-04:00 Enum deriving: generate better code (#16364) Generate better code for Enum.toEnum: check both the lower and the upper bounds at once with an unsigned comparison. Initially I've used a type ascription with a call to 'fromIntegral', hence the slight refactoring of nlAscribe. Using 'fromIntegral' was problematic (too low in the module hierarchy) so 'enumIntToWord' was introduced instead. Combined with the previous commit, T21839c ghc/alloc decrease by 5% Metric Decrease: T21839c - - - - - 383af074 by Sylvain Henry at 2024-09-26T04:16:06-04:00 Core: add absorb rules for binary or/and (#16351) Rules: x or (x and y) ==> x x and (x or y) ==> x - - - - - 783c8b29 by Matthew Pickering at 2024-09-26T12:07:44-04:00 Don't compile `asBox` with -fprof-late The `asBox` function is intended to store exactly the closure which the user passes to it. Placing a cost centre on asBox introduces a thunk, which violates this expectation and can change the result of using asBox when profiling is enabled. See #25212 for more details and ample opportunity to discuss if this is a bug or not. - - - - - 0967dcc7 by Matthew Pickering at 2024-09-26T12:07:44-04:00 Fix normalisation of .prof files Fix 1: If a cost centre contained CAF then the normalisation was corrupted, now only check if CAF is at the start of a line. Fix 2: "no location info" contain a space, which messed up the next normalisation logic which assumed that columns didn't have spaced in. - - - - - 9eda1cb9 by Matthew Pickering at 2024-09-26T12:07:44-04:00 testsuite: Fix normalisation of prof_files removing newlines These normalisation steps were collapsing lines together, which made subsequent normalisation steps fail. ``` foo x y z CAF x y z qux x y z ``` was getting normalised to ``` foo x y z qux x y z ``` which means that subsequent line based filters would not work correctly. - - - - - 2b25f9e2 by Matthew Pickering at 2024-09-26T12:07:44-04:00 packaging: Enable late-ccs for release flavour This enables late cost centres when building profiled libraries and subsequently greatly improves the resolution of cost centre stacks when profiling. This patch also introduces the `grep_prof` test modifier which is used to apply a further filter to the .prof file before they are compared. Fixes #21732 ------------------------- Metric Increase: libdir ------------------------- - - - - - bb030d0d by Brandon Chinn at 2024-09-26T12:08:21-04:00 Replace manual string lexing (#25158) Metric Increase: MultilineStringsPerf This commit replaces the manual string lexing logic with native Alex lexing syntax. This aligns the lexer much closer to the Haskell Report, making it easier to see how the implementation and spec relate. This slightly increases memory usage when compiling multiline strings because we now have two distinct phases: lexing the multiline string with Alex and post-processing the string afterwards. Before, these were done at the same time, but separating them allows us to push as much logic into normal Alex lexing as possible. Since multiline strings are a new feature, this regression shouldn't be too noticeable. We can optimize this over time. - - - - - 16742987 by Matthew Pickering at 2024-09-26T12:08:57-04:00 Revert !4655: Stop 'import "base" Prelude' removing implicit Prelude import This behaviour is problematic for the principle reason that `import Prelude` may not refer to the `base` package, and in which case importing an entirely unrelated module causing your implicit prelude to leave the scope is extremely surprising. See the added test for this example. Discussion on #17045. The secondary reason for reverting this patch is that "base" can't be a wired in package any more (see #24903), so we have to remove special logic which singles out base from the compiler. The rule for implicit shadowing is now simply: * If you write import Prelude (..) then you don't get an implicit prelude import * If you write import "foobar" Prelude (..) for all pkgs foobar, you get an implicit import of prelude. If you want to write a package import of Prelude, then you can enable `NoImplicitPrelude` for the module in question to recover the behaviour of ghc-9.2-9.10. Fixes #17045 - - - - - 57c50f41 by Matthew Pickering at 2024-09-26T12:08:57-04:00 Rename COMPILING_BASE_PACKAGE to COMPILING_GHC_INTERNAL_PACKAGE The COMPILING_BASE_PACKAGE macro is concerned with issues defining symbols and using symbols in the same compilation unit. However, these symbols now exist in ghc-internal rather than base, so we should rename the macro accordingly. The code is guards is likely never used as we never produce windows DLLs but it is simpler to just perform the renaming for now. These days there is little doubt that this macro defined in this ad-hoc manner would be permitted to exist, but these days are not those days. Fixes #25221 - - - - - 70764243 by Matthew Pickering at 2024-09-26T12:08:57-04:00 Preload ghc-internal rather than base This occurence of baseUnitId was missed when moving the bulk of internal definitions into `ghc-internal`. We need to remove this preloading of `base` now because `base` should not be wired in. Towards #24903 - - - - - 12915609 by Matthew Pickering at 2024-09-26T12:08:57-04:00 Remove Data.List compat warning There is currently a warning implemented in -Wcompat which warns you when importing Data.List in a non-qualified manner. ``` A.hs:3:8: warning: [-Wcompat-unqualified-imports] To ensure compatibility with future core libraries changes imports to Data.List should be either qualified or have an explicit import list. | 3 | import Data.List | ^^^^^^^^^ Ok, one module loaded. ``` GHC ticket: https://gitlab.haskell.org/ghc/ghc/-/issues/17244 CLC discussion: https://groups.google.com/g/haskell-core-libraries/c/q3zHLmzBa5E This warning was implemented as part of the migration to making Data.List monomorphic again (and to be used like Data.Set, Data.Map etc). That doesn't seem like it happened, and I imagine that the current CLC would require a new proposal anyway in order to do that now. It's not clear in any case what "future core libraries changes" we are waiting to happen before this warning can be removed. Given the first phase of the proposal has lasted 5 years it doesn't seem that anyone is motivated to carry the proposal to completion. It does seem a bit unnecessary to include a warning in the compiler about "future changes to the module" when there's no timeline or volunteer to implement these changes. The removal of this warning was discussed again at: https://github.com/haskell/core-libraries-committee/issues/269 During the discussion there was no new enthusiasm to move onto the next stages of the proposal so we are removing the warning to unblock the reinstallable "base" project (#24903) Fixes #24904 - - - - - d4e4d498 by Matthew Pickering at 2024-09-26T12:08:57-04:00 Move Control.Monad.Zip into ghc-internal mzip is wired in and therefore needs to be in ghc-internal. Fixes #25222 Towards #24903 - - - - - d3dacdfb by Matthew Pickering at 2024-09-26T12:08:57-04:00 Unwire the base package This patch just removes all the functions related to wiring-in the base package and the `-this-unit-id=base` flag from the cabal file. After this commit "base" becomes just like any other package and the door is opened to moving base into an external repo and releasing base on a separate schedule to the rest of ghc. Closes #24903 - - - - - 1b39363b by Patrick at 2024-09-27T06:10:19-04:00 Add entity information to HieFile #24544 Enhanced HieFile to capture entity information for identifiers, enabling better support for language tools and protocols. See issue #24544 for more details. Work have been done: * Introduction of new data type `EntityInfo` in `GHC.Iface.Ext.Types`. * Add extra field `hie_entity_infos :: NameEntityInfo` to `HieFile` to store the mapping from entity name to corresponding entity infos in `GHC.Iface.Ext.Types`. * Compute `EntityInfo` for each entity name in the HieAst from `TyThing, Id, OccName` when generating the `HieFile` in `GHC.Iface.Ext.Ast`. * Add test T24544 to test the generation of `EntityInfo`. - - - - - 4f3618d8 by sheaf at 2024-09-27T06:10:57-04:00 The X86 SIMD patch. This commit adds support for 128 bit wide SIMD vectors and vector operations to GHC's X86 native code generator. Main changes: - Introduction of vector formats (`GHC.CmmToAsm.Format`) - Introduction of 128-bit virtual register (`GHC.Platform.Reg`), and removal of unused Float virtual register. - Refactor of `GHC.Platform.Reg.Class.RegClass`: it now only contains two classes, `RcInteger` (for general purpose registers) and `RcFloatOrVector` (for registers that can be used for scalar floating point values as well as vectors). - Modify `GHC.CmmToAsm.X86.Instr.regUsageOfInstr` to keep track of which format each register is used at, so that the register allocator can know if it needs to spill the entire vector register or just the lower 64 bits. - Modify spill/load/reg-2-reg code to account for vector registers (`GHC.CmmToAsm.X86.Instr.{mkSpillInstr, mkLoadInstr, mkRegRegMoveInstr, takeRegRegMoveInstr}`). - Modify the register allocator code (`GHC.CmmToAsm.Reg.*`) to propagate the format we are storing in any given register, for instance changing `Reg` to `RegFormat` or `GlobalReg` to `GlobalRegUse`. - Add logic to lower vector `MachOp`s to X86 assembly (see `GHC.CmmToAsm.X86.CodeGen`) - Minor cleanups to genprimopcode, to remove the llvm_only attribute which is no longer applicable. Tests for this feature are provided in the "testsuite/tests/simd" directory. Fixes #7741 Keeping track of register formats adds a small memory overhead to the register allocator (in particular, regUsageOfInstr now allocates more to keep track of the `Format` each register is used at). This explains the following metric increases. ------------------------- Metric Increase: T12707 T13035 T13379 T3294 T4801 T5321FD T5321Fun T783 ------------------------- - - - - - 10e431ef by sheaf at 2024-09-27T06:10:57-04:00 Use xmm registers in genapply This commit updates genapply to use xmm, ymm and zmm registers, for stg_ap_v16/stg_ap_v32/stg_ap_v64, respectively. It also updates the Cmm lexer and parser to produce Cmm vectors rather than 128/256/512 bit wide scalars for V16/V32/V64, removing bits128, bits256 and bits512 in favour of vectors. The Cmm Lint check is weakened for vectors, as (in practice, e.g. on X86) it is okay to use a single vector register to hold multiple different types of data, and we don't know just from seeing e.g. "XMM1" how to interpret the 128 bits of data within. Fixes #25062 - - - - - 8238fb2d by sheaf at 2024-09-27T06:10:57-04:00 Add vector fused multiply-add operations This commit adds fused multiply add operations such as `fmaddDoubleX2#`. These are handled both in the X86 NCG and the LLVM backends. - - - - - 2cb7b748 by sheaf at 2024-09-27T06:10:57-04:00 Add vector shuffle primops This adds vector shuffle primops, such as ``` shuffleFloatX4# :: FloatX4# -> FloatX4# -> (# Int#, Int#, Int#, Int# #) -> FloatX4# ``` which shuffle the components of the input two vectors into the output vector. NB: the indices must be compile time literals, to match the X86 SHUFPD instruction immediate and the LLVM shufflevector instruction. These are handled in the X86 NCG and the LLVM backend. Tested in simd009. - - - - - 0d2428d6 by sheaf at 2024-09-27T06:10:57-04:00 Add Broadcast MachOps This adds proper MachOps for broadcast instructions, allowing us to produce better code for broadcasting a value than simply packing that value (doing many vector insertions in a row). These are lowered in the X86 NCG and LLVM backends. In the LLVM backend, it uses the previously introduced shuffle instructions. - - - - - e6c19a41 by sheaf at 2024-09-27T06:10:57-04:00 Fix treatment of signed zero in vector negation This commit fixes the handling of signed zero in floating-point vector negation. A slight hack was introduced to work around the fact that Cmm doesn't currently have a notion of signed floating point literals (see get_float_broadcast_value_reg). This can be removed once CmmFloat can express the value -0.0. The simd006 test has been updated to use a stricter notion of equality of floating-point values, which ensure the validity of this change. - - - - - f496ff7f by sheaf at 2024-09-27T06:10:57-04:00 Add min/max primops This commit adds min/max primops, such as minDouble# :: Double# -> Double# -> Double# minFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# minWord16X8# :: Word16X8# -> Word16X8# -> Word16X8# These are supported in: - the X86, AArch64 and PowerPC NCGs, - the LLVM backend, - the WebAssembly and JavaScript backends. Fixes #25120 - - - - - 5dd2a423 by sheaf at 2024-09-27T06:10:57-04:00 Add test for C calls & SIMD vectors - - - - - f824e1ee by sheaf at 2024-09-27T06:10:58-04:00 Add test for #25169 - - - - - d54db7f3 by sheaf at 2024-09-27T06:10:58-04:00 Fix #25169 using Plan A from the ticket We now compile certain low-level Cmm functions in the RTS multiple times, with different levels of vector support. We then dispatch at runtime in the RTS, based on what instructions are supported. See Note [realArgRegsCover] in GHC.Cmm.CallConv. Fixes #25169 ------------------------- Metric Increase: T10421 T12425 T18730 T1969 T9198 ------------------------- - - - - - d5f8778a by sheaf at 2024-09-27T06:10:58-04:00 Fix C calls with SIMD vectors This commit fixes the code generation for C calls, to take into account the calling convention. This is particularly tricky on Windows, where all vectors are expected to be passed by reference. See Note [The Windows X64 C calling convention] in GHC.CmmToAsm.X86.CodeGen. - - - - - f64bd564 by sheaf at 2024-09-27T06:10:58-04:00 X86 CodeGen: refactor getRegister CmmLit This refactors the code dealing with loading literals into registers, removing duplication and putting all the code in a single place. It also changes which XOR instruction is used to place a zero value into a register, so that we use VPXOR for a 128-bit integer vector when AVX is supported. - - - - - ab12de6b by sheaf at 2024-09-27T06:10:58-04:00 X86 genCCall: promote arg before calling evalArgs The job of evalArgs is to ensure each argument is put into a temporary register, so that it can then be loaded directly into one of the argument registers for the C call, without the generated code clobbering any other register used for argument passing. However, if we promote arguments after calling evalArgs, there is the possibility that the code used for the promotion will clobber a register, defeating the work of evalArgs. To avoid this, we first promote arguments, and only then call evalArgs. - - - - - 8fd12429 by sheaf at 2024-09-27T06:10:58-04:00 X86 genCCall64: simplify loadArg code This commit simplifies the argument loading code by making the assumption that it is safe to directly load the argument into register, because doing so will not clobber any previous assignments. This assumption is borne from the use of 'evalArgs', which evaluates any arguments which might necessitate non-trivial code generation into separate temporary registers. - - - - - 12504a9f by sheaf at 2024-09-27T06:10:58-04:00 LLVM: propagate GlobalRegUse information This commit ensures we keep track of how any particular global register is being used in the LLVM backend. This informs the LLVM type annotations, and avoids type mismatches of the following form: argument is not of expected type '<2 x double>' call ccc <2 x double> (<2 x double>) (<4 x i32> arg) - - - - - 2bb1e8df by Cheng Shao at 2024-09-27T06:11:35-04:00 Link bytecode from interface-stored core bindings in oneshot mode !13042 Part of #T25090 If the flag `-fprefer-byte-code` is given when compiling a module containing TH, GHC will use Core bindings stored in interfaces to compile and link bytecode for splices. This was only implemented for `--make` mode initially, so this commit adds the same mechanism to oneshot mode (`-c`). When an interface is loaded into the EPS in `loadInterface` that has dehydrated Core bindings, an entry is added to the new field `eps_iface_bytecode`, containing an IO action that produces a bytecode `Linkable`, lazily processing the `mi_extra_decls` by calling `loadIfaceByteCode`. When Template Haskell dependencies are resolved in `getLinkDeps`, this action is looked up after loading a module's interface. If it exists, the action is evaluated and the bytecode is added to the set of `Linkable`s used for execution of the splice; otherwise it falls back on the traditional object file. Metric Decrease: MultiLayerModules T13701 - - - - - 7cb7172e by Matthew Pickering at 2024-09-27T06:12:12-04:00 ci: Fix variable inheritence for ghcup-metadata testing job Downstream in ghcup-ci we use the CONFIGURE_ARGS variable to determine how to setup all the different jobs. On the downstream trigger this was being inherited from the default setting in .gitlab.yml file. Therefore this led to job failures as the necessary CONFIGURE_ARGS were not being passed to the configure script when installing the bindist. See docs: * https://docs.gitlab.com/ee/ci/yaml/#inherit * https://docs.gitlab.com/ee/ci/yaml/#triggerforward 1. inherit:variables:fals - This stops the global variables being inherited into the job and hence forwarded onto the downstream job. 2. trigger:forward:* - yaml_variables: true (default) pass yaml variables to downstream, this is important to pass the upstream pipeline id to downstream. - pipeline_variables: false (default) but don't pass pipeline variables (normal environment variables). Fixes #25294 - - - - - 9ffd6163 by Leo at 2024-09-27T16:26:01+05:30 Fix typo in Prelude doc for (>>=) Fix a minor typo ("equivialent" instead of "equivalent") in the documentation for (>>=) in the prelude. - - - - - 5745dbd3 by Vladislav Zavialov at 2024-09-27T16:26:52+05:30 Wildcard binders in type declarations (#23501) Add support for wildcard binders in type declarations: type Const a b = a -- BEFORE: the `b` had to be named -- even if unused on the RHS type Const a _ = a -- AFTER: the compiler accepts -- a wildcard binder `_` The new feature is part of GHC Proposal #425 "Invisible binders in type declarations", and more specifically its amendment #641. Just like a named binder, a wildcard binder `_` may be: * plain: _ * kinded: (_ :: k -> Type) * invisible, plain: @_ * invisible, kinded: @(_ :: k -> Type) Those new forms of binders are allowed to occur on the LHSs of data, newtype, type, class, and type/data family declarations: data D _ = ... newtype N _ = ... type T _ = ... class C _ where ... type family F _ data family DF _ (Test case: testsuite/tests/typecheck/should_compile/T23501a.hs) However, we choose to reject them in forall telescopes and type family result variable binders (the latter being part of the TypeFamilyDependencies extension): type family Fd a = _ -- disallowed (WildcardBndrInTyFamResultVar) fn :: forall _. Int -- disallowed (WildcardBndrInForallTelescope) (Test case: testsuite/tests/rename/should_fail/T23501_fail.hs) See the new Notes: * Note [Type variable binders] * Note [Wildcard binders in disallowed contexts] To accommodate the new forms of binders, HsTyVarBndr was changed as follows (demonstrated without x-fields for clarity) -- BEFORE (ignoring x-fields and locations) data HsTyVarBndr flag = UserTyVar flag Name | KindedTyVar flag Name HsKind -- AFTER (ignoring x-fields and locations) data HsTyVarBndr flag = HsTvb flag HsBndrVar HsBndrKind data HsBndrVar = HsBndrVar Name | HsBndrWildCard data HsBndrKind = HsBndrNoKind | HsBndrKind LHsKind The rest of the patch is downstream from this change. To avoid a breaking change to the TH AST, we generate fresh names to replace wildcard binders instead of adding a dedicated representation for them (as discussed in #641). And to put a cherry on top of the cake, we now allow wildcards in kind-polymorphic type variable binders in constructor patterns, see Note [Type patterns: binders and unifiers] and the tyPatToBndr function in GHC.Tc.Gen.HsType; example: fn (MkT @(_ :: forall k. k -> Type) _ _) = ... (Test case: testsuite/tests/typecheck/should_compile/T23501b.hs) - - - - - ff2bdca2 by Matthew Pickering at 2024-09-27T16:27:08+05:30 ci: Push perf notes from wasm jobs It was observed in #25299 that we were failing to push performance numbers from the wasm jobs. In future we might want to remove this ad-hoc check but for now it's easier to add another special case. Towards #25299 - - - - - 4c76f75c by Zubin Duggal at 2024-09-27T16:44:00+05:30 Bump GHC version to 9.12 - - - - - e4ac1b0d by Zubin Duggal at 2024-09-27T19:12:24+05:30 Bump GHC version to 9.13 - - - - - da20cac1 by Andreas Klebinger at 2024-10-02T22:18:48-04:00 SpecConstr: Introduce a separate argument limit for forced specs. We used to put no limit at all on specializations forced via the SPEC argument. This isn't always reasonable so we introduce a very high limit that applies to forced specializations, a flag to control it, and we now emit a warning if we fail a specialization because we exceed the warning. Fixes #25197 - - - - - 39497eed by Andreas Klebinger at 2024-10-02T22:19:24-04:00 ghc-experimental: Expose primops and ghc extensions via GHC.PrimOps This will be the new place for functions that would have gone into GHC.Exts in the past but are not stable enough to do so now. Addresses #25242 - - - - - e9dc2690 by Sylvain Henry at 2024-10-02T22:20:06-04:00 RTS: cleanup timerfd file descriptors after a fork (#25280) When we init a timerfd-based ticker, we should be careful to cleanup the old file descriptors (e.g. after a fork). - - - - - 64e876bc by Rodrigo Mesquita at 2024-10-02T22:20:43-04:00 determinism: Deterministic MonadGetUnique LlvmM Update LlvmM to thread a unique deterministic supply (using UniqDSMT), and use it in the MonadGetUnique instance. This makes uniques sampled from LlvmM deterministic, which guarantees object determinism with -fllvm. Fixes #25274 - - - - - 36bbb167 by Matthew Pickering at 2024-10-02T22:21:18-04:00 Bump LLVM upper bound to allow LLVM 19 Also bumps the ci-images commit so that the deb12 images uses LLVM 19 for testing. ------------------------- Metric Decrease: size_hello_artifact_gzip size_hello_unicode_gzip ------------------------- Fixes #25295 - - - - - 0029ca91 by Matthew Pickering at 2024-10-02T22:21:54-04:00 configure: Allow happy-2.0.2 happy-2.0.2 can be used to compile GHC. happy-2.0 and 2.0.1 have bugs which make it unsuitable to use. The version bound is now == 1.20.* || >= 2.0.2 && < 2.1 Fixes #25276 - - - - - 92976985 by ARATA Mizuki at 2024-10-02T22:22:35-04:00 Use bundled llc/opt on Windows (#22438) - - - - - af59749a by Matthew Pickering at 2024-10-02T22:23:11-04:00 Fix registerArch for riscv64 The register allocator doesn't support vector registers on riscv64, therefore advertise as NoVectors. Fixes #25314 - - - - - a49e66fc by Matthew Pickering at 2024-10-02T22:23:11-04:00 riscv: Avoid using csrr instruction to test for vector registers The csrr instruction isn't allowed in qemu user-mode, and raises an illegal instruction error when it is encountered. Therefore for now, we just hard-code that there is no support for vector registers since the rest of the compiler doesn't support vector registers for riscv. Fixes #25312 - - - - - 115a30e9 by Andreas Klebinger at 2024-10-02T22:23:11-04:00 Add support for fp min/max to riscv Fixes #25313 - - - - - f28b5992 by Ben Gamari at 2024-10-02T22:23:47-04:00 testsuite/perf: Report better error message on malformed note Previously a malformed perf note resulted in very poor errors. Here we slight improve this situation. - - - - - 51377508 by Ben Gamari at 2024-10-02T22:23:47-04:00 testsuite: Handle division-by-zero more gracefully Previously we would fail with an ZeroDivisionError. Fixes #25321 - - - - - 50490075 by Matthew Pickering at 2024-10-03T05:55:13-04:00 ci: Add nightly & release ubuntu-22.04 jobs This adds build of bindists on ubuntu-22.04 on nightly and release pipelines. We also update ghcup-metadata to provide ubuntu-22.04 bindists on ubuntu-22.04. Fixes #25317 - - - - - 9cf1cef5 by Zubin Duggal at 2024-10-03T05:55:49-04:00 haddock: Bump binary interface version to 46. This allows haddock to give good error messages when being used on mismatched interface files. We bump to 46 since GHC 9.12 uses version 45: https://gitlab.haskell.org/ghc/ghc/-/commit/362afd632032ee8f174690c3ffe0015076b83ce6 This should have been done in e4ac1b0d281b85a0144d1ef6f84a1df00e236052 but was overlooked. - - - - - 2293c0b7 by Andreas Klebinger at 2024-10-03T05:56:25-04:00 Change versionig of ghc-experimental to follow ghc versions. Just like ghc-internal it will now use the @ProjectVersionForLib@ macro for versioning. This means for ghc=9.10.1, ghc-experimental's version will be 9.1001.0 and so on. This fixes #25289 - - - - - 876d6e0e by Ben Gamari at 2024-10-04T15:07:53+01:00 base: Add `HasCallStack` constraint to `ioError` As proposed in core-libraries-committee#275. - - - - - 9bfd9fd0 by Matthew Pickering at 2024-10-04T15:08:03+01:00 Fix toException method for ExceptionWithContext Fixes #25235 - - - - - ac004028 by Matthew Pickering at 2024-10-04T15:09:07+01:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - bcb293f2 by Cheng Shao at 2024-10-04T17:59:28-04:00 testsuite: remove accidentally checked in debug print logic - - - - - 68e2da5a by Rodrigo Mesquita at 2024-10-05T10:36:15-04:00 Deprecation for WarnCompatUnqualifiedImports Fixes #25330 - - - - - 4327f0e8 by Andrew Lelechenko at 2024-10-05T10:36:52-04:00 Restrict Data.List.NonEmpty.unzip to NonEmpty (a, b) -> (NonEmpty a, NonEmpty b) Implementing the final phase of CLC proposal https://github.com/haskell/core-libraries-committee/issues/86 - - - - - ceca9efb by Cheng Shao at 2024-10-06T02:18:31+00:00 driver: fix runWorkerLimit on wasm This commit fixes link-time unresolved symbol errors for sem_open etc on wasm, by making runWorkerLimit always behave single-threaded. This avoids introducing the jobserver logic into the final wasm module and thus avoids referencing the posix semaphore symbols. - - - - - 135fd1ac by Torsten Schmits at 2024-10-06T02:18:31+00:00 Parallelize getRootSummary computations in dep analysis downsweep This reuses the upsweep step's infrastructure to process batches of modules in parallel. I benchmarked this by running `ghc -M` on two sets of 10,000 modules; one with a linear dependency chain and the other with a binary tree. Comparing different values for the number of modules per thread suggested an optimum at `length targets `div` (n_cap * 2)`, with results similar to this one (6 cores, 12 threads): ``` Benchmark 1: linear 1 jobs Time (mean ± σ): 1.775 s ± 0.026 s [User: 1.377 s, System: 0.399 s] Range (min … max): 1.757 s … 1.793 s 2 runs Benchmark 2: linear 6 jobs Time (mean ± σ): 876.2 ms ± 20.9 ms [User: 1833.2 ms, System: 518.6 ms] Range (min … max): 856.2 ms … 898.0 ms 3 runs Benchmark 3: linear 12 jobs Time (mean ± σ): 793.5 ms ± 23.2 ms [User: 2318.9 ms, System: 718.6 ms] Range (min … max): 771.9 ms … 818.0 ms 3 runs ``` Results don't differ much when the batch size is reduced to a quarter of that, but there's significant thread scheduling overhead for a size of 1: ``` Benchmark 1: linear 1 jobs Time (mean ± σ): 2.611 s ± 0.029 s [User: 2.851 s, System: 0.783 s] Range (min … max): 2.591 s … 2.632 s 2 runs Benchmark 2: linear 6 jobs Time (mean ± σ): 1.189 s ± 0.007 s [User: 2.707 s, System: 1.103 s] Range (min … max): 1.184 s … 1.194 s 2 runs Benchmark 3: linear 12 jobs Time (mean ± σ): 1.097 s ± 0.006 s [User: 2.938 s, System: 1.300 s] Range (min … max): 1.093 s … 1.101 s 2 runs ``` Larger batches also slightly worsen performance. - - - - - 535a2117 by Daniel Díaz at 2024-10-06T09:51:46-04:00 Clarify the meaning of "exactly once" in LinearTypes Solves documentaion issue #25084. - - - - - 92f8939a by Krzysztof Gogolewski at 2024-10-06T09:52:22-04:00 Only allow (a => b) :: Constraint rather than CONSTRAINT rep Fixes #25243 - - - - - 4a2f0f13 by Alan Zimmerman at 2024-10-07T05:16:54-04:00 EPA: Remove unused hsCaseAnnsRest We never populate it, so remove it. - - - - - 5099057b by John Paul Adrian Glaubitz at 2024-10-07T05:17:40-04:00 rts: Fix invocation of __ieee_set_fp_control() on alpha-linux Fixes the following error when building GHC on alpha-linux: rts/posix/Signals.c: In function ‘initDefaultHandlers’: rts/posix/Signals.c:709:5: error: error: implicit declaration of function ‘ieee_set_fp_control’ [-Wimplicit-function-declaration] 709 | ieee_set_fp_control(0); | ^~~~~~~~~~~~~~~~~~~ | 709 | ieee_set_fp_control(0); | - - - - - c9590ba0 by Teo Camarasu at 2024-10-07T05:18:17-04:00 Add changelog entries for !12479 - - - - - bf9c9566 by Matthew Pickering at 2024-10-07T13:19:30-04:00 javascript: Read fields of ObjectBlock lazily When linking a module with a large dependency footprint too much of the object files were forced during linking. This lead to a large amount of memory taken up by thunks which would never be forced On the PartialDownsweep test this halves the memory required (from 25G to 13G). Towards #25324 ------------------------- Metric Increase: size_hello_obj ------------------------- - - - - - 571329df by Matthew Pickering at 2024-10-07T13:20:06-04:00 ci: Run the i386 validation job when i386 label is set This is helpful when making changes to base and must update the javascript and i386 base exports files. - - - - - e68f9aaf by Matthew Pickering at 2024-10-07T13:20:42-04:00 Rewrite partitionByWorkerSize to avoid pattern match checker bug With `-g3` the pattern match checker would warn about these incomplete patterns. This affects the debug_info builds on CI. ``` Pattern match(es) are non-exhaustive In an equation for ‘go’: Patterns of type ‘[a]’, ‘[a]’, ‘[SpecFailWarning]’ not matched: (_:_) _ _ | 2514 | go [] small warnings = (small, warnings) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... ``` Workaround for #25338 - - - - - d915dc8b by Arnaud Spiwack at 2024-10-07T19:23:00-04:00 Remove the wrapper/coercion-passing logic for submultiplicity checks Instead, we use a dedicated DelayedError, which is emitted systematically on submultiplicity checks, but is suppressed if we can indeed solve the submultiplicity constraint with a reflexivity coercion. This way, we don't have to return anything from `tcSubMult`, which now looks like a regular constraint check, the rest is implementation detail. This removes all of the strange boilerplate that I'd been struggling with under the previous implementation. Even if submultiplicity checks are not properly constraints, this way it's contained entirely within a `WantedConstraint`. Much more pleasant. Closes #25128. - - - - - 1d226116 by Sven Tennie at 2024-10-07T19:23:37-04:00 AArch64: Implement switch/jump tables (#19912) This improves the performance of Cmm switch statements (compared to a chain of if statements.) - - - - - 3fe621dd by Mario Blažević at 2024-10-07T19:24:18-04:00 Fixes #25256, missing parens inside TH-printed pattern type signature - - - - - ea4b4391 by ARATA Mizuki at 2024-10-07T19:24:59-04:00 Better documentation for floatRange function Closes #16479 - - - - - ff09205c by Andreas Klebinger at 2024-10-07T19:25:35-04:00 Adjust progress message for hadrian to include cwd. Fixes #25335 - - - - - 5fd320da by Sven Tennie at 2024-10-07T19:26:12-04:00 CCallConv test: Align argument types The C calling convention / standard requires that arguments and their values are of the same type. - - - - - c6e5fd3d by Cheng Shao at 2024-10-07T19:26:47-04:00 hadrian: remove unused ghciWithDebugger field from flavour config This patch removes the ghciWithDebugger field from flavour config since it's actually not used anywhere. - - - - - 9c9c790d by sheaf at 2024-10-07T19:27:23-04:00 user's guide: update docs for X86 CPU flags This commit updates the section of the user's guide pertaining to X86 feature flags with the following changes: - the NCG backend now supports SIMD, so remove all text that says the contrary, - the LLVM backend does not "automatically detect" features, so remove any text that makes that claim. - - - - - a1ecc826 by Sven Tennie at 2024-10-08T13:36:03-04:00 ci: RISCV64 cross-compile testing This adds a validation job which tests that we can build a riscv64 cross compiler and build a simple program using it. We do not currently run the whole testsuite. Towards #25254 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - d5c2577f by Arnaud Spiwack at 2024-10-08T13:36:44-04:00 Remove unused accumulators in partition_errors - - - - - 55609880 by Andrzej Rybczak at 2024-10-09T16:41:46-04:00 Fix typo in the @since annotation of annotateIO - - - - - ef481813 by Alan Zimmerman at 2024-10-09T16:42:23-04:00 EPA: Remove [AddEpAnn] from (most of) HsExpr EPA: introduce EpAnnLam for lambda annotationsi, and remove `glAA` from `Parser.y`, it is the same as `glR` EPA: Remove unused annotation from XOpApp EPA: Use EpToken for XNPat and XNegApp EPA: specific anns for XExplicitTuple / XTuplePat / sumPatParens. EPA: Use specific annotation for MultiIf EPA: Move annotations into FunRhs EPA: Remove [AddEpAnn] from SigPat and ExprWithTySig EPA: Remove [AddEpAnn] from ArithSeq EPA: Remove [AddEpAnn] from HsProc EPA: Remove [AddEpAnn] from HsStatic EPA: Remove [AddEpAnn] from BindStmt EPA: Remove [AddEpAnn] from TransStmt EPA: Remove [AddEpAnn] from HsTypedSplice EPA: Remove [AddEpAnn] from HsUntypedSpliceExpr - - - - - 69960230 by Fabian Thorand at 2024-10-10T19:03:59+00:00 Handle exceptions from IO manager backend If an IO manager backend throws, it will not actually have registered the file descriptor. However, at that point, the IO manager state was already updated to assume the file descriptor is being tracked, leading to errors and an eventual deadlock down the line as documented in the issue #21969. The fix for this is to undo the IO manager state change in case the backend throws (just as we already do when the backend signals that the file type is not supported). The exception then bubbles up to user code. That way we make sure that 1. the bookkeeping state of the IO manager is consistent with the actions taken by the backend, even in the presence of unexpected failures, and 2. the error is not silent and visible to user code, making failures easier to debug. - - - - - 1587cccf by Hassan Al-Awwadi at 2024-10-11T03:52:36-04:00 Put RdrName in the foExt field of FieldOcc The main purpose of this commit is to rip RdrName out of FieldOcc, in accordance with #21592, and as a side note it has simplified the method we use to deal with ambiguity somewhat. To do the first, we make FieldOccs store (LIdP p) instead of always storing Located RdrName, and moved the readername to the extension points where necessary. For the second, well, we just turn an ambiguous RdrName into a unbound Name through mkUnboundName. Later during disambiguateRecordBinds of the type checking phase, we will try and do type-directed disambiguation based on the rdrName field (for now), so this hack works out fine. See Note [Ambiguous FieldOcc in record updates] for more details. There are two additional minor changes in this commit: * The HsRecSel constructor of HsExpr has been moved to the extension constuctors, since its really GHC specific. * HsProjection no longer has a Located DotFieldOcc as a field, but just a regular DotFieldOcc, since DotFieldOcc already wraps a located FieldLabelString co-authored by: @Jade <Jade512 at proton.me> @alt-romes <rodrigo.m.mesquita at gmail.com> - - - - - 2338a971 by Cheng Shao at 2024-10-11T03:53:13-04:00 driver: bail out when -fllvm is passed to GHC not configured with LLVM This patch makes GHC bail out with an proper error message when it's not configured with LLVM but users attempt to pass -fllvm, see #25011 and added comment for details. Fixes #25011 Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 78ad81ec by Cristiano Moraes at 2024-10-11T03:53:55-04:00 configure: Find C++ probing when GCC version is the latest but G++ is old #23118 - - - - - 083703a1 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Consider Wanteds with rewriters as insoluble This MR fixes #25325 See GHC.Tc.Types.Constraint, Note [Insoluble Wanteds], especially (IW2) There is a small change in the error message for T14172, but it looks entirely acceptable to me. - - - - - 0dfaeb66 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Wibbles - - - - - 09d24d82 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Spelling errors - - - - - 694489ed by sheaf at 2024-10-11T03:55:14-04:00 LLVM: use sse4.2 instead of sse42 LLVM expects the former instead of the latter since version 3.4. Fixes #25019 - - - - - 06ae8507 by sheaf at 2024-10-11T03:55:14-04:00 LLVM: make SSE4.2 imply +popcnt For consistency with the NCG as well as with Clang and GCC, we make the SSE4.2 feature flag imply +popcnt when using the LLVM backend. Fixes #25353 - - - - - 3fe843c7 by Cheng Shao at 2024-10-11T03:55:50-04:00 Drop obsolete libffi Makefile This patch drops obsolete libffi Makefile from the tree, given it's completely unused since removal of make build system in !7094. - - - - - df70405c by Ben Gamari at 2024-10-11T03:56:26-04:00 ghc-internal: Fix incomplete matches on IOError As noted in #25362, these incomplete matches were previously not being warned about. They were easily addressed by use of `GHC.Internal.Event.Windows.withException`. Closes #25362. - - - - - 8584504b by Matthew Pickering at 2024-10-11T03:57:02-04:00 compiler: Fix orientation of GHC.Hs.Doc boot file We should be free to import things from Language.Haskell.Syntax in GHC modules. Therefore the the boot file for the loop between ImpExp and GHC.Hs.Doc was in the wrong place. Issue #21592 - - - - - d029f170 by Ben Gamari at 2024-10-11T23:43:17-04:00 testsuite: Normalise trailing digits from hole fits output The type variables in the holes fit output from `abstract_refinement_hole_fits` is quite sensitive to compiler configuration. Specifically, a slight change in the inlining behavior of `throw` changes type variable naming in `(>>=)` and a few others. Ideally we would make hole fits output more deterministic but in the meantime we simply normalise this difference away as it not relevant to the test's goal. - - - - - da5d7d0d by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Add test for #25066 - - - - - eb7ddae1 by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Fix #25066 As noted in #25066, the exception backtrace proposal introduced a rather subtle performance regression due to simplification producing Core which the demand analyser concludes may diverge with a precise exception. The nature of the problem is more completely described in the new Note [Hiding precise exception signature in throw]. The (rather hacky) solution we use here hides the problematic optimisation through judicious use of `noinline`. Ultimately however we will want a more principled solution (e.g. #23847). Fixes #255066 CLC proposal: https://github.com/haskell/core-libraries-committee/issues/290 Metric Decrease: T9872d - - - - - 0060ece7 by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Improve documentation of Control.Exception.Backtrace - - - - - 18f532f3 by Ben Gamari at 2024-10-11T23:43:53-04:00 Bump process submodule to v1.6.25.0 - - - - - a9a3badf by Hassan Al-Awwadi at 2024-10-11T23:44:29-04:00 Move HsInteger and HsRat to an extension constructor These constructors were only used during the TC stage, or during template haskell. It seemed clear that it was independent of the source syntax represented in L.H.S, and thus we removed it according to #21592. - - - - - 4dd30cba by Artem Pelenitsyn at 2024-10-11T23:45:09-04:00 Docs: Linear types: link Strict Patterns subsection Also, fix a bug in RST with missing newline before a listing. Co-authored-by: Arnaud Spiwack <arnaud at spiwack.net> - - - - - adca5f2b by Ben Gamari at 2024-10-11T23:45:45-04:00 users guide: Address remaining TODOs in eventlog format docs Closes #25296. - - - - - 9291c125 by Sylvain Henry at 2024-10-11T23:46:26-04:00 Fix z-encoding of tuples (#25364) Tuples with prefix/suffix strings weren't always properly encoded with their shortcut notations. Fix this. - - - - - c08b68bc by Sven Tennie at 2024-10-11T23:47:01-04:00 Delete constants that can be deduced There are macros in MachRegs.h to figure those out. - - - - - 8b402da2 by Zubin Duggal at 2024-10-12T20:36:57+00:00 hadrian: Handle broken symlinks properly when creating source dist directories If we have a broken symlink in the repository, don't try to `need` the symlink or the target of the symlink. Attempting to do so has `shake` attempt to read the target to compute its hash, which fails because the target doesn't exist. - - - - - 16f97667 by Zubin Duggal at 2024-10-12T20:36:57+00:00 hadrian: exclude cabal.project.symlink.broken from source archives Cabal 3.14 introduced a broken symlink in its testsuite. Unfortunately, this broke our source distribution as we use use `tar --dereference` to avoid issues with symlink compatibility on windows, and `tar --dereference` chokes when it encounters any broken symlinks. We can't get rid of `--dereference` because symlinks are generally broken on windows, so the only option is to exclude this file from source archives. see also https://github.com/haskell/cabal/issues/10442 - - - - - f1a2c9fc by Zubin Duggal at 2024-10-12T20:36:57+00:00 Bump Cabal submodule to 3.14 Metric Decrease: MultiLayerModulesTH_OneShot Metric Increase: haddock.Cabal - - - - - 745dd590 by Ben Gamari at 2024-10-14T09:13:12-04:00 users-guide: Document GHCi :where command Resolve #24509. - - - - - e9cc4699 by Alan Zimmerman at 2024-10-14T09:13:48-04:00 EPA: Remove [AddEpAnn] from IE, Pat and some Tys EPA: Remove [AddEpAnn] from LazyPat EPA: Remove [AddEpAnn] from RecordCon/RecordUpd/ConPat EPA: Remove [AddEpAnn] from HsFieldBind EPA: Remove [AddEpAnn] from PatSynBind EPA: Remove [AddEpAnn] from IPBind EPA: Remove [AddEpAnn] from FixSig EPA: Remove [AddEpAnn] from activation rules EPA: Remove [AddEpann] from SpecInstSig EPA: Remove [AddEpAnn] from MinimalSig EPA: Remove [AddEpAnn] from SCCFunSig EPA: Remove [AddEpAnn] from CompleteMatchSig EPA: Remove [AddEpAnn] from AnnSig, as used in PatSynSig, ClassOpSig, TypeSig EPA: Remove [AddEpAnn] from IEThingAbs EPA: Remove [AddEpAnn] from IEThingAll / IEThingWith EPA: Remove [AddEpAnn] from IEModuleContents EPA: Remove [AddEpAnn] from HsOpTy EPA: Remove [AddEpAnn] for various binders EPA: Remove [AddEpAnn] for HsIParamTy - - - - - 81a570bf by Sebastian Graf at 2024-10-14T22:15:31-04:00 Desugaring, plus -Wincomplete-record-selectors This commit does several related things: * Major refactor of the handling of applications in the desugarer. Now all applications are handled in `dsApp`, `ds_app` and related functions. This dramatically simplifies the code and removes complicated cruft that had accumulated. Hooray. Fixes #25281. * Improve the handling of -Wincomplete-record-selectors. We now incorporate the result type of unsaturated record selector applications as well as consider long-distance information in getField applications. Plus, the implmentation now builds the improved `dsApp` stuff above, so it is much easier to understand. Plus, incorporates improved error message wording suggested by Adam Gundry in !12685. Fixes #24824, #24891 See the long Note [Detecting incomplete record selectors] * Add -Wincomplete-record-selectors to -Wall, as specified in GHC Proposal 516. To do this, I also had to add -Wno-incomplete-record-selectors to the build flags for Cabal in GHC's CI. See hadrian/src/Settings/Warnings.hs. We can remove this when Cabal is updated so that it doesn't trigger the warning: https://github.com/haskell/cabal/issues/10402 2.6% decrease in compile time allocation in RecordUpPerf Metric Decrease: RecordUpdPerf - - - - - ae7bc08e by Simon Peyton Jones at 2024-10-14T22:15:31-04:00 Elmininate incomplete record selectors This patch is a pure refactor of GHC's source code, to avoid the use of partial record selectors. It was provoked by adding -Wincomplete-record-selectors to -Wall (as the GHC Proposal specified), which in turn showed up lots of places where GHC was using incomplete record selectors. This patch does mostly-simple refactoring to make it clear to the pattern match checker that there is in fact no partiality. There is one externally-visible change: I changed the data type HoleFit to split out the two cases data HoleFit = TcHoleFit TcHoleFit | RawHoleFit SDoc data TcHoleFit = HoleFit { ...lots of fields } There are large swathes of code that just deal with `TcHoleFit`, and having it as a separate data types makes it apparent that `RawHoleFit` can't occur. This makes it much better -- but the change is visible in the HolePlugin interface. I decided that there are so few clients of this API that it's worth the change. I moved several functions from Language.Haskell.Syntax to GHC.Hs. Reason, when instantiated at (GhcPass _), the extension data construtcor is guaranteed unused, and that justifies omitted patterns in these functions. By putting them in GHC.Hs.X I can specialise the type for (GhcPass _) and thereby make the function total. An interesting side-light is that there were a few local function definitions without a type signature, like this one in GHC.Parser.Header convImport (L _ i) = (ideclPkgQual i, reLoc $ ideclName i) This is fully closed, and so is generalised; but that generalises it to any old pass, not (GhcPass _), so GHC rightly complains about the use of the selector `ideclPkgQual`. I added a type signature to `i`, thus convImport (L _ (i::ImportDecl GhcPs)) = (ideclPkgQual i, reLoc $ ideclName i) which specialised the function enough to make the record selector complete. Quite a surprising consequence of local let-generalisation! - - - - - 6a067226 by Simon Peyton Jones at 2024-10-14T22:15:31-04:00 Add -Werror=-Wno-error=incomplete-record-selectors to hadrian-multi In the main MR, -Wall now includes -Wincomplete-record-selectors. However `hadrian-multi` has many, many warnings about incomplete record selectors, so this patch stops those warnings being treated as errors. (See discussion on !13308.) A better fix would be to remove the use of incomplete record selectors, since each of them represents a potential crash. - - - - - edeafc14 by Ben Gamari at 2024-10-14T22:16:08-04:00 users-guide: Document field coalescence - - - - - 55b83587 by ARATA Mizuki at 2024-10-14T22:16:49-04:00 LLVM backend: Use correct rounding for Float literals Fixes #22033 - - - - - e59fe5c6 by Hassan Al-Awwadi at 2024-10-15T08:25:33+00:00 Changed import from Ghc. module to L.H.S module Progresses #21592 For some reason we still imported GHC.Types.Fixity when the definitino of Fixity and LexicalFixity have already been moved to Language.Haskell.Syntax.Basic. This fixes that for - - - - - ab1767d5 by Simon Peyton Jones at 2024-10-15T23:45:04-04:00 Add a release-notes entry for -Wincomplete-record-selectors - - - - - 6f0a62db by ur4t at 2024-10-16T15:33:43+00:00 GHCi: fix improper location of ghci_history file Fixes #24266 - - - - - 5f67db48 by Alan Zimmerman at 2024-10-17T05:18:43-04:00 EPA: Remove [AddEpAnn] commit 3 EPA: Remove [AddEpAnn] from HsDocTy EPA: Remove [AddEpAnn] from HsBangTy EPA: Remove [AddEpAnn] from HsExplicitListTy EPA: Remove [AddEpAnn] from HsExplicitTupleTy EPA: Remove [AddEpAnn] from HsTypedBracket EPA: Remove [AddEpAnn] from HsUntypedBracket EPA: Remove [AddEpAnn] from PatBuilderOpApp EPA: break out 'EpToken "|"' from ClassDecl anns EPA: Remove [AddEpAnn] from ClassDecl EPA: Remove [AddEpAnn] from SynDecl - - - - - fbbbd010 by Daan Rijks at 2024-10-17T05:19:19-04:00 Expand the haddocks for Control.Category - - - - - 076c1a10 by Andrew Lelechenko at 2024-10-17T05:19:19-04:00 documentation: more examples for Control.Category - - - - - 90891962 by Cheng Shao at 2024-10-17T16:41:18+00:00 ghci: mitigate host/target word size mismatch in BCOByteArray serialization This patch mitigates a severe host/target word size mismatch issue in BCOByteArray serialization logic introduced since !12142, see added note for detailed explanation. - - - - - 839ac52e by Cheng Shao at 2024-10-17T16:41:18+00:00 ghci: use plain malloc for mkConInfoTable on non-TNTC platforms This patch avoids using mmap() to allocate executable memory for mkConInfoTable on platforms without tables-next-to-code, see added comment for explanation. - - - - - a998f69d by Cheng Shao at 2024-10-17T16:41:18+00:00 ghc-internal: add missing CPPs for wasm This patch adds some missing CPP guards to ghc-internal, given those functions are non existent on wasm and would cause linking issues. - - - - - 71a471e7 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: rename prelude.js to prelude.mjs This commit renames prelude.js to prelude.mjs for wasm backend rts jsbits, and slightly adjusts the jsbits contents. This is for preparing the implementation of dyld.mjs that contains wasm dynamic linker logic, which needs to import prelude.mjs as a proper ESM module. - - - - - 33d9db17 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: add __wrapped_freeJSVal This commit wraps imported freeJSVal in a __wrapped_freeJSVal C function for wasm backend RTS. In general, wasm imports are only supposed to be directly called by C; they shouldn't be used as function pointers, which confuses wasm-ld at link-time when generating shared libraries. - - - - - 0d0a16a8 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: correct stale link in comment - - - - - 90a35c41 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: drop interpretBCO support from non-dyn ways on wasm This commit drops interpretBCO support from non dynamic rts ways on wasm. The bytecode interpreter is only useful when the RTS linker also works, and on wasm it only works for dynamic ways anyway. An additional benefit of dropping interpretBCO is reduction in code size of linked wasm modules, especially since interpretBCO references ffi_call which is an auto-generated large function in libffi-wasm and unused by most user applications. - - - - - 98a32ec5 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: don't build predefined GloblRegs for wasm PIC mode This commit wraps the predefined GlobalRegs in Wasm.S under a CPP guard to prevent building for PIC mode. When building dynamic ways of RTS, the wasm globals that represent STG GlobalRegs will be created and supplied by dyld.mjs. The current wasm dylink convention doesn't properly support exporting relocatable wasm globals at all, any wasm global exported by a .so is assumed to be a GOT.mem entry. - - - - - bef94bde by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: fix conflicting StgRun definitions on wasm This commit fixes conflicting StgRun definition when building dynamic ways of RTS for wasm in unregisterised mode. - - - - - a6a82cdb by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: use targetSupportsRPaths predicate This commit changes the hostSupportsRPaths predicate to targetSupportsRPaths and use that to decide whether to pass RPATH-related link-time options. It's not applied to stage0, we should just use the default link-time options of stageBoot ghc. - - - - - f232c872 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: disable internal-interpreter of ghc library when cross compiling This commit disable the internal-interpreter flag of ghc library when cross compiling, only external interpreter works in such cases. - - - - - 577c1819 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: enable internal-interpreter for ghc-bin stage0 This commit enables internal-interpreter flag for ghc-bin even when compiling stage0, as long as target supports ghci. It enables ghci functionality for cross targets that support ghci, since cross ghc-bin is really stage0. - - - - - c247f2ee by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: fix CFLAGS for gmp shared objs on wasm This commit adds -fvisibility=default to CFLAGS of gmp when building for wasm. This is required to generate the ghc-bignum shared library without linking errors. Clang defaults to -fvisibility=hidden for wasm targets, which will cause issues when a symbol is expected to be exported in a shared library but without explicit visibility attribute annotation. - - - - - 775410fd by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: re-enable PIC for gmp on wasm This commit re-enables --with-pic=yes configuration option of gmp when building for wasm, given we're about to include support for shared libraries, TH and ghci. - - - - - b45080a3 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: add the host_fully_static flavour transformer This commit adds the host_fully_static flavour transformer to hadrian, which ensures stage0 is fully statically linked while still permitting stage1 libdir to contain shared libraries. This is intended to be used by the wasm backend to build portable linux bindists that contain wasm shared libraries. - - - - - 5043507c by Cheng Shao at 2024-10-17T16:41:18+00:00 ci: update wasm jobs configuration This commit bumps ci-image revision to use updated wasm toolchain, and use host_fully_static instead of fully_static for wasm jobs so to ensure wasm shared libraries can be properly built. - - - - - 2956a3f7 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian/testsuite: implement config.cross logic This commit implements the config.cross field in the testsuite driver. It comes from the "cross compiling" ghc info field for both in-tree/out-of-tree GHC, and is an accurate predicate of whether we're cross-compiling or not (compared to the precense of target emulator), and is useful to implement predicates to assert the precense of internal interpreter (only available on non-cross GHC) for tests that do require it (e.g. plugins). - - - - - 8c74a0ed by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian/compiler: implement targetRTSLinkerOnlySupportsSharedLibs This patch implements the targetRTSLinkerOnlySupportsSharedLibs predicate in hadrian. Its definition in hadrian is the single source of truth, and the information propagates to ghc settings file, ghc driver and testsuite driver. It is used in various places to ensure dynamic dependency is selected when the target RTS linker only supports loading dynamic code. - - - - - b4c3c340 by Cheng Shao at 2024-10-17T16:41:18+00:00 testsuite: don't use host cpu features when testing cross ghc This patch disables CPU feature detection logic when testing cross GHC, since those features don't make sense for the target anyway. - - - - - 3c21b696 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: implement & use req_plugins predicate This commit implements req_plugins predicate to indicate that the test requires plugin functionality. Currently this means cross GHC is disabled since internal-interpreter doesn't work in cross GHC yet. - - - - - 93b8af80 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: make use of config.interp_force_dyn This commit takes config.interp_force_dyn into consideration when setting up TH/ghci way flags. - - - - - 94673d41 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: bump T17572 timeout - - - - - 2b5efc2d by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: bump T22744 pre_cmd timeout - - - - - 45102e2a by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip terminfo_so for cross ghc - - - - - 05e40406 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: fix shared library size tests for cross ghc This commit fixes shared library size tests (e.g. array_so in testsuite/tests/perf/size/all.T) when testing cross ghc. Previously, if shared library file extension of host and target differs, those tests will fail with framework errors due to not finding the right files. - - - - - fa68f833 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip ghc api tests that attempt to spawn processes inside wasm This commit skips a few ghc api tests on wasm, since they would attempt to spawn processes inside wasm, which is not supported at all. - - - - - 1241c04e by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip T22840 due to broken -dtag-inference-checks on wasm - - - - - 78c8b900 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: ensure $(ghciWayFlags) can be overridden This commit revises boilerplate.mk in testsuite as well as a few other places, to ensure the tests that do make use of $(ghciWayFlags) can receive the right $(ghciWayFlags) from testsuite driver config. - - - - - 47989ecc by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: skip rdynamic on wasm - - - - - fefb4ea1 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: skip T2615 on wasm This commit marks T2615 as skip on wasm, given LD_* environment variables aren't supported on wasm anyway. - - - - - 77c79762 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: mark MultiLayerModulesTH_Make/MultiLayerModulesTH_OneShot as fragile on wasm - - - - - 69bb4745 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: fix T16180 on wasm This commit fixes T16180 on wasm once TH support is flipped on. The fix is simply adding right asm code for wasm. - - - - - 621c753d by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: fix -fexternal-interpreter flag for JS backend Previously, -fexternal-interpreter is broken for JS backend, since GHC would attempt to launch a non-existent ghc-iserv* executable. This commit fixes it by adjusting pattern matching order in setTopSessionDynFlags. - - - - - 80aa8983 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: use interpreterDynamic predicate in preloadLib This commit use the interpreterDynamic predicate in preloadLib to decide if we should do dynLoadObjs instead of loadObj. Previously we used hostIsDynamic which was only written with non-cross internal interpreter in mind. The testsuite is also adjusted to remove hard-wired -fPIC flag for cbits (doesn't work in i386 RTS linker in vanilla way, #25260) and properly pass ghc_th_way_flags to ghc. - - - - - 74411461 by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix Cmm dynamic CLabels for wasm This commit fixes the handling of dynamic CLabels for the wasm backend. Just do the simplest handling: preserve the original CLabel, both unreg/NCG backends can handle them properly without issue. - - - - - f6abaf13 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: add necessary compile-time flags for wasm PIC mode This commit adds necessary compile-time flags when compiling for wasm PIC mode, see added comment for detailed explanation. - - - - - 9745fcfb by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: add necessary link-time flags for wasm shared libs This commit adds necessary link-time flags for wasm shared libs, see added comments for detailed explanation. - - - - - 649aae00 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: enforce -fno-use-rpaths for wasm This commit ensures the GHC driver never passes any RPATH-related link-time flags on wasm, which is not supported at all. - - - - - 47baa904 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: ensure static archives are picked when linking static .wasm modules This commit ensures static archives are picked when linking .wasm modules which are supposed to be fully static, even when ghc may be invoked with -dynamic, see added comment for explanation. - - - - - fc3a5591 by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix dynamic_too_enable for targets that require dynamic libraries This commit fixes dynamic_too_enable for targets whose RTS linker can only load dynamic code. - - - - - 94ef949e by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix checkNonStdWay for targets that require dynamic libraries This commit fixes checkNonStdWay to ensure that for targets whose RTS linker can only load dynamic code, the dynamic way of object is selected. - - - - - 88e99248 by Cheng Shao at 2024-10-17T16:41:24+00:00 ghc-bin: enforce dynamic way when the target requires so This commit makes ghc-bin use dynamic way when it is doing interactive stuff on certain targets whose RTS linker can only handle dynamic code. - - - - - 549582ef by Cheng Shao at 2024-10-17T16:41:24+00:00 hadrian/ghci: add wasm dyld This commit adds the wasm dynamic linker implementation, as well as ghci logic to call it and hadrian logic to install it to the correct location. See the top-level note in utils/jsffi/dyld.mjs for more details. - - - - - b562e3a6 by Cheng Shao at 2024-10-17T16:41:29+00:00 driver: fix getGccSearchDirectory for wasm target This commit fixes getGccSearchDirectory logic for wasm target, ensures the correct search directory containing libc.so etc can be found by GHC. getGccSearchDirectory is also exported so it can be used elsewhere to obtain the wasi-sdk libdir and pass to the dyld script. - - - - - 2d6107dc by Cheng Shao at 2024-10-17T16:41:29+00:00 driver: add wasm backend iserv logic This commit adds wasm backend iserv logic to the driver, see added comments for explanation. - - - - - 61f5baa5 by Cheng Shao at 2024-10-17T16:41:29+00:00 compiler: add PIC support to wasm backend NCG This commit adds support for generating PIC to the wasm backend NCG. - - - - - 652e7239 by Cheng Shao at 2024-10-17T16:41:29+00:00 hadrian/compiler: flip on support for shared libs & ghci for wasm This commit flips on the support for shared libs and ghci for the wasm target, given all required support logic has been added in previous commits. - - - - - 74a1f681 by Cheng Shao at 2024-10-17T16:41:29+00:00 testsuite: flip on support for shared libs, TH & ghci for wasm This commit flips on support for shared libs, TH & ghci for wasm in the testsuite, given support has been landed in previous commits. - - - - - 525d451e by Cheng Shao at 2024-10-17T23:03:34-04:00 Revert "compiler: start deprecating cmmToRawCmmHook" This reverts commit 1c064ef1f3e1aa2afc996e962ad53effa99ec5f4. Turns out the GHC-WPC project does use it to observe Cmm in the pipeline, see #25363. - - - - - 5bcfefd5 by Cheng Shao at 2024-10-17T23:04:09-04:00 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. - - - - - eb67875f by Matthew Craven at 2024-10-18T12:18:35+00:00 Bump transformers submodule The svg image files mentioned in transformers.cabal were previously not checked in, which broke sdist generation. - - - - - 366a1109 by Matthew Craven at 2024-10-18T12:18:35+00:00 Remove reference to non-existent file in haddock.cabal - - - - - 826852e9 by Matthew Craven at 2024-10-18T12:18:35+00:00 Move tests T11462 and T11525 into tests/tcplugins - - - - - dbe27152 by Matthew Craven at 2024-10-18T12:18:35+00:00 Repair the 'build-cabal' hadrian target Fixes #23117. Fixes #23281. Fixes #23490. This required: * Updating the bit-rotted compiler/Setup.hs and its setup-depends * Listing a few recently-added libraries and utilities in cabal.project-reinstall * Setting allow-boot-library-installs to 'True' since Cabal now considers the 'ghc' package itself a boot library for the purposes of this flag Additionally, the allow-newer block in cabal.project-reinstall was removed. This block was probably added because when the libraries/Cabal submodule is too new relative to the cabal-install executable, solving the setup-depends for any package with a custom setup requires building an old Cabal (from Hackage) against the in-tree version of base, and this can fail un-necessarily due to tight version bounds on base. However, the blind allow-newer can also cause the solver to go berserk and choose a stupid build plan that has no business succeeding, and the failures when this happens are dreadfully confusing. (See #23281 and #24363.) Why does setup-depends solving insist on an old version of Cabal? See: https://github.com/haskell/cabal/blob/0a0b33983b0f022b9697f7df3a69358ee9061a89/cabal-install/src/Distribution/Client/ProjectPlanning.hs#L1393-L1410 The right solution here is probably to use the in-tree cabal-install from libraries/Cabal/cabal-install with the build-cabal target rather than whatever the environment happens to provide. But this is left for future work. - - - - - b3c00c62 by Matthew Craven at 2024-10-18T12:18:35+00:00 Revert "CI: Disable the test-cabal-reinstall job" This reverts commit 38c3afb64d3ffc42f12163c6f0f0d5c414aa8255. - - - - - a04959b8 by Daneel Yaitskov at 2024-10-19T09:34:15-04:00 base: speed up traceEventIO and friends when eventlogging is turned off #17949 Check the RTS flag before doing any work with the given lazy string. Fix #17949 Co-authored-by: Michael Peyton Jones <me at michaelpj.com> Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - eff16c22 by Matthew Pickering at 2024-10-19T21:55:55-04:00 ci: Add support for ONLY_JOBS variable to trigger any validation pipeline By setting the ONLY_JOBS variable to the name of the job (or multiple jobs), the resulting pipeline will include a validation job for that pipeline. For example - if you set ONLY_JOBS="x86_64-linux-ubuntu22_04-validate" then a ubuntu22_04 job will be included in the validation pipeline. This is useful for testing specific jobs. Fixes #25332 - - - - - 280b6278 by Zubin Duggal at 2024-10-19T21:56:31-04:00 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit d83f5bd730a8aef37d8a38b3560590d9798f8e45) - - - - - 25edf849 by Alan Zimmerman at 2024-10-19T21:57:08-04:00 EPA: Remove [AddEpAnn] Commit 4 EPA: Remove [AddEpAnn] from DataDecl This is quite a big change. The most important part is moving the annotations into HsDataDefn, using a specific annotation data type. It has a knock-on to everything that uses HsDataDefn EPA: Remove [AddEpAnn] for FunDep EPA: Remove [AddEpann] from FamilyDecl EPA: Remove [AddEpAnn] From InjectivityAnn EPA: Remove [AddEpAnn] from DefaultDecl EPA: Remove [AddEpAnn] from RuleDecls EPA: Remove [AddEpAnn] from Warnings - - - - - d5f42045 by Luite Stegeman at 2024-10-20T16:34:47-04:00 Interpreter: Add locking for communication with external interpreter This adds locking to communication with the external interpreter to prevent concurrent tasks interfering with each other. This fixes Template Haskell with the external interpreter in parallel (-j) builds. Fixes #25083 - - - - - d6bfea76 by Matthew James Kraai at 2024-10-20T16:35:29-04:00 Use monospace font for "Either a b" in fmap docs The documentation for fmap shows "`Either a b`" in the default font instead of showing "Either a b" in a monospace font. - - - - - 4bc7f9c8 by Luite Stegeman at 2024-10-20T16:36:15-04:00 Parser: remove non-ASCII characters from Parser.y Non-ASCII characters in the source causes a problem with the default Haskell Language Server setup in VSCode. Two characters seems to have been left in by accident. Workaround for #25396 - - - - - 7f61ed4e by Alan Zimmerman at 2024-10-21T06:39:45-04:00 EPA: Remove [AddEpAnn] Commit 5 EPA: Remove [AddEpAnn] from AnnPragma EPA: Remove [AddEpAnn] From ForeignDecl EPA: Remove [AddEpAnn] from RoleAnnotDecl EPA: Remove [AddEpAnn] from StandaloneKindSig EPA: Remove [AddEpAnn] From HsDeriving EPA: Remove [AddEpAnn] from ConDeclField EPA: Remove [AddEpAnn] from ConDeclGADT EPA: Remove [AddEpAnn] from ConDeclH98 EPA: Remove [AddEpAnn] from ClsInstDecl - - - - - f8694fe7 by Cheng Shao at 2024-10-21T06:40:21-04:00 wasm: bump dyld v8 heap size limit This patch adds `--max-old-space-size=8192` to wasm dyld shebang arguments to bump V8 heap size limit. The default limit (`heap_size_limit` returned by `v8.getHeapStatistics()`) is dynamically determined and a bit too low under certain workloads, and V8 would waste too much CPU time to garbage collect old generation heap more aggressively. Bumping the limit to 8G doesn't imply dyld would really take that much memory at run-time, but it lessens V8 heap stress significantly. - - - - - d328d173 by Luite Stegeman at 2024-10-21T12:39:18+00:00 Add requestTickyCounterSamples to GHC.Internal.Profiling This allows the user to request ticky counters to be written to the eventlog at specific times. See #24645 - - - - - 71765b1d by Simon Peyton Jones at 2024-10-21T20:55:00-04:00 Move defaulting code into a new module GHC.Tc.Solver had reached 4,000 lines -- although quite a lot of them are comments. This MR * Adds the new module GHC.Tc.Solver.Default, which has all the complex, but well modularised, defaulting code * Moves a bit of code from GHC.Tc.Solver into the existing GHC.Tc.Solver.Solve. Notably solveWanteds and simplifyWantedsTcM, which are called from GHC.Tc.Solver.Default It's a pure refactor. No code changes. - - - - - a398227b by Simon Peyton Jones at 2024-10-21T20:55:00-04:00 Improve the generalisation code in Solver.simplifyInfer The code in `decideQuantification` has become quite complicated. This MR straightens it out, adds a new Note, and on the way fixes #25266. See especially Note [decideAndPromoteTyVars] which is is where all the action happens in this MR. - - - - - 148059fe by Andrzej Rybczak at 2024-10-21T20:55:40-04:00 Adjust catches to properly rethrow exceptions https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13302 implemented exception rethrowing proposal, but it didn't adjust `catches`. This fixes it. - - - - - 25121dbc by doyougnu at 2024-10-22T09:38:18-04:00 linker: add --optimistic-linking flag This patch adds: - the --optimistic-linking flag which binds unknown symbols in the runtime linker to 0xDEADBEEF instead of exiting with failure - The test T25240 which tests these flags using dead code in the FFI system. - closes #25240 This patch is part of the upstreaming haskell.nix patches project. - - - - - f19e076d by doyougnu at 2024-10-22T09:38:18-04:00 ghc-internal: hide linkerOptimistic in MiscFlags - - - - - edc02197 by Cheng Shao at 2024-10-22T09:38:54-04:00 hadrian: fix bindist executable wrapper logic for cross targets This commit fixes an oversight of hadrian wrapper generation logic: when doing cross compilation, `wrapper` is called on executable names with cross prefix, therefore we must use `isSuffixOf` when matching to take the cross prefix into account. Also add missing cross prefix to ghci wrapper content and fix hsc2hs wrapper logic. - - - - - edf3bdf5 by Andreas Klebinger at 2024-10-22T16:30:42-04:00 mkTick: Push ticks through unsafeCoerce#. unsafeCoerce# doesn't exist at runtime so we should treat it like a Cast for the purpose of mkTick. This means if we have `{-# SCC foo #-} (unsafeCoerce# trivial_expr))` we now push the scope part of the cost centre up to `trivial_expr` at which point we can discard it completely if the expression is trivial enough. This fixes #25212. - - - - - 1bdb1317 by Cheng Shao at 2024-10-22T16:31:17-04:00 hadrian: enable late-CCS for perf flavour as well This patch enables late-CCS for perf flavour so that the testsuite can pass for perf as well. Fixes #25308. - - - - - fde12aba by Cheng Shao at 2024-10-22T16:31:54-04:00 hadrian: make sure ghc-bin internal-interpreter is disabled for stage0 when not cross compiling This patch disables internal-interpreter flag for stage0 ghc-bin when not cross compiling, see added comment for explanation. Fixes #25406. - - - - - 6ab8d751 by ignatiusm at 2024-10-24T01:23:35-04:00 Improve heap overflow exception message (#25198) Catch heap overflow exceptions and suggest using `+RTS -M<size>`. Fix #25198 - - - - - b3f7fb80 by Rodrigo Mesquita at 2024-10-24T01:24:12-04:00 determinism: Interface re-export list det In 'DocStructureItem' we want to make sure the 'Avails' are sorted, for interface file determinism. This commit introduces 'DetOrdAvails', a newtype that should only be constructed by sorting Avails with 'sortAvails' unless the avails are known to be deterministically ordered. This newtype is used by 'DocStructureItem' where 'Avails' was previously used to ensure the list of avails is deterministically sorted by construction. Note: Even though we order the constructors and avails in the interface file, the order of constructors in the haddock output is still determined from the order of declaration in the source. This was also true before, when the list of constructors in the interface file <docs> section was non-deterministic. Some haddock tests such as "ConstructorArgs" observe this (check the order of constructors in out/ConstructorArgs.html vs src/ConstructorArgs.hs vs its interface file) The updated tests are caused by haddock corners where the order in the source is not preserved (and was non-deterministic before this PR): * Module header in the latex backend * Re-export of pattern synonyms associated to a datatype (#25342) Fixes #25304 - - - - - e39c8c99 by Rodrigo Mesquita at 2024-10-24T01:24:12-04:00 Revert "ci: Allow abi-test to fail." After #25304, the abi-test with interface and object determinism succeeds. This reverts commit 7b37afc9f3e79559055488998ee73187886a0e00. - - - - - 7b1b0c6d by Alan Zimmerman at 2024-10-24T13:07:02-04:00 EPA: reduce [AddEpann] in AnnList Remove it from the `al_rest` field, and make `AnnList` parameterized on a type to be used in `al_rest`, for the various use cases. - - - - - 4a00731e by Rodrigo Mesquita at 2024-10-24T13:07:38-04:00 Fix -fobject-determinism flag definition The flag should be defined as an fflag to make sure the -fno-object-determinism flag is also an available option. Fixes #25397 - - - - - 55e4b9f2 by Sebastian Graf at 2024-10-25T07:01:54-04:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - 9f57c96d by Sebastian Graf at 2024-10-25T07:01:54-04:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * I reworked the whole narrative around "Tag inference". It's now called "EPT enforcement" and I recycyled the different overview Notes into `Note [EPT enforcement]`. * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Compiler perf generally improves, sometimes drastically: Baseline Test Metric value New value Change -------------------------------------------------------------------------------- ManyConstructors(normal) ghc/alloc 3,629,760,116 3,711,852,800 +2.3% BAD MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,502,735,440 2,565,282,888 +2.5% BAD T12707(normal) ghc/alloc 804,399,798 791,807,320 -1.6% GOOD T17516(normal) ghc/alloc 964,987,744 1,008,383,520 +4.5% T18140(normal) ghc/alloc 75,381,152 49,860,560 -33.9% GOOD T18698b(normal) ghc/alloc 232,614,457 184,262,736 -20.8% GOOD T18923(normal) ghc/alloc 62,002,368 58,301,408 -6.0% GOOD T20049(normal) ghc/alloc 75,719,168 70,494,368 -6.9% GOOD T3294(normal) ghc/alloc 1,237,925,833 1,157,638,992 -6.5% GOOD T9233(normal) ghc/alloc 686,490,105 635,166,688 -7.5% GOOD geo. mean -0.7% minimum -33.9% maximum +4.5% I looked at T17516. It seems we do a few more simplifier iterations and end up with a larger program. It seems that some things inline more, while other things inline less. I don't see low-hanging fruit. I also looked at MultiLayerModulesTH_OneShot. It appears we generate a strange join point in the `getUnique` method of `Uniquable GHC.Unit.Types.Module` that should better call-site inline, but does not. Perhaps with !11492. NoFib does not seem affected much either: +-------------------------------++--+------------+-----------+---------------+-----------+ | || | base/ | std. err. | T20749/ (rel) | std. err. | +===============================++==+============+===========+===============+===========+ | spectral/last-piece || | 7.263e8 | 0.0% | +0.62% | 0.0% | +===============================++==+============+===========+===============+===========+ | geom mean || | +0.00% | | | | +-------------------------------++--+------------+-----------+---------------+-----------+ I had a look at last-piece. Nothing changes in stg-final, but there is a bit of ... movement around Data.Map.insert's use of GHC.Exts.lazy that is gone in stg-final. Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> Metric Decrease: T12707 T18140 T18698b T18923 T19695 T20049 T3294 T9233 T21839c Metric Increase: ManyConstructors MultiLayerModulesTH_OneShot - - - - - 0225249a by Simon Peyton Jones at 2024-10-25T07:02:32-04:00 Some renaming This is a pure refactor, tidying up some inconsistent naming: isEqPred --> isEqClassPred isEqPrimPred --> isEqPred isReprEqPrimPred --> isReprEqPred mkPrimEqPred --> mkNomEqPred mkReprPrimEqPred --> mkReprEqPred mkPrimEqPredRold --> mkEqPredRole Plus I moved mkNomEqPred, mkReprEqPred, mkEqPredRolek from GHC.Core.Coercion to GHC.Core.Predicate where they belong. That means that Coercion imports Predicate rather than vice versa -- better. - - - - - 15a3456b by Ryan Hendrickson at 2024-10-25T07:02:32-04:00 compiler: Fix deriving with method constraints See Note [Inferred contexts from method constraints] Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - dbc77ce8 by Alan Zimmerman at 2024-10-25T18:20:13+01:00 EPA: Remove AddEpann commit 7 EPA: Remove [AddEpAnn] from HYPHEN in Parser.y The return value is never used, as it is part of the backpack configuration parsing. EPA: Remove last [AddEpAnn] usages Remove residual usage in GHC. It is still used - In haddock TTG extension point definitions (to be removed) - Some check-exact residual, to be removed - Comments around DisambECP in PostProcess EPA: Clean up [AddEpAnn] from check-exact There is one left, to be cleaned up when we remove AddEpann itself EPA: Remove [AddEpAnn] from haddock The TTG extension points need a value, it is not critical what that value is, in most cases. EPA: Remove AddEpAnn from HsRuleAnn EPA: Remove AddEpAnn from HsCmdArrApp - - - - - 23ddcc01 by Simon Peyton Jones at 2024-10-26T12:44:34-04:00 Fix optimisation of InstCo It turned out (#25387) that the fix to #15725 was not quite right: commit 48efbc04bd45d806c52376641e1a7ed7278d1ec7 Date: Mon Oct 15 10:25:02 2018 +0200 Fix #15725 with an extra Sym Optimising InstCo is quite subtle, and the invariants surrounding the LiftingContext in the coercion optimiser were not stated explicitly. This patch refactors the InstCo optimisation, and documents these invariants. See * Note [Optimising InstCo] * Note [The LiftingContext in optCoercion] I also did some refactoring of course: * Instead of a Bool swap-flag, I am not using GHC.Types.Basic.SwapFlag * I added some invariant-checking the coercion-construction functions in GHC.Core.Coercion.Opt. (Sadly these invariants don't hold during typechecking, becuase the types are un-zonked, so I can't put these checks in GHC.Core.Coercion.) - - - - - 589fea7f by Cheng Shao at 2024-10-27T05:36:38-04:00 ghcid: use multi repl for ghcid - - - - - d52a0475 by Andrew Lelechenko at 2024-10-27T05:37:13-04:00 documentation: add motivating section to Control.Monad.Fix - - - - - 301c3b54 by Cheng Shao at 2024-10-27T05:37:49-04:00 wasm: fix safari console error message related to import("node:timers") This patch fixes the wasm backend JSFFI prelude script to avoid calling `import("node:timers")` on non-deno hosts. Safari doesn't like it and would print an error message to the console. Fixes https://gitlab.haskell.org/ghc/ghc-wasm-meta/-/issues/13. - - - - - 9f02dfb5 by Simon Peyton Jones at 2024-10-27T15:10:08-04:00 Add a missing tidy in UnivCo We were failing to tidy the argument coercions of a UnivCo, which led directly to #25391. The fix is, happily, trivial. I don't have a small repro case (it came up when building horde-ad, which uses typechecker plugins). It should be possible to make a repro case, by using a plugin (which builds a UnivCo) but I decided it was not worth the bother. The bug is egregious and easily fixed. - - - - - 853050c3 by Andrew Lelechenko at 2024-10-27T15:10:44-04:00 Bump text submodule to 2.1.2 - - - - - 90746a59 by Andrew Lelechenko at 2024-10-27T15:10:44-04:00 hadrian: allow -Wunused-imports for text package - - - - - 8a6691c3 by Alan Zimmerman at 2024-10-27T19:44:48+00:00 EPA: Remove AddEpAnn Commit 8/final EPA: Remove AddEpAnn from AnnList EPA: Remove AddEpAnn from GrhsAnn This is the last actual use EPA: Remove NameAdornment from NameAnn Also rework AnnContext to use EpToken, and AnnParen EPA: Remove AddEpAnn. Final removal There are now none left, except for in a large note/comment in PostProcess, describing the historical transition to the disambiguation infrastructure - - - - - d5e7990c by Alan Zimmerman at 2024-10-28T21:41:05+00:00 EPA: Remove AnnKeywordId. This was used as part of AddEpAnn, and is no longer needed. Also remove all the haddock comments about which of are attached to the various parts of the AST. This is now clearly captured in the appropriate TTG extension points, and the `ExactPrint.hs` file. - - - - - e08b8370 by Serge S. Gulin at 2024-10-29T23:17:01-04:00 JS: Re-add optimization for literal strings in genApp (fixes #23479) Based on https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10588/ Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> Co-authored-by: Danil Berestov <goosedb at yandex.ru> ------------------------- Metric Decrease: T25046_perf_size_gzip size_hello_artifact size_hello_artifact_gzip size_hello_unicode size_hello_unicode_gzip ------------------------- - - - - - e3496ef6 by Cheng Shao at 2024-10-29T23:17:37-04:00 compiler: remove unused hscDecls/hscDeclsWithLocation This patch removes unused `hscDecls`/`hscDeclsWithLocation` functions from the compiler, to reduce maintenance burden when doing refactorings related to ghci. - - - - - b1eed26f by Cheng Shao at 2024-10-29T23:18:13-04:00 testsuite: add T25414 test case marked as broken This commit adds T25414 test case to demonstrate #25414. It is marked as broken and will be fixed by the next commit. - - - - - e70009bc by Cheng Shao at 2024-10-29T23:18:13-04:00 driver: fix foreign stub handling logic in hscParsedDecls This patch fixes foreign stub handling logic in `hscParsedDecls`. Previously foreign stubs were simply ignored here, so any feature that involve foreign stubs would not work in ghci (e.g. CApiFFI). The patch reuses `generateByteCode` logic and eliminates a large chunk of duplicate logic that implements Core to bytecode generation pipeline here. Fixes #25414. - - - - - 1d7cd7fe by Andreas Klebinger at 2024-10-30T19:14:28-04:00 Add since tag for -fwrite-if-compression in user guide. Partial fix for #25395 - - - - - b349fd1b by Alan Zimmerman at 2024-10-30T19:15:04-04:00 EPA: Remove some unused functions - - - - - f859d61c by Alan Zimmerman at 2024-10-30T19:15:04-04:00 EPA: use explicit vertical bar token for ExplicitSum / SumPat - - - - - 721ac00d by Ben Gamari at 2024-10-31T08:37:38-04:00 rts/Disassembler: Fix encoding of BRK_FUN instruction The offset of the CC field was not updated after the encoding change in b85b11994e0130ff2401dd4bbdf52330e0bcf776. Fix this. Fixes #25374. - - - - - 0bc94360 by Alan Zimmerman at 2024-10-31T08:38:15-04:00 EPA: Bring in last EpToken usages For import declarations, NameAnnCommas and NPlusKPat. And remove anchor, it is the same as epaLocationRealSrcSpan. - - - - - 0b11cdc0 by sheaf at 2024-10-31T08:38:55-04:00 Assert that ctEvCoercion is called on an equality Calling 'ctEvCoercion' on non-equality constraints is always incorrect. We add an assertion to this function to detect such cases; for example a type-checking plugin might erroneously do this. - - - - - ea458779 by doyougnu at 2024-11-01T18:11:33-04:00 ghc-internal: strict, unboxed src loc ranges - closes: #20449 - See CLC proposal: #55 - - - - - 778ac793 by Kazuki Okamoto at 2024-11-01T18:12:13-04:00 No haddock markup in doctest line - - - - - cf0deeaf by Andreas Klebinger at 2024-11-02T17:54:52-04:00 Reword -fexpose-overloaded-unfoldings docs. This should make them slightly clearer. Fixes #24844 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> - - - - - 1c21e7d4 by Andreas Klebinger at 2024-11-02T17:55:29-04:00 Compile T25062 simd tests even if we can't run them. Helps avoid them being utterly broken. Fixes #25341 - - - - - 573cad4b by Cheng Shao at 2024-11-02T17:56:04-04:00 Remove unused USE_REPORT_PRELUDE code paths from the tree This patch removes unused `USE_REPORT_PRELUDE` code paths from the tree. They have been present since the first git revision 4fb94ae5e5d632748fa2e6c35e259eccc5a1a3f4, and might have been useful for debugging purposes many years ago, but these code paths are never actually built. Removing these ease maintenance of relevant modules in the future, and also allows us to get rid of `CPP` extension in those modules as a nice byproduct. - - - - - 97f600c6 by Hassan Al-Awwadi at 2024-11-04T15:52:12+00:00 Refactored BooleanFormula to be in line with TTG (#21592) There are two parts to this commit. * We moved the definition of BooleanFormula over to L.H.S.BooleanFormula * We parameterized the BooleanFormula over the pass The GHC specific details of BooleanFormula remain in Ghc.Data.BooleanFormula. Because its parameterized over the pass its no longer a functor or traversable, but we defined bfMap and bfTraverse for the cases where we needed fmap and traverse originally. Most other changes are just churn. ------------------------- Metric Decrease: MultiLayerModulesTH_OneShot ------------------------- - - - - - d4fd3580 by Andreas Klebinger at 2024-11-05T07:36:16-05:00 ghc-heap: Fix incomplete selector warnings. Use utility functions instead of selectors to read partial attributes. Part of fixing #25380. - - - - - fdd9f62a by Peter Trommler at 2024-11-05T07:36:51-05:00 PPC NCG: Implement fmin and fmax - - - - - 8e217256 by Mike Pilgrem at 2024-11-07T04:34:20-05:00 Re CLC #293 - Don't specify Data.List.NonEmpty in terms of partial See https://github.com/haskell/core-libraries-committee/issues/293 `List.init` had already been driven out of `tails1` by 21fc180bec93d964a7f4ffdf2429ef6f74b49ab6 but this specification also avoided partial `fromList`, so I preferred it. The `changelog.md` for `base` is updated, with an entry added under `base-4.22.0.0`. - - - - - 346e4cd1 by Zubin Duggal at 2024-11-07T04:34:57-05:00 release: copy zip files into the correct directory Fixes #25446 - - - - - bbdbe225 by Zubin Duggal at 2024-11-07T04:34:57-05:00 release: Sign .gz bindists too Fixes #25447 - - - - - 0c722e14 by Hécate Kleidukos at 2024-11-07T04:35:37-05:00 hadrian: Enforce the usage of GHC >=9.8.1 for ghci-multi GHC 9.6 no good when it comes to multi-repl stuff, despite being well within the range of n-2 releases for bootstrapping, when the script was adapted to load haddock, in !12851 - - - - - d8f8a1c3 by Sylvain Henry at 2024-11-07T19:27:46-05:00 Handle the special ghc-prim:GHC.Prim module in the compiler Before this patch, some custom hacks were necessary in ghc-prim's Setup.hs to register the GHC.Prim (virtual) module and in Hadrian to generate haddocks properly. In this patch we special-case this module in the compiler itself instead (which it already is, see ghcPrimIface in GHC.Iface.Load). From Cabal/Hadrian's perspective GHC.Prim is now just a normal autogenerated module. This simplification is worthwhile on its own. It was found while looking into the work needed for #24453 which aims to merge ghc-prim, ghc-bignum, and ghc-internal. It's also one step closer to remove ghc-prim's custom setup. - - - - - a55adc8e by Cheng Shao at 2024-11-07T19:28:22-05:00 Clean up obsolete CPP guarded code paths from the tree This patch cleans up obsolete CPP guarded code paths from the tree. The minimum supported boot GHC version is 9.6, and all the pre-9.6 era code paths can be removed. - - - - - 9ede97f3 by Cheng Shao at 2024-11-07T19:28:58-05:00 Remove obsolete executable wrappers from the tree The executable wrappers are handled by hadrian and bindist Makefile. The various .wrapper scripts in the tree are unused since removal of Make build system, so this patch removes them all. - - - - - 7d42b2df by tristian at 2024-11-07T19:29:40-05:00 TcRnDuplicateDecls now suggests to use the DuplicateRecordFields extension. Fixes: !24627 - - - - - e56ed179 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: normalise some versions in callstacks (cherry picked from commit f230e29f30d0c1c566d4dd251807fcab76a2710e) - - - - - a28fc903 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: use -fhide-source-paths to normalise some backpack tests (cherry picked from commit b19de476bc5ce5c7792e8af1354b94a4286a1a13) - - - - - ed16d303 by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite/haddock: strip version identifiers and unit hashes from html tests (cherry picked from commit fbf0889eadc410d43dd5c1657e320634b6738fa5) - - - - - e45e5836 by Zubin Duggal at 2024-11-11T15:16:36+05:30 haddock: oneshot tests can drop files if they share modtimes. Stop this by including the filename in the key. Ideally we would use `ghc -M` output to do a proper toposort Partially addresses #25372 (cherry picked from commit e78c7ef96e395f1ef41f04790aebecd0409b92b9) - - - - - 9104e6eb by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: fix normalisation of T9930fail so that it doesn't get tripped up by ghc executable (ARGV[0]) differences (cherry picked from commit a79a587e025d42d34bb30e115fc5c7cab6c1e030) - - - - - 2c31264a by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: normalise windows file seperators (cherry picked from commit f858875e03b9609656b542aaaaff85ad0a83878a) - - - - - 2807f91b by Zubin Duggal at 2024-11-11T15:21:30+05:30 testsuite: Also match <VERSION> placeholders when normalising callsites - - - - - c02add17 by Ben Gamari at 2024-11-12T01:22:11-05:00 configure: Check version number validity Here we verify the previously informal invariant that stable release version numbers must have three components, preventing costly failed releases. Specifically, the check fails in the following scenarios: * `version=9.13` while `RELEASE=YES` since this would imply a release made from an unstable branch * `version=9.13.0` since unstable versions should only have two components * `version=9.12` since this has the wrong number of version components for a stable branch Fixes #25390. - - - - - 747fd322 by Teo Camarasu at 2024-11-12T01:22:49-05:00 docs: link to #14474 in the template-haskell docs - - - - - 6d96bb62 by Zubin Duggal at 2024-11-12T01:23:25-05:00 testsuite: normalise execvp vs exec differences in process tests Fixes #25431 - - - - - 502e6711 by Torsten Schmits at 2024-11-12T01:24:01-05:00 fix test lint that accumulated while the checks were broken I didn't fix the issues flagged by the #ifdef linter because it were so many that it seemed like the rule has become obsolete. - - - - - 223a4cb5 by Torsten Schmits at 2024-11-12T01:24:02-05:00 test driver: fix file collection for regex linters When a testsuite linter is executed with the `tracked` strategy, the driver runs `git ls-tree` to collect eligible files. This appears to have ceased producing any paths – `ls-tree` restricts its results to the current working directory, which is `testsuite/tests/linters` in this case. As a quick fix, this patch changes the working directory to match expectations. - - - - - 9ad9ac63 by Alan Zimmerman at 2024-11-12T01:24:39-05:00 EPA: Capture location of '_' for wild card type binder And keep track of promotion status in HsExplicitTupleTy, so the round-trip ppr test works for it. Updates Haddock output too, using the PromotionFlag in HsExplicitTupleTy. Closes #25454 - - - - - c37b96fa by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix setImmediate() implementation for Cloudflare Workers This patch fixes setImmediate() implementation for Cloudflare Workers in the wasm backend's js prelude script. Cloudflare Workers doesn't support the MessageChannel API, and we use a setTimeout() based fallback implementation in this case. - - - - - bea8ea4c by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix FinalizationRegistry logic for Cloudflare Workers This patch fixes FinalizationRegistry related logic for Cloudflare Workers in wasm backend js post linker. Cloudflare Workers doesn't support FinalizationRegistry, in this case we use a dummy implementation that doesn't do anything. - - - - - 00d551bf by Cheng Shao at 2024-11-13T08:48:21-05:00 Remove obsolete cross-port script This patch removes the obsolete cross-port script in the tree. The script was based on the legacy Make build system which has been pruned from the tree long ago. For hadrian, proper support for two-stage bootstrapping onto a new unsupported platform is a work in progress in !11444. - - - - - 75a2eae4 by Cheng Shao at 2024-11-13T08:48:58-05:00 hadrian: fix bindist makefile for wasm32-wasi target This patch fixes one incoherent place between bindist makefile and hadrian logic: I forgot to include wasi/wasm32 in OsSupportsGHCi/ArchSupportsGHCi as well. And this results in incorrect settings file generated after installing the bindist, and "Use interpreter"/"Have interpreter" fields incorrectly have "NO" values where they should be "YES" like --info output of in-tree version. - - - - - 0614abef by Alan Zimmerman at 2024-11-13T08:49:34-05:00 EPA: Correctly capture leading semis in decl list Closes #25467 - - - - - 00d58ae1 by Sebastian Graf at 2024-11-13T15:21:23-05:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. - - - - - 93233a66 by Ben Gamari at 2024-11-13T15:21:59-05:00 boot: Do not attempt to update config.sub While Apple ARM hardware was new we found that the autoconf scripts included in some boot packages were too old. As a mitigation for this, we introduced logic in the `boot` script to update the `config.sub` with that from the GHC tree. However, this causes submodules which have `config.sub` committted to appear to be dirty. This is a considerable headache. Now since `config.sub` with full platform support is more common we can remove `boot`'s `config.sub` logic. Fixes #19574. - - - - - fa66fa64 by Ryan Scott at 2024-11-14T19:05:00-05:00 Add regression test for #16234 Issue #16234 was likely fixed by !9765. This adds a regression test to ensure that it remains fixed. Fixes #16234. - - - - - bfe64df8 by Matthew Pickering at 2024-11-14T19:05:36-05:00 ghc-internal: Update to Unicode 16 This patch updates the automatically generated code for querying unicode properties to unicode 16. Fixes #25402 - - - - - 1fd83f86 by Ben Gamari at 2024-11-14T19:06:13-05:00 configure: Accept happy-2.1.2 happy-2.1 was released in late Oct 2024. I have confirmed that master bootstraps with it. Here we teach configure to accept this tool. Fixes #25438. - - - - - aa58fc5b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Tighten up invariants of PACK - - - - - 8aa4c10a by Ben Gamari at 2024-11-14T19:06:49-05:00 testsuite: Fix badly escaped literals Use raw string literals to ensure that `\s` is correctly interpreted as a character class. - - - - - 0e084029 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Improve documentation of SLIDE bytecode instruction - - - - - 9bf3663b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Assert that TEST*_P discriminators are valid - - - - - 1f668511 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Improve documentation of TEST*_P instructions - - - - - 59e0a770 by Cheng Shao at 2024-11-14T19:07:25-05:00 misc: improve clangd compile_flags.txt flags This patch improves the compile_flags.txt config used to power clangd for the rts C codebase. The flags in the file are sampled & deduped from a real stage1 build with clang-19 and vastly improves the IDE accuracy when hacking the rts. For maximum code coverage under the default settings, compile_flags.txt defaults to threaded+profiled+dynamic+debug way. This does not mean profdyn needs to be actually built in _build/stage1 for IDE to work. To activate IDE for other RTS ways, simply remove one of the -D flags at the end of compile_flags.txt and restart clangd. - - - - - c2c562e0 by Ben Gamari at 2024-11-14T19:08:01-05:00 testsuite: Don't consider untracked files in dirtiness check Considering trees containing untracked files as dirty is a bridge too far. The chance of an untracked file significantly affecting measured performanced metrics is quite small whereas not collecting measurements is quite inconvenient for some workflows. We now ignore untracked files in the dirtiness check. Fixes #25471. - - - - - ed2ed6c5 by Cheng Shao at 2024-11-14T19:08:37-05:00 testsuite: add regression test T25473 This commit adds regression test T25473 marked as broken due to #25473. It will be fixed in the subsequent commit. - - - - - bd0a8b7e by Cheng Shao at 2024-11-14T19:08:37-05:00 wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. - - - - - f1b0bc32 by Ben Gamari at 2024-11-14T19:09:13-05:00 rts/linker: Make FreeBSD declarations proper prototypes The iconv declarations for FreeBSD were previously not prototypes, leading to warnings. - - - - - 086cbbc1 by Ben Gamari at 2024-11-14T19:09:13-05:00 base: Drop redundant import in FreeBSD ExecutablePath implementation - - - - - 79ecd199 by Ben Gamari at 2024-11-14T19:09:13-05:00 compiler: Fix partial selector warnings in GHC.Runtime.Heap.Inspect - - - - - 1acb73bf by Andrew Lelechenko at 2024-11-15T06:10:47-05:00 gitlab: mention CLC in MR template - - - - - 8f2e0832 by Ben Gamari at 2024-11-15T06:11:24-05:00 rts: Allow use of GNU-stack notes on FreeBSD Previously we gated use of GNU-style non-executable stack notes to only apply on Linux. However, these are also supported by FreeBSD, which also uses ELF. Fix this. Fixes #25475. - - - - - 2c427cb0 by Ben Gamari at 2024-11-16T05:27:40-05:00 rts: Fix EINTR check in timerfd ticker When `poll` failed we previously checked that `errno == -EINTR` to silence the failure warning. However, this is wrong as `errno` values are generally not negated error codes (in contrast to many system call results, which is likely what the original author had in mind). Fixes #25477. - - - - - a0fa4941 by Ben Gamari at 2024-11-16T05:28:16-05:00 rts: Increase gen_workspace alignment to 128 bytes on AArch64 Increase to match the 128-byte cache-line size of Apple's ARMv8 implementation. Closes #25459. - - - - - 142d8afa by Ben Gamari at 2024-11-16T16:20:47-05:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - b7a146e5 by Ben Gamari at 2024-11-16T16:20:47-05:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - ddb7afa6 by Ben Gamari at 2024-11-16T16:21:23-05:00 users guide: Mention language extensions in equality constraints discussion As suggested in #24127, mention the language extensions necessary for usage of equality constriants in their documentation. Closes #24127. - - - - - 36133dac by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/9.14.1-notes: Fix list syntax - - - - - 888de658 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/debug-info: Fix duplicate flag descriptions - - - - - f120e427 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide: Fix reference to 9.14.1 release notes - - - - - 8e975032 by Ben Gamari at 2024-11-16T16:21:59-05:00 Introduce GHC.Tc.Plugin.lookupTHName This makes it significantly more convenient (and less GHC-version-dependent) to resolve a template-haskell name into a GHC Name. As proposed in #24741. - - - - - a0e168ec by ARATA Mizuki at 2024-11-16T16:22:40-05:00 x86 NCG SIMD: Lower packFloatX4#, insertFloatX4# and broadcastFloatX4# to SSE1 instructions Fixes #25441 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 3936bf1b by sheaf at 2024-11-16T16:23:22-05:00 X86 NCG: allow VXOR at scalar floating-point types The NCG can emit VXOR instructions at scalar floating-point types, but the pretty-printer would panic instead of emitting the appropriate VXORPS/VXORPD instructions. This patch rectifies that oversight. Fixes #25455 - - - - - d9dff93a by Ben Gamari at 2024-11-16T16:23:58-05:00 rts: Fix platform-dependent pointer casts Previously we had unnecessary (and incorrect) platform-dependent casts to turn `OSThreadIds`s into a integer. We now just uniformly cast first to a `uintptr_t` (which is always safe, regardless of whether `OSThreadId` is a pointer), and then cast to the desired integral type. This fixes a warning on musl platforms. - - - - - 6d95cdb8 by Ben Gamari at 2024-11-16T16:24:34-05:00 testsuite: Mark encoding004 as broken on FreeBSD Due to #22003, CP936 fails to roundtrip: ```diff == CP936 +Failed to roundtrip given mutant byte at index 891 (251 /= 123 at index 891) +Failed to roundtrip given mutant byte at index 1605 (197 /= 69 at index 1605) +Failed to roundtrip given mutant byte at index 2411 (235 /= 107 at index 2411) +Failed to roundtrip given mutant byte at index 6480 (208 /= 80 at index 6480) +Failed to roundtrip given mutant byte at index 6482 (210 /= 82 at index 6482) +Failed to roundtrip given mutant byte at index 6484 (212 /= 84 at index 6484) +Failed to roundtrip given mutant byte at index 6496 (224 /= 96 at index 6496) +Failed to roundtrip given mutant byte at index 7243 (203 /= 75 at index 7243) +Failed to roundtrip given mutant byte at index 7277 (237 /= 109 at index 7277) +Failed to roundtrip given mutant byte at index 8027 (219 /= 91 at index 8027) +Failed to roundtrip given mutant byte at index 8801 (225 /= 97 at index 8801) ``` - - - - - 26e86984 by Ben Gamari at 2024-11-18T04:05:31-05:00 hadrian: Allow haddock options to be passed via key-value settings - - - - - 6e68b117 by Matthew Pickering at 2024-11-18T04:06:07-05:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - a4e0d235 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 exceptions: Improve the message layout as per #285 This commit fixes the layout of the additional information included when displaying an exception, namely the type of the exception. It also fixes the default handler's heading message to work well together with the improved display message of SomeException. CLC proposal#285 - - - - - 284ffab3 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 Display type and callstack of exception on handler This commit changes the Exception instance of SomeException to *simply* display the underlying exception in `displayException`. The augmented exception message that included the type and backtrace of the exception are now only printed on a call to `displayExceptionWithInfo`. At a surface level, existing programs should behave the same since the `uncaughtExceptionHandler`, which is responsible for printing out uncaught exceptions to the user, will use `displayExceptionWithInfo` by default. However, unlike the instance's `displayException` method, the `uncaughtExceptionHandler` can be overriden with `setUncaughtExceptionHandler`. This makes the extra information opt-in without fixing it the instance, which can be valuable if your program wants to display uncaught exceptions to users in a user-facing way (ie without backtraces). This is what was originally agreed for CLC#231 or CLC#261 with regard to the type of the exception information. The call stack also becoming part of the default handler rather than the Exception instance is an ammendment to CLC#164. Discussion of the ammendment is part of CLC#285. - - - - - 36cddd2c by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Remove redundant CallStack from exceptions Before the exception backtraces proposal was implemented, ErrorCall accumulated its own callstack via HasCallStack constraints, but ExceptionContext is now accumulated automatically. The original ErrorCall mechanism is now redundant and we get a duplicate CallStack Updates Cabal submodule to fix their usage of ErrorCallWithLocation to ErrorCall CLC proposal#285 Fixes #25283 - - - - - 7a74330b by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Freeze call stack in error throwing functions CLC proposal#285 - - - - - 3abf31a4 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 De-duplicate displayContext and displayExceptionContext The former was unused except for one module where it was essentially re-defining displayExceptionContext. Moreover, this commit extends the fix from bfe600f5bb3ecd2c8fa71c536c63d3c46984e3f8 to displayExceptionContext too, which was missing. - - - - - c0d783f8 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Re-export NoBacktrace from Control.Exception This was originally proposed and accepted in section "2.7 Capturing Backtraces on Exceptions" of the CLC proposal for exception backtraces. However, the implementation missed this re-export, which this commit now fixes. - - - - - 802b5c3e by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Fix exception backtraces from GHCi When running the program with `runhaskell`/`runghc` the backtrace should match the backtrace one would get by compiling and running the program. But currently, an exception thrown in a program interpreted with `runhaskell` will: * Not include the original exception backtrace at all * Include the backtrace from the internal GHCi/ghc rethrowing of the original exception This commit fixes this divergence by not annotating the ghc(i) backtrace (with NoBacktrace) and making sure that the backtrace of the original exception is serialized across the boundary and rethrown with the appropriate context. Fixes #25116 The !13301 MR (not this commit in particular) improves performance of MultiLayerModules. Unfortunately, T3294 regresses on aarch64-linux-deb12 by 1% allocations. Since this patch must be merged for 9.12 ASAP, we will not be able to investigate the slight regression on this platform in time. ------------------------- Metric Decrease: MultiLayerModulesRecomp MultiLayerModulesTH_OneShot Metric Increase: T3294 ------------------------- - - - - - 3e89eb65 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 base: Add to changelog.md CLC #285 - - - - - d9326a48 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Bump array and stm submodules for testsuite The testsuites of array and stm had to be updated according to !13301. Updates submodule array and stm. - - - - - 325fcb5d by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Clean up code style of Nativei386 adjustor - - - - - 39bb6e58 by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Fix stack overrun error in Nativei386 adjustor We were reserving the wrong kind of adjustor context (the generic `AdjustorContext` used by other adjustor implementations, rather than the i386-specific `CCallContext`) to return the adjustor context while freeing, resulting in #25485. Fixes #25485. - - - - - 831aab22 by sheaf at 2024-11-18T21:22:36-05:00 Include diagnostic reason in -fdiagnostics-as-json This commit ensures that the -fdiagnostics-as-json output includes the diagnostic reason. This allows the full error message produced by GHC to be re-constructed from the JSON output. Fixes #25403 - - - - - 3e5bfdd3 by Ben Gamari at 2024-11-18T21:23:12-05:00 rts: Introduce printIPE This is a convenience utility for use in GDB. - - - - - 44d909a3 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Don't store boot locations in finder cache Partially reverts commit fff55592a7b Amends add(Home)ModuleToFinder so that locations for boot files are not stored in the finder cache. Removes InstalledModule field from InstalledFound constructor since it's the same as the key that was searched for. - - - - - 64c95292 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Concentrate boot extension logic in Finder With new mkHomeModLocation that takes an extra HscSource to add boot extensions if required. - - - - - 11bad98d by ARATA Mizuki at 2024-11-19T14:39:08-05:00 Better documentation for floating-point min/max and SIMD primitives See #25350 for floating-point min/max Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 791a47b2 by Arnaud Spiwack at 2024-11-20T14:00:05+00:00 Add test for #25185 - - - - - 374e18e5 by Arnaud Spiwack at 2024-11-20T14:09:30+00:00 Quick look: emit the multiplicity of app heads in tcValArgs Otherwise it's not scaled properly by the context, allowing unsound expressions. Fixes #25185. - - - - - 1fc02399 by sheaf at 2024-11-20T18:11:03-05:00 x86 NCG: fix regUsageOfInstr for VMOVU & friends This commit fixes the implementation of 'regUsageOfInstr' for vector operations that take an 'Operand' as the destination, by ensuring that when the destination is an address then the address should be *READ*, and not *WRITTEN*. Getting this wrong is a disaster, as it means the register allocator has incorrect information, which can lead to it discard stores to registers, segfaults ensuing. Fixes #25486 - - - - - 7bd407a6 by Brandon Chinn at 2024-11-21T14:08:15-05:00 Fix CRLF in multiline strings (#25375) - - - - - 7575709b by Rodrigo Mesquita at 2024-11-21T14:08:52-05:00 Improve reachability queries on ModuleGraph Introduces `ReachabilityIndex`, an index constructed from a `GHC.Data.Graph.Directed` `Graph` that supports fast reachability queries (in $O(1)$). This abstract data structure is exposed from `GHC.Data.Graph.Directed.Reachability`. This index is constructed from the module graph nodes and cached in `ModuleGraph`, enabling efficient reachability queries on the module graph. Previously, we'd construct a Map of Set of ModuleGraph nodes which used a lot of memory (`O(n^2)` in the number of nodes) and cache that in the `ModuleGraph`. By using the reachability index we get rid of this space leak in the module graph -- even though the index is still quadratic in the number of modules, it is much, much more space efficient due to its representation using an IntMap of IntSet as opposed to the transitive closure we previously cached. In a memory profile of MultiLayerModules with 100x100 modules, memory usage improved from 6GB residency to 2.8GB, out of which roughly 1.8GB are caused by a second space leak related to ModuleGraph. On the same program, it brings compile time from 7.5s to 5.5s. Note how we simplify `checkHomeUnitsClosed` in terms of `isReachableMany` and by avoiding constructing a second graph with the full transitive closure -- it suffices to answer the reachability query on the full graph without collapsing the transitive closure completely into nodes. Unfortunately, solving this leak means we have to do a little bit more work since we can no longer cache the result of turning vertex indices into nodes. This results in a slight regression in MultiLayerModulesTH_Make, but results in large performance and memory wins when compiling large amounts of modules. ------------------------- Metric Decrease: mhu-perf Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - bcbcdaaf by Cheng Shao at 2024-11-21T14:09:28-05:00 driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code This commit fixes an undefined symbol error in RTS linker when attempting to compile home modules with -fhpc and -fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for detailed description and analysis of the bug. Also adds T25510/T25510c regression tests to test make mode/oneshot mode of the bug. - - - - - 970ada5a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Bump ci-images For introduction of Alpine/i386 image. Thanks to Julian for the base image. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 8115abc2 by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Add release job for i386/Alpine As requested by Mikolaj and started by Julian. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 639f0149 by Ben Gamari at 2024-11-22T23:32:06-05:00 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ - - - - - 490d4d0a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Mark i386 Alpine test breakages Marks the following tests as broken on i386/Alpine: * T22033 due to #25497 * simd009, T25062_V16, T25169, T22187_run due to #25498 - - - - - 536cdf09 by Cheng Shao at 2024-11-22T23:32:42-05:00 compiler: remove unused GHC.Linker.Loader.loadExpr This patch removes the unused `GHC.Linker.Loader.loadExpr` function. It was moved from `GHC.Runtime.Linker.linkExpr` in `ghc-9.0` to `GHC.Linker.Loader.loadExpr` in `ghc-9.2`, and remain completely unused and untested ever since. There's also no third party user of this function to my best knowledge, so let's remove this. Anyone who wants to write their own GHC API function to load bytecode can consult the source code in older release branches. - - - - - 6ee35024 by Drew Fenwick at 2024-11-22T23:33:26-05:00 Fix a non-compiling example in the type abstractions docs This patch adds a missing Show constraint to a code example in the User Guide's type abstractions docs to fix issue #25422. - - - - - d1172e20 by Rodrigo Mesquita at 2024-11-22T23:34:02-05:00 Re-introduce ErrorCallWithLocation with a deprecation pragma With the removal of the duplicate backtrace, part of CLC proposal #285, the constructor `ErrorCallWithLocation` was removed from base. This commit re-introduces it with a deprecation. - - - - - 1187a60a by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Skip tests requiring Hadrian deps in out-of-tree testsuite runs Some testsuite tests require specific tools (e.g. `check-ppr` and `check-exact`) beyond those shipped in the binary distribution. Skip these tests. Fixes #13897. - - - - - c37d7a2e by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Declare exactprint tests' dependency on check-exact - - - - - 454ce957 by Ben Gamari at 2024-11-22T23:35:15-05:00 ghc-internal: Fix a few cases of missing Haddock markup - - - - - a249649b by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/GHCiPrimCall : Add missing Makefile includes - - - - - a021a493 by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/IpeStats: Use Make rather than shell interpolation - - - - - 6e1fbda7 by Ben Gamari at 2024-11-25T03:55:44-05:00 hadrian-ghci-multi: Pass -this-package-name in unit response files As noted in #25509, the `-this-package-name` must be passed for each package to ensure that GHC can response references to the packages' exposed modules via package-qualified imports. Fix this. Closes #25509. - - - - - a05e4a9b by Simon Hengel at 2024-11-25T03:56:33-05:00 Refactoring: Use `OnOff` more consistently for `Extension` - - - - - 7536181d by Matthew Pickering at 2024-11-25T14:00:07-05:00 driver: Always link against "base" package when one shot linking The default value for base-unit-id is stored in the settings file. At install time, this can be set by using the BASE_UNIT_ID environment variable. At runtime, the value can be set by `-base-unit-id` flag. For whether all this is a good idea, see #25382 Fixes #25382 - - - - - 7f90f319 by Andreas Klebinger at 2024-11-25T14:00:44-05:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 - - - - - 291388e1 by Cheng Shao at 2024-11-25T14:01:19-05:00 ci: minor nix-in-docker improvements This patch makes some minor improvements re nix-in-docker logic in the ci configuration: - Update `nixos/nix` to the latest version - Apply $CPUS to `cores`/`max-jobs` to avoid oversubscribing while allowing a reasonable degree of parallelism - Remove redundant `--extra-experimental-features nix-command` in later `nix shell` invocations, it's already configured in `/etc/nix/nix.conf` - - - - - e684c406 by Cheng Shao at 2024-11-25T14:01:57-05:00 ci: avoid depending on stack job for test-bootstrap jobs This patch makes test-bootstrap related ci jobs only depend on hadrian-ghc-in-ghci job to finish, consistent with other jobs in the full-build stage generated by gen_ci.hs. This allows the jobs to be spawned earlier and improve overall pipeline parallelism. - - - - - caaf5388 by Simon Hengel at 2024-11-25T14:02:41-05:00 Refactoring: Remove `pSupportedExts` from `ParserOpts` This is never used for lexing / parsing. It is only used by `GHC.Parser.Header.getOptions`. - - - - - 41f8365c by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Add test for #25515 - - - - - 9279619f by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Desugar record notation with correct multiplicities Simply uses the multiplicity as stored in the field. As I'm writing this commit, the only possible multiplicity is 1, but !13525 is changing this. It's actually easier to take !13525 into account. Fixes #25515. - - - - - fcc3ae6e by Andreas Klebinger at 2024-11-26T08:24:58-05:00 Clarify INLINE unfolding optimization docs. Fixes #24660 - - - - - 88c4fe1d by Cheng Shao at 2024-11-26T08:25:34-05:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. - - - - - 53f978c0 by doyougnu at 2024-11-26T16:07:26-05:00 ghc-experimental: expose GHC.RTS.Flags, GHC.Stats See this CLC proposal: - https://github.com/haskell/core-libraries-committee/issues/289 and this CLC proposal for background: - https://github.com/haskell/core-libraries-committee/issues/288 Metric Decrease: MultiLayerModulesTH_OneShot - - - - - e70d4140 by Wang Xin at 2024-11-26T16:08:10-05:00 Add -mcmodel=medium moduleflag to generated LLVM IR on LoongArch platform With the Medium code model, the jump range of the generated jump instruction is larger than that of the Small code model. It's a temporary fix of the problem descriped in https://gitlab.haskell .org/ghc/ghc/-/issues/25495. This commit requires that the LLVM used contains the code of commit 9dd1d451d9719aa91b3bdd59c0c6679 83e1baf05, i.e., version 8.0 and later. Actually we should not rely on LLVM, so the only way to solve this problem is to implement the LoongArch backend. Add new type for codemodel - - - - - df42ba16 by Andreas Klebinger at 2024-11-27T11:40:49-05:00 Cmm constant folding: Narrow results to operations bitwidth. When constant folding ensure the result is still within bounds for the given type by explicitly narrowing the results. Not doing so results in a lot of spurious assembler warnings especially when testing primops. - - - - - bf3db97e by Ben Gamari at 2024-11-27T11:41:26-05:00 ghc-toolchain: Introduce basic flag validation We verify that required flags (currently `--output` and `--triple`) are provided. The implementation is truly awful, but so is getopt. Begins to address #25500. - - - - - a104508d by Ben Gamari at 2024-11-27T11:42:03-05:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. - - - - - c3fc9b86 by Ben Gamari at 2024-11-27T11:42:39-05:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. - - - - - a362b943 by sheaf at 2024-11-27T23:44:28-05:00 Add checkExact to toolTargets This change means that the Hadrian multi target will include exactprint. In particular, this means that HLS will work on exactprint inside the GHC tree. - - - - - e6c957e4 by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Add test for #25428 - - - - - 52d97f4e by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Don't bypass MonoLocalBind in empty patterns Fixes #25428 - - - - - 7890f2d8 by Ben Gamari at 2024-11-28T10:26:46-05:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. - - - - - 0fd43ea6 by Adam Sandberg Ericsson at 2024-11-28T10:27:22-05:00 mention -Iw in +RTS -? - - - - - 6cf579b9 by Ben Gamari at 2024-11-28T10:27:59-05:00 gitlab-ci: Set GIT_SUBMODULE_FORCE_HTTPS GitLab recommends using `https://` to clone submodules and provides the `GIT_SUBMODULE_FORCE_HTTPS` variable to force this. Fixes #25528. - - - - - 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 3b085428 by Vladislav Zavialov at 2025-01-21T00:36:05+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 8 changed files: - .ghcid - .gitattributes - .gitignore - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/generate-ci/flake.lock - .gitlab/generate-ci/gen_ci.hs - .gitlab/hello.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3d98594fefe68c3f802522caf1aeaf23a0a9066...3b0854288ed74134f69062a3fb1cbdd97315d98b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3d98594fefe68c3f802522caf1aeaf23a0a9066...3b0854288ed74134f69062a3fb1cbdd97315d98b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 01:21:56 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Mon, 20 Jan 2025 20:21:56 -0500 Subject: [Git][ghc/ghc][wip/T25641] 22 commits: Add flags for switching off speculative evaluation. Message-ID: <678ef6b442a2b_312ea01f5a784120021@gitlab.mail> Ben Gamari pushed to branch wip/T25641 at Glasgow Haskell Compiler / GHC Commits: 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 790b6d8b by Ben Gamari at 2025-01-20T20:21:45-05:00 StgToByteCode: Fix overly-broad handling of Addr# literals Previously we assumed that all unlifted types were `Addr#` but this isn't true. As noted in #25638, unlifted nullary data constructor workers can also appear at the top-level and are obviously not of type `Addr#`. Note that there is more work to be done to properly handle unlifted data constructors (especially nullary; see #25636). However, this is a small step in the right direction. Closes #25641. - - - - - 30 changed files: - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Ppr.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/HsToCore/Errors/Ppr.hs - compiler/GHC/HsToCore/Errors/Types.hs - compiler/GHC/Iface/Errors/Ppr.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Linker/Deps.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/217e4b998cc4b91bdc4c850736d542cb2e550572...790b6d8b6fcc6633ab61d8ed984beaada0860e13 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/217e4b998cc4b91bdc4c850736d542cb2e550572...790b6d8b6fcc6633ab61d8ed984beaada0860e13 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 01:28:20 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 20 Jan 2025 20:28:20 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: hie: fix hie.yaml to use default hie-bios script Message-ID: <678ef8349a2a8_312ea01f5a7ac123189@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 72482a43 by Ben Gamari at 2025-01-20T20:27:59-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 1f4187b5 by Ryan Scott at 2025-01-20T20:28:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 8 changed files: - compiler/GHC/Iface/Syntax.hs - compiler/cbits/genSym.c - hie.yaml - testsuite/tests/backpack/should_fail/T19244a.stderr - testsuite/tests/ghci/scripts/T9881.stdout - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0d161a577fd9116ea029cebf4ef60af28f98b508...1f4187b56be79e3327e1c4562f66c8556b66ff9b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0d161a577fd9116ea029cebf4ef60af28f98b508...1f4187b56be79e3327e1c4562f66c8556b66ff9b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 05:15:39 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Tue, 21 Jan 2025 00:15:39 -0500 Subject: [Git][ghc/ghc][wip/T25623] Fix for alex-3.5.2.0 (#25623) Message-ID: <678f2d7b43f5_38f6db12bf718492f6@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 206317b8 by Brandon Chinn at 2025-01-20T21:13:05-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0. I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 1 changed file: - compiler/GHC/Parser/Lexer.x Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3467,10 +3468,12 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. {-# INLINE alexScanUser #-} +#endif lexToken :: P (PsLocated Token) lexToken = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/206317b85e5c0e3bb05d474420548540c47465f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/206317b85e5c0e3bb05d474420548540c47465f8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 05:18:37 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Tue, 21 Jan 2025 00:18:37 -0500 Subject: [Git][ghc/ghc][wip/T25623] Fix for alex-3.5.2.0 (#25623) Message-ID: <678f2e2dcd120_3bec11c0530563e6@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 12de7903 by Brandon Chinn at 2025-01-20T21:16:09-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 1 changed file: - compiler/GHC/Parser/Lexer.x Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3467,10 +3468,12 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. {-# INLINE alexScanUser #-} +#endif lexToken :: P (PsLocated Token) lexToken = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/12de79036430d68111a34fc948edfee0256f3d32 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/12de79036430d68111a34fc948edfee0256f3d32 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 05:29:19 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 21 Jan 2025 00:29:19 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: compiler: Fix CPP guards around ghc_unique_counter64 Message-ID: <678f30af5f4ee_3bec112cd990606bf@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5415f266 by Ben Gamari at 2025-01-21T00:29:06-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - ae64a859 by Ryan Scott at 2025-01-21T00:29:06-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 7 changed files: - compiler/GHC/Iface/Syntax.hs - compiler/cbits/genSym.c - testsuite/tests/backpack/should_fail/T19244a.stderr - testsuite/tests/ghci/scripts/T9881.stdout - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f4187b56be79e3327e1c4562f66c8556b66ff9b...ae64a859a6a70b2b5e72d98ef601be5ff0f3d0d7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f4187b56be79e3327e1c4562f66c8556b66ff9b...ae64a859a6a70b2b5e72d98ef601be5ff0f3d0d7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 10:57:38 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 21 Jan 2025 05:57:38 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: compiler: Fix CPP guards around ghc_unique_counter64 Message-ID: <678f7da25425f_9ed3cfe9489554c@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c5b146dc by Ben Gamari at 2025-01-21T05:57:15-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 916c79e3 by Ryan Scott at 2025-01-21T05:57:16-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 7 changed files: - compiler/GHC/Iface/Syntax.hs - compiler/cbits/genSym.c - testsuite/tests/backpack/should_fail/T19244a.stderr - testsuite/tests/ghci/scripts/T9881.stdout - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae64a859a6a70b2b5e72d98ef601be5ff0f3d0d7...916c79e39cd3d5e6e8280220412d1efb9de9e330 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae64a859a6a70b2b5e72d98ef601be5ff0f3d0d7...916c79e39cd3d5e6e8280220412d1efb9de9e330 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 11:21:59 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 21 Jan 2025 06:21:59 -0500 Subject: [Git][ghc/ghc][wip/romes/graph-compact-easy] 3 commits: driver: Store an ExternalModuleGraph in the EPS Message-ID: <678f8357eadf3_a8e4a14c2c4461a9@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/graph-compact-easy at Glasgow Haskell Compiler / GHC Commits: 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 77917f22 by Rodrigo Mesquita at 2025-01-21T11:21:21+00:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6410d636a142c4539afaaa7b77ccd8cd35ff6a2...77917f22dd4f1bf443fb34673df64205299d610d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6410d636a142c4539afaaa7b77ccd8cd35ff6a2...77917f22dd4f1bf443fb34673df64205299d610d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 13:04:54 2025 From: gitlab at gitlab.haskell.org (Jens Petersen (@juhp)) Date: Tue, 21 Jan 2025 08:04:54 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/juhp-hp2ps-c23 Message-ID: <678f9b767c497_d0c904b7abc838cf@gitlab.mail> Jens Petersen pushed new branch wip/juhp-hp2ps-c23 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/juhp-hp2ps-c23 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 14:29:58 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Tue, 21 Jan 2025 09:29:58 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/ghc-9.6.7-backports Message-ID: <678faf66c04bc_11267e1f4eec45213@gitlab.mail> Luite Stegeman pushed new branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghc-9.6.7-backports You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 14:57:54 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 21 Jan 2025 09:57:54 -0500 Subject: [Git][ghc/ghc][master] compiler: Fix CPP guards around ghc_unique_counter64 Message-ID: <678fb5f294e35_1277951eaf148640@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 1 changed file: - compiler/cbits/genSym.c Changes: ===================================== compiler/cbits/genSym.c ===================================== @@ -9,6 +9,18 @@ // // The CPP is thus about the RTS version GHC is linked against, and not the // version of the GHC being built. -#if !MIN_VERSION_GLASGOW_HASKELL(9,9,0,0) + +#if MIN_VERSION_GLASGOW_HASKELL(9,9,0,0) +// Unique64 patch was present in 9.10 and later +#define HAVE_UNIQUE64 1 +#elif !MIN_VERSION_GLASGOW_HASKELL(9,9,0,0) && MIN_VERSION_GLASGOW_HASKELL(9,8,4,0) +// Unique64 patch was backported to 9.8.4 +#define HAVE_UNIQUE64 1 +#elif !MIN_VERSION_GLASGOW_HASKELL(9,7,0,0) && MIN_VERSION_GLASGOW_HASKELL(9,6,7,0) +// Unique64 patch was backported to 9.6.7 +#define HAVE_UNIQUE64 1 +#endif + +#if !defined(HAVE_UNIQUE64) HsWord64 ghc_unique_counter64 = 0; #endif View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/595013d41464c1e328369bb81ce0ea2814e91b68 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/595013d41464c1e328369bb81ce0ea2814e91b68 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 14:58:43 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 21 Jan 2025 09:58:43 -0500 Subject: [Git][ghc/ghc][master] Fix :info pretty-printing of UNPACKed fields Message-ID: <678fb623715d0_127795256098129b@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6 changed files: - compiler/GHC/Iface/Syntax.hs - testsuite/tests/backpack/should_fail/T19244a.stderr - testsuite/tests/ghci/scripts/T9881.stdout - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/09ee324759cfab6fd44f03ff7d9b43cf95aaafc9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/09ee324759cfab6fd44f03ff7d9b43cf95aaafc9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 15:13:30 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 21 Jan 2025 10:13:30 -0500 Subject: [Git][ghc/ghc][wip/T25654] gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Message-ID: <678fb99a6befd_137873209a907105d@gitlab.mail> Ben Gamari pushed to branch wip/T25654 at Glasgow Haskell Compiler / GHC Commits: 9dc07fcf by Ben Gamari at 2025-01-21T10:13:21-05:00 gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Closes #25654. - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -909,6 +909,7 @@ test-primops-label: extends: .test-primops-validate-template rules: - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-primops.*/' + - *full-ci test-primops-nightly: extends: .test-primops View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9dc07fcfc1aa422349693e22d63f5343d9481513 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9dc07fcfc1aa422349693e22d63f5343d9481513 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 18:00:42 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 21 Jan 2025 13:00:42 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: compiler: Fix CPP guards around ghc_unique_counter64 Message-ID: <678fe0ca3f53_199a0518a81c9767b@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - a89b82e3 by Rodrigo Mesquita at 2025-01-21T13:00:28-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 69ffd30d by Jens Petersen at 2025-01-21T13:00:29-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/916c79e39cd3d5e6e8280220412d1efb9de9e330...69ffd30dccf6387626faf7c9924706d614265faf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/916c79e39cd3d5e6e8280220412d1efb9de9e330...69ffd30dccf6387626faf7c9924706d614265faf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 18:26:45 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Tue, 21 Jan 2025 13:26:45 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add doc field to CFS Message-ID: <678fe6e5867ba_199a058e227c102674@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 8e23f4d9 by Sjoerd Visscher at 2025-01-21T19:26:26+01:00 Add doc field to CFS - - - - - 17 changed files: - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Type.hs - utils/check-exact/ExactPrint.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/Rename.hs Changes: ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -61,7 +61,7 @@ module GHC.Hs.Type ( HsConDetails(..), noTypeArgs, HsConFieldSpec(..), pprHsConFieldSpecWith, pprHsConFieldSpecNoMult, - hsPlainTypeField, hsConFieldSpecToHsTypes, mkConFieldSpec, + hsPlainTypeField, mkConFieldSpec, FieldOcc(..), LFieldOcc, mkFieldOcc, fieldOccRdrName, fieldOccLRdrName, @@ -570,7 +570,7 @@ type instance XXConDeclField (GhcPass _) = DataConCantHappen instance OutputableBndrId p => Outputable (ConDeclField (GhcPass p)) where - ppr (ConDeclField _ fld_n cfs _) = ppr_names fld_n <+> pprHsConFieldSpecWith ppr_mult cfs + ppr (ConDeclField _ fld_n cfs) = pprMaybeWithDoc (cfs_doc cfs) (ppr_names fld_n <+> pprHsConFieldSpecWith ppr_mult cfs { cfs_doc = Nothing }) where ppr_names :: [LFieldOcc (GhcPass p)] -> SDoc ppr_names [n] = pprPrefixOcc n @@ -1286,24 +1286,22 @@ instance (Outputable tyarg, Outputable arg, Outputable rec) ppr (RecCon rec) = text "RecCon:" <+> ppr rec ppr (InfixCon l r) = text "InfixCon:" <+> ppr [l, r] -pprHsConFieldSpecWith :: (OutputableBndrId p) => (HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc) -> HsConFieldSpec on (GhcPass p) -> SDoc -pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult (L _ (HsDocTy _ ty doc))) = ppr_mult mult (pprWithDoc doc $ ppr prag <+> ppr mark <> ppr ty) -pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty) = ppr_mult mult (ppr prag <+> ppr mark <> ppr ty) +pprHsConFieldSpecWith :: (OutputableBndrId p) + => (HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc) + -> HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty doc) = + pprMaybeWithDoc doc (ppr_mult mult (ppr prag <+> ppr mark <> ppr ty)) pprHsConFieldSpecNoMult :: (OutputableBndrId p) => HsConFieldSpec on (GhcPass p) -> SDoc pprHsConFieldSpecNoMult = pprHsConFieldSpecWith (\_ d -> d) -hsConFieldSpecToHsTypes :: HsConFieldSpec on GhcRn -> [LHsType GhcRn] -hsConFieldSpecToHsTypes (CFS _ _ _ arr t) = [multAnnToHsType arr, t] - hsPlainTypeField :: LHsType GhcPs -> HsConFieldSpec OnArrow GhcPs hsPlainTypeField = mkConFieldSpec (HsLinearAnn noAnn) mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs -mkConFieldSpec mult (L l (HsDocTy x ty lds)) = case mkConFieldSpec mult ty of - CFS ann unp str mult' t -> CFS ann unp str mult' (L l (HsDocTy x t lds)) -mkConFieldSpec mult (L _ (XHsType (HsBangTy ann (HsBang unp str) t))) = CFS ann unp str mult t -mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t +mkConFieldSpec mult (L _ (HsDocTy _ ty lds)) = (mkConFieldSpec mult ty) { cfs_doc = Just lds } +mkConFieldSpec mult (L _ (XHsType (HsBangTy ann (HsBang unp str) t))) = CFS ann unp str mult t Nothing +mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t Nothing instance Outputable (XRecGhc (IdGhcP p)) => Outputable (FieldOcc (GhcPass p)) where @@ -1379,11 +1377,7 @@ pprLHsContextAlways (L _ ctxt) pprConDeclFields :: forall p. OutputableBndrId p => [LConDeclField (GhcPass p)] -> SDoc -pprConDeclFields fields = braces (sep (punctuate comma (map ppr_fld fields))) - where - ppr_fld :: LConDeclField (GhcPass p) -> SDoc - ppr_fld (L _ (cdf at ConDeclField { cd_fld_doc = doc })) - = pprMaybeWithDoc doc (ppr cdf) +pprConDeclFields fields = braces (sep (punctuate comma (map ppr fields))) -- Printing works more-or-less as for Types ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -399,7 +399,7 @@ subordinates env instMap decl = case decl of | c <- toList cons, cname <- getConNames c ] fields = [ (unLoc $ foLabel n, maybeToList $ fmap unLoc doc, IM.empty) | Just flds <- toList $ fmap getRecConArgs_maybe cons - , (L _ (ConDeclField _ ns _ doc)) <- (unLoc flds) + , (L _ (ConDeclField _ ns (CFS { cfs_doc = doc }))) <- (unLoc flds) , (L _ n) <- ns ] derivs = [ (instName, [unLoc doc], IM.empty) | (l, doc) <- concatMap (extract_deriv_clause_tys . @@ -430,20 +430,23 @@ conArgDocs (ConDeclGADT{con_g_args = args, con_res_ty = res_ty}) = h98ConArgDocs :: HsConDeclH98Details GhcRn -> IntMap (HsDoc GhcRn) h98ConArgDocs con_args = case con_args of - PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args - InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (cfs_type arg1) - , unLoc (cfs_type arg2) ] + PrefixCon _ args -> con_arg_docs 0 $ map cfs_doc args + InfixCon arg1 arg2 -> con_arg_docs 0 [ cfs_doc arg1, cfs_doc arg2 ] RecCon _ -> IM.empty gadtConArgDocs :: HsConDeclGADTDetails GhcRn -> HsType GhcRn -> IntMap (HsDoc GhcRn) gadtConArgDocs con_args res_ty = case con_args of - PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args ++ [res_ty] - RecConGADT _ _ -> con_arg_docs 1 [res_ty] + PrefixConGADT _ args -> con_arg_docs 0 $ map cfs_doc args ++ [res_doc] + RecConGADT _ _ -> con_arg_docs 1 [res_doc] + where + res_doc = case res_ty of + HsDocTy _ _ lds -> Just lds + _ -> Nothing -con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn) +con_arg_docs :: Int -> [Maybe (LHsDoc GhcRn)] -> IntMap (HsDoc GhcRn) con_arg_docs n = IM.fromList . catMaybes . zipWith f [n..] where - f n (HsDocTy _ _ lds) = Just (n, unLoc lds) + f n (Just lds) = Just (n, unLoc lds) f _ _ = Nothing isValD :: HsDecl a -> Bool ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -921,7 +921,7 @@ repSrcStrictness SrcStrict = rep2 sourceStrictName [] repSrcStrictness NoSrcStrict = rep2 noSourceStrictnessName [] repConFieldSpec :: HsConFieldSpec on GhcRn -> MetaM (Core (M TH.BangType)) -repConFieldSpec (CFS _ su ss _ ty') = do +repConFieldSpec (CFS _ su ss _ ty' _) = do MkC u <- repSrcUnpackedness su MkC s <- repSrcStrictness ss MkC b <- rep2 bangName [u, s] ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1796,7 +1796,11 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where ] instance ToHie (HsConFieldSpec on GhcRn) where - toHie (CFS _ _ _ w t) = concatM [toHie (multAnnToHsType w), toHie t] + toHie (CFS _ _ _ w t doc) = concatM + [ toHie (multAnnToHsType w) + , toHie t + , toHie doc + ] instance ToHie (TScoped (HsWildCardBndrs GhcRn (LocatedA (HsSigType GhcRn)))) where toHie (TS sc (HsWC names a)) = concatM $ @@ -1993,10 +1997,9 @@ instance HiePass p => ToHie (LocatedC [LocatedA (HsExpr (GhcPass p))]) where instance ToHie (LocatedA (ConDeclField GhcRn)) where toHie (L span field) = concatM $ makeNode field (locA span) : case field of - ConDeclField _ fields typ doc -> + ConDeclField _ fields typ -> [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ cfs_type typ)) fields , toHie typ - , toHie doc ] instance ToHie (LHsExpr a) => ToHie (ArithSeqInfo a) where ===================================== compiler/GHC/Parser.y ===================================== @@ -2598,15 +2598,13 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3) - Nothing))} + (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3)))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (mkMultField (epTok $2) $3 (epUniTok $4) $5) - Nothing))} + (mkMultField (epTok $2) $3 (epUniTok $4) $5)))} -- Reversed! maybe_derivings :: { Located (HsDeriving GhcPs) } ===================================== compiler/GHC/Parser/PostProcess/Haddock.hs ===================================== @@ -215,9 +215,8 @@ collectHdkWarnings HdkSt{ hdk_st_pending, hdk_st_warnings } = -- But having a single name for all of them is just easier to read, and makes it clear -- that they all are of the form t -> HdkA t for some t. -- --- If you need to handle a more complicated scenario that doesn't fit this --- pattern, it's always possible to define separate functions outside of this --- class, as is done in case of e.g. addHaddockConDeclField. +-- If you need to handle a more complicated scenario that doesn't fit this pattern, +-- it's always possible to define separate functions outside of this class. -- -- See Note [Adding Haddock comments to the syntax tree]. class HasHaddock a where @@ -711,7 +710,7 @@ instance HasHaddock (LocatedA (ConDecl GhcPs)) where case con_g_args of PrefixConGADT x ts -> PrefixConGADT x <$> addHaddock ts RecConGADT arr (L l_rec flds) -> do - flds' <- traverse addHaddockConDeclField flds + flds' <- traverse addHaddock flds pure $ RecConGADT arr (L l_rec flds') con_res_ty' <- addHaddock con_res_ty pure $ L l_con_decl $ @@ -735,22 +734,22 @@ instance HasHaddock (LocatedA (ConDecl GhcPs)) where case con_args of PrefixCon _ ts -> do con_doc' <- getConDoc (getLocA con_name) - ts' <- traverse addHaddockConDeclFieldTy ts + ts' <- traverse addHaddock ts pure $ L l_con_decl $ ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt, con_doc = lexLHsDocString <$> con_doc', con_args = PrefixCon noTypeArgs ts' } InfixCon t1 t2 -> do - t1' <- addHaddockConDeclFieldTy t1 + t1' <- addHaddock t1 con_doc' <- getConDoc (getLocA con_name) - t2' <- addHaddockConDeclFieldTy t2 + t2' <- addHaddock t2 pure $ L l_con_decl $ ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt, con_doc = lexLHsDocString <$> con_doc', con_args = InfixCon t1' t2' } RecCon (L l_rec flds) -> do con_doc' <- getConDoc (getLocA con_name) - flds' <- traverse addHaddockConDeclField flds + flds' <- traverse addHaddock flds pure $ L l_con_decl $ ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt, con_doc = lexLHsDocString <$> con_doc', @@ -785,25 +784,11 @@ getConDoc -> HdkA (Maybe (Located HsDocString)) getConDoc l = extendHdkA l $ liftHdkA $ getPrevNextDoc l --- Add documentation comment to a data constructor field. --- Used for PrefixCon and InfixCon. -addHaddockConDeclFieldTy - :: HsConFieldSpec on GhcPs - -> HdkA (HsConFieldSpec on GhcPs) -addHaddockConDeclFieldTy (CFS ann unpack strict mult (L l t)) = - extendHdkA (locA l) $ liftHdkA $ do - mDoc <- getPrevNextDoc (locA l) - return (CFS ann unpack strict mult (mkLHsDocTy (L l t) mDoc)) - --- Add documentation comment to a data constructor field. --- Used for RecCon. -addHaddockConDeclField - :: LConDeclField GhcPs - -> HdkA (LConDeclField GhcPs) -addHaddockConDeclField (L l_fld fld) = - extendHdkA (locA l_fld) $ liftHdkA $ do - cd_fld_doc <- fmap lexLHsDocString <$> getPrevNextDoc (locA l_fld) - return (L l_fld (fld { cd_fld_doc })) +instance HasHaddock (LocatedA (ConDeclField GhcPs)) where + addHaddock (L l_fld (ConDeclField ext nms cfs)) = + extendHdkA (locA l_fld) $ liftHdkA $ do + cfs_doc <- fmap lexLHsDocString <$> getPrevNextDoc (locA l_fld) + return $ L l_fld (ConDeclField ext nms (cfs { cfs_doc })) {- Note [Leading and trailing comments on H98 constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -907,7 +892,11 @@ We implement this in two steps: -} instance HasHaddock (HsConFieldSpec on GhcPs) where - addHaddock (CFS ann unp str mult a) = CFS ann unp str mult <$> addHaddock a + addHaddock cfs = do + cfs_type <- addHaddock (cfs_type cfs) + return $ case cfs_type of + L _ (HsDocTy _ ty doc) -> cfs { cfs_type = ty, cfs_doc = Just doc } + _ -> cfs { cfs_type } instance HasHaddock a => HasHaddock (HsWildCardBndrs GhcPs a) where addHaddock (HsWC _ t) = HsWC noExtField <$> addHaddock t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -451,15 +451,16 @@ rnLHsTypes :: HsDocContext -> [LHsType GhcPs] -> RnM ([LHsType GhcRn], FreeVars) rnLHsTypes doc tys = mapFvRn (rnLHsType doc) tys rnHsConFieldSpec :: HsDocContext -> HsConFieldSpec on GhcPs - -> RnM (HsConFieldSpec on GhcRn, FreeVars) + -> RnM (HsConFieldSpec on GhcRn, FreeVars) rnHsConFieldSpec doc = rnHsConFieldSpecTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) rnHsConFieldSpecTyKi :: RnTyKiEnv -> HsConFieldSpec on GhcPs - -> RnM (HsConFieldSpec on GhcRn, FreeVars) -rnHsConFieldSpecTyKi env (CFS ext unp str w ty) = do + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpecTyKi env (CFS ext unp str w ty doc) = do (w' , fvs_w) <- rnHsMultAnnOn env w (ty', fvs) <- rnLHsTyKi env ty - return (CFS ext unp str w' ty', fvs `plusFV` fvs_w) + doc' <- traverse rnLHsDoc doc + return (CFS ext unp str w' ty' doc', fvs `plusFV` fvs_w) rnHsType :: HsDocContext -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) @@ -1329,11 +1330,10 @@ rnConDeclFields ctxt fls fields rnField :: FastStringEnv FieldLabel -> RnTyKiEnv -> LConDeclField GhcPs -> RnM (LConDeclField GhcRn, FreeVars) -rnField fl_env env (L l (ConDeclField _ names ty haddock_doc)) +rnField fl_env env (L l (ConDeclField _ names ty)) = do { let new_names = map (fmap (lookupField fl_env)) names ; (new_ty, fvs) <- rnHsConFieldSpecTyKi env ty - ; haddock_doc' <- traverse rnLHsDoc haddock_doc - ; return (L l (ConDeclField noExtField new_names new_ty haddock_doc') + ; return (L l (ConDeclField noExtField new_names new_ty) , fvs) } lookupField :: FastStringEnv FieldLabel -> FieldOcc GhcPs -> FieldOcc GhcRn @@ -2049,7 +2049,7 @@ extract_scaled_ltys args acc = foldr extract_scaled_lty acc args extract_scaled_lty :: HsConFieldSpec on GhcPs -> FreeKiTyVars -> FreeKiTyVars -extract_scaled_lty (CFS _ _ _ m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc +extract_scaled_lty (CFS _ _ _ m ty _) acc = extract_lty ty $ extract_hs_mult_ann_on m acc extract_ltys :: [LHsType GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_ltys tys acc = foldr extract_lty acc tys ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1802,8 +1802,8 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc kcConArgTys :: NewOrData -> TcKind -> [HsConFieldSpec on GhcRn] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext ty exp_kind - tcMult mult) + ; forM_ arg_tys (\(CFS _ _ _ mult ty _) -> do _ <- tcCheckLHsTypeInContext ty exp_kind + tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -3925,7 +3925,7 @@ tcConGADTArgs exp_kind (RecConGADT _ fields) tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) -tcConArg exp_kind (CFS (_, src) unp str w bty) +tcConArg exp_kind (CFS (_, src) unp str w bty _) = do { traceTc "tcConArg 1" (ppr bty) ; arg_ty <- tcCheckLHsTypeInContext bty exp_kind ; w' <- tcDataConMult w ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -782,7 +782,7 @@ cvt_arg (Bang su ss, ty) ; let ty' = parenthesizeHsType appPrec ty'' su' = cvtSrcUnpackedness su ss' = cvtSrcStrictness ss - ; return $ CFS noAnn su' ss' hsNoMultAnn ty' } + ; return $ CFS noAnn su' ss' hsNoMultAnn ty' Nothing } cvt_id_arg :: TH.Name -- ^ parent constructor name -> (TH.Name, TH.Bang, TH.Type) -> CvtM (LConDeclField GhcPs) @@ -793,8 +793,7 @@ cvt_id_arg parent_con (i, str, ty) { cd_fld_ext = noExtField , cd_fld_names = [L (l2l li) $ FieldOcc noExtField (L li i')] - , cd_fld_spec = ty' - , cd_fld_doc = Nothing} } + , cd_fld_spec = ty' } } cvtDerivs :: [TH.DerivClause] -> CvtM (HsDeriving GhcPs) cvtDerivs cs = do { mapM cvtDerivClause cs } ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -1077,12 +1077,11 @@ data HsTupleSort = HsUnboxedTuple type LConDeclField pass = XRec pass (ConDeclField pass) -- | Constructor Declaration Field -data ConDeclField pass -- Record fields have Haddock docs on them +data ConDeclField pass = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_spec :: HsConFieldSpec OnRecField pass, - cd_fld_doc :: Maybe (LHsDoc pass)} + cd_fld_spec :: HsConFieldSpec OnRecField pass } | XConDeclField !(XXConDeclField pass) -- | Describes the arguments to a data constructor. This is a common @@ -1117,7 +1116,8 @@ data HsConFieldSpec on pass , cfs_unpack :: SrcUnpackedness , cfs_bang :: SrcStrictness , cfs_multiplicity :: HsMultAnnOn on (LHsType pass) pass - , cfs_type :: LHsType pass } + , cfs_type :: LHsType pass + , cfs_doc :: Maybe (LHsDoc pass) } hsConFieldSpecGeneralize :: HsConFieldSpec on pass -> HsConFieldSpec on1 pass hsConFieldSpecGeneralize = unsafeCoerce ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4424,10 +4424,10 @@ instance ExactPrint (ConDeclField GhcPs) where getAnnotationEntry _ = NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (ConDeclField _ names ftype mdoc) = do + exact (ConDeclField _ names ftype) = do names' <- markAnnotated names ftype' <- markAnnotated ftype - return (ConDeclField noExtField names' ftype' mdoc) + return (ConDeclField noExtField names' ftype') -- --------------------------------------------------------------------- @@ -4443,20 +4443,20 @@ instance ExactPrint (FieldOcc GhcPs) where instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (CFS an unp str arr t) = do + exact (CFS an unp str arr t doc) = do an' <- exactBang an str t' <- markAnnotated t arr' <- markArrow arr - return (CFS an' unp str arr' t') + return (CFS an' unp str arr' t' doc) instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (CFS an unp str mult t) = do + exact (CFS an unp str mult t doc) = do mult' <- markRecFieldMult mult an' <- exactBang an str t' <- markAnnotated t - return (CFS an' unp str mult' t') + return (CFS an' unp str mult' t' doc) exactBang :: (Monoid w, Monad m) => XConFieldSpec GhcPs -> SrcStrictness -> EP w m (XConFieldSpec GhcPs) exactBang ((o,c,tk), mt) str = do ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -1031,7 +1031,7 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = -- | Pretty-print a record field ppSideBySideField :: [(DocName, DocForDecl DocName)] -> Bool -> ConDeclField DocNameI -> LaTeX -ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = +ppSideBySideField subdocs unicode (ConDeclField _ names ltype) = decltt ( cat (punctuate comma (map (ppBinder . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode ltype (dcolon unicode) @@ -1039,16 +1039,16 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = ) <-> rDoc mbDoc where - -- don't use cd_fld_doc for same reason we don't use con_doc above - -- Where there is more than one name, they all have the same documentation mbDoc = lookup (unLoc . foLabel . unLoc $ name) subdocs >>= fmap _doc . combineDocumentation . fst name = case Maybe.listToMaybe names of Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd +-- don't use cfs_doc for same reason we don't use con_doc above +-- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX -ppRecFieldMultAnn unicode (CFS _ _ _ arr _) following = case arr of +ppRecFieldMultAnn unicode (CFS _ _ _ arr _ _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1533,7 +1533,7 @@ ppSideBySideField -> Qualification -> ConDeclField DocNameI -> SubDecl -ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = +ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype) = ( hsep ( punctuate comma @@ -1548,21 +1548,21 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = , [] ) where - -- don't use cd_fld_doc for same reason we don't use con_doc above - -- Where there is more than one name, they all have the same documentation mbDoc = lookup (unLoc . foLabel $ unLoc declName) subdocs >>= combineDocumentation . fst declName = case Maybe.listToMaybe names of Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd +-- don't use cfs_doc for same reason we don't use con_doc above +-- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html -ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _) following = case arr of +ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _ _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following ppShortField :: Bool -> Unicode -> Qualification -> ConDeclField DocNameI -> Html -ppShortField summary unicode qual (ConDeclField _ names ltype _) = +ppShortField summary unicode qual (ConDeclField _ names ltype) = hsep (punctuate comma (map ((ppBinder summary) . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) <+> ppLType unicode qual HideEmptyContexts (hsConFieldSpecToHsTypeNoMult ltype) ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -497,7 +497,7 @@ synifyDataCon use_gadt_syntax dc = ( \(Scaled mult ty) (HsSrcBang st (HsBang unp str)) -> let tySyn = synifyType WithinType [] ty multSyn = synifyMultRec [] mult - in CFS (noAnn, st) unp str multSyn tySyn + in CFS (noAnn, st) unp str multSyn tySyn Nothing ) arg_tys (dataConSrcBangs dc) @@ -509,7 +509,6 @@ synifyDataCon use_gadt_syntax dc = noExtField [noLocA $ FieldOcc (mkVarUnqual $ field_label $ flLabel fl) (noLocA (flSelector fl))] synTy - Nothing mk_h98_arg_tys :: Either String (HsConDeclH98Details GhcRn) mk_h98_arg_tys = case (use_named_field_syntax, use_infix_syntax) of ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -196,10 +196,10 @@ hsConFieldSpecToFunTy (hsConFieldSpecGeneralize -> cfs) tgt = noLocA (HsFunTy noAnn (cfs_multiplicity cfs) (hsConFieldSpecToHsTypeNoMult cfs) tgt) hsConFieldSpecToHsTypeNoMult - :: (XRec pass (HsType pass) ~ GenLocated e (HsType pass), HasAnnotation e, NoAnn (XBangTy pass), XXType pass ~ HsTypeGhcPsExt pass) + :: (XRec pass (HsType pass) ~ GenLocated e (HsType pass), HasAnnotation e, NoAnn (XBangTy pass), NoAnn (XDocTy pass), XXType pass ~ HsTypeGhcPsExt pass) => HsConFieldSpec on pass -> LHsType pass -hsConFieldSpecToHsTypeNoMult (CFS _ unp str _ t) = case t of - L l (HsDocTy x ty doc) -> L l (HsDocTy x (mkBang unp str ty) doc) +hsConFieldSpecToHsTypeNoMult (CFS _ unp str _ t doc) = case doc of + Just doc' -> noLocA (HsDocTy noAnn (mkBang unp str t) doc') _ -> mkBang unp str t where mkBang NoSrcUnpack NoSrcStrict ty = ty @@ -373,11 +373,11 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] -- see above field_avail :: LConDeclField GhcRn -> Bool - field_avail (L _ (ConDeclField _ fs _ _)) = + field_avail (L _ (ConDeclField _ fs _)) = all (\f -> (unLoc . foLabel . unLoc $ f) `elem` names) fs field_types :: [LConDeclField GhcRn] -> [HsConFieldSpec OnArrow GhcRn] - field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t _) <- flds] + field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t) <- flds] keep _ = Nothing restrictDecls :: [Name] -> [LSig GhcRn] -> [LSig GhcRn] @@ -526,7 +526,7 @@ reparenBndrKind v at XBndrKind{} = v -- | Add parenthesis around the types in a 'ConDeclField' (see 'reparenTypePrec') reparenConDeclField :: XRecCond a => ConDeclField a -> ConDeclField a -reparenConDeclField (ConDeclField x n (CFS an unp str m t) d) = ConDeclField x n (CFS an unp str m (reparenLType t)) d +reparenConDeclField (ConDeclField x n (CFS an unp str m t d)) = ConDeclField x n (CFS an unp str m (reparenLType t) d) reparenConDeclField c at XConDeclField{} = c ------------------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Create.hs ===================================== @@ -998,13 +998,13 @@ extractRecSel _ _ _ [] = Left "extractRecSel: selector not found" extractRecSel nm t tvs (L _ con : rest) = case getRecConArgs_maybe con of Just (L _ fields) - | ((l, L _ (ConDeclField _ _nn ty _)) : _) <- matching_fields fields -> + | ((l, L _ (ConDeclField _ _nn ty)) : _) <- matching_fields fields -> pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (cfs_type ty)))))) _ -> extractRecSel nm t tvs rest where matching_fields :: [LConDeclField GhcRn] -> [(SrcSpan, LConDeclField GhcRn)] matching_fields flds = - [ (locA l, f) | f@(L _ (ConDeclField _ ns _ _)) <- flds, L l n <- ns, unLoc (foLabel n) == nm + [ (locA l, f) | f@(L _ (ConDeclField _ ns _)) <- flds, L l n <- ns, unLoc (foLabel n) == nm ] data_ty -- ResTyGADT _ ty <- con_res con = ty ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -719,7 +719,11 @@ renameCon renameHsConFieldSpec :: HsConFieldSpec on GhcRn -> RnM (HsConFieldSpec on DocNameI) -renameHsConFieldSpec (CFS _ unp str w ty) = CFS noExtField unp str <$> renameMultAnnOn w <*> renameLType ty +renameHsConFieldSpec (CFS _ unp str w ty doc) = do + w' <- renameMultAnnOn w + ty' <- renameLType ty + doc' <- mapM renameLDocHsSyn doc + return (CFS noExtField unp str w' ty' doc') renameH98Details :: HsConDeclH98Details GhcRn @@ -742,11 +746,10 @@ renameGADTDetails (RecConGADT _ (L l fields)) = do renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsConFieldSpec ps renameConDeclFieldField :: LConDeclField GhcRn -> RnM (LConDeclField DocNameI) -renameConDeclFieldField (L l (ConDeclField _ names t doc)) = do +renameConDeclFieldField (L l (ConDeclField _ names t)) = do names' <- mapM renameLFieldOcc names t' <- renameHsConFieldSpec t - doc' <- mapM renameLDocHsSyn doc - return $ L (locA l) (ConDeclField noExtField names' t' doc') + return $ L (locA l) (ConDeclField noExtField names' t') renameLFieldOcc :: LFieldOcc GhcRn -> RnM (LFieldOcc DocNameI) renameLFieldOcc (L l (FieldOcc rdr (L n sel))) = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8e23f4d9982cf93120c71f3853ff56e5bee83fdb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8e23f4d9982cf93120c71f3853ff56e5bee83fdb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 18:31:47 2025 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Tue, 21 Jan 2025 13:31:47 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T18631 Message-ID: <678fe813d7cef_199a058065b01031be@gitlab.mail> Teo Camarasu pushed new branch wip/T18631 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18631 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 18:35:51 2025 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Tue, 21 Jan 2025 13:35:51 -0500 Subject: [Git][ghc/ghc][wip/T18631] doc: Add documentation for -XDoAndIfThenElse Message-ID: <678fe907b4483_199a05b7a1ec1047c5@gitlab.mail> Teo Camarasu pushed to branch wip/T18631 at Glasgow Haskell Compiler / GHC Commits: eec047d8 by Teo Camarasu at 2025-01-21T18:34:51+00:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4 changed files: - docs/users_guide/conf.py - docs/users_guide/expected-undocumented-flags.txt - + docs/users_guide/exts/doandifthenelse.rst - docs/users_guide/exts/syntax.rst Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -36,7 +36,6 @@ nitpick_ignore = [ ("c:type", "bool"), - ("extension", "DoAndIfThenElse"), ("extension", "RelaxedPolyRec"), ] ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -7,7 +7,6 @@ -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional -XAutoDeriveTypeable --XDoAndIfThenElse -XDoRec -XJavaScriptFFI -XParallelArrays ===================================== docs/users_guide/exts/doandifthenelse.rst ===================================== @@ -0,0 +1,28 @@ +.. _doandifthenelse: + +Do And If Then Else +============ + +.. extension:: DoAndIfThenElse + :shortdesc: Allow semicolons in ``if`` expressions. + + :status: Included in :extension:`Haskell2010` + + Allow semicolons in ``if`` expressions. + +Normally, a conditional is written like this: ``if cond then expr1 else expr2``. With the extension +:extension:`DoAndIfThenElse`, semicolons are allowed before the ``then`` and also before the ``else``, allowing +``if cond; then expr1; else expr2``. (You can also include either semicolon on its own.) + +Allowing semicolons in the middle of a conditional is useful in connection with layout-controlled +blocks, like ``do``\ -blocks. This is because GHC invisibly inserts a semicolon between each line of a +layout-controlled block. Accordingly, with :extension:`DoAndIfThenElse`, we can write code like this :: + + f mb x y = do + b <- mb + if b + then x + else y + +Without :extension:`DoAndIfThenElse`, the ``then`` and ``else`` lines would have to be indented with respect +to the rest of the lines in the ``do``\ -block. ===================================== docs/users_guide/exts/syntax.rst ===================================== @@ -20,6 +20,7 @@ Syntax lambda_case empty_case multiway_if + doandifthenelse local_fixity_decls block_arguments typed_holes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eec047d8c99a7eec73eee0f6ccd01474075e19d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eec047d8c99a7eec73eee0f6ccd01474075e19d2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 21:10:59 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 21 Jan 2025 16:10:59 -0500 Subject: [Git][ghc/ghc][master] driver: Store the HomePackageTable in a mutable reference Message-ID: <67900d63870d3_1fb4476164585736@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6b7ea592a81e8058f12f42941665690638d4afe1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6b7ea592a81e8058f12f42941665690638d4afe1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 21 21:11:42 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 21 Jan 2025 16:11:42 -0500 Subject: [Git][ghc/ghc][master] hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Message-ID: <67900d8e948ca_1fb447935b5c612af@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 1 changed file: - utils/hp2ps/Utilities.c Changes: ===================================== utils/hp2ps/Utilities.c ===================================== @@ -3,7 +3,7 @@ #include #include "Error.h" -extern void* malloc(); +extern void* malloc(long unsigned int); char* Basename(char *name) @@ -89,7 +89,7 @@ void * xrealloc(void *p, size_t n) { void *r; - extern void *realloc(); + extern void *realloc(void *, long unsigned int); r = realloc(p, n); if (!r) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f983a00ffc97b779eb52b10e69e254ec107f8311 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f983a00ffc97b779eb52b10e69e254ec107f8311 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 00:15:59 2025 From: gitlab at gitlab.haskell.org (Adriaan Leijnse (@aidylns)) Date: Tue, 21 Jan 2025 19:15:59 -0500 Subject: [Git][ghc/ghc][wip/aidylns/ttg-remove-hsunboundvar-via-hshole] Simplify XHole instantiation Message-ID: <679038bfd20c1_23d16c113ea3835135@gitlab.mail> Adriaan Leijnse pushed to branch wip/aidylns/ttg-remove-hsunboundvar-via-hshole at Glasgow Haskell Compiler / GHC Commits: 06add9db by Adriaan Leijnse at 2025-01-22T00:14:59+00:00 Simplify XHole instantiation - - - - - 3 changed files: - compiler/GHC/Hs/Expr.hs - compiler/GHC/Rename/Expr.hs - utils/check-exact/ExactPrint.hs Changes: ===================================== compiler/GHC/Hs/Expr.hs ===================================== @@ -404,45 +404,26 @@ type instance XEmbTy GhcTc = DataConCantHappen -- be enough. But then deriving a Data instance becomes impossible. Much, -- much easier just to define HoleExprRef with a Data instance and store -- the whole structure. -type instance XHole (GhcPass p) = - (HoleKind (XHoleVar (GhcPass p)) (XHoleParseError (GhcPass p)), XHoleShared (GhcPass p)) +type instance XHole GhcPs = (HoleKind (Maybe EpAnnHole) NoExtField, NoExtField) +type instance XHole GhcRn = (HoleKind RdrName DataConCantHappen, NoExtField) +type instance XHole GhcTc = (HoleKind RdrName DataConCantHappen, HoleExprRef) data HoleKind unboundVarInfo parseErrorInfo = HoleVar unboundVarInfo | HoleParseError parseErrorInfo deriving Data --- | HsHole extensions for (named) holes and unbound variables. -type family XHoleVar x -type instance XHoleVar GhcPs = Maybe EpAnnHole -type instance XHoleVar GhcRn = RdrName -type instance XHoleVar GhcTc = RdrName - --- | HsHole extension for parse errors. Unused for now except to encode that --- these cannot occur after the renamer. -type family XHoleParseError p -type instance XHoleParseError GhcPs = NoExtField -type instance XHoleParseError GhcRn = DataConCantHappen -type instance XHoleParseError GhcTc = DataConCantHappen - --- | HsHole extension shared between all types of holes. -type family XHoleShared p -type instance XHoleShared GhcPs = NoExtField -type instance XHoleShared GhcRn = NoExtField -type instance XHoleShared GhcTc = HoleExprRef - --- | The RdrName for an unnamed hole ("_"). -unnamedHoleRdrName :: RdrName -unnamedHoleRdrName = mkUnqual varName (fsLit "_") - --- | The RdrName for an unnamed ("_") hole or named hole/unbound variable --- ("_hole"). -holeVarRdrName :: forall p. IsPass p => XHoleVar (GhcPass p) -> RdrName -holeVarRdrName hv = case (ghcPass @p, hv) of - (GhcPs, _) -> unnamedHoleRdrName - (GhcRn, r) -> r - (GhcTc, r) -> r - +-- | The 'RdrName' for a hole. In the case of a 'HoleVar' denoting an unnamed +-- hole ("_"), named hole ("_hole"), or an unbound variable this returns a +-- 'RdrName' matching the syntactical representation. For a 'ParseError' +-- 'HoleKind' the "_" literal is returned. +holeRdrName :: forall p. IsPass p => XHole (GhcPass p) -> RdrName +holeRdrName h = case (ghcPass @p, h) of + (GhcPs, _) -> mkUnqual varName (fsLit "_") + (GhcRn, (HoleVar r, _)) -> r + (GhcRn, (HoleParseError x, _)) -> dataConCantHappen x + (GhcTc, (HoleVar r, _)) -> r + (GhcTc, (HoleParseError x, _)) -> dataConCantHappen x type instance XForAll GhcPs = NoExtField type instance XForAll GhcRn = NoExtField @@ -748,11 +729,7 @@ ppr_lexpr e = ppr_expr (unLoc e) ppr_expr :: forall p. (OutputableBndrId p) => HsExpr (GhcPass p) -> SDoc ppr_expr (HsVar _ (L _ v)) = pprPrefixOcc v -ppr_expr (HsHole (HoleVar v, _)) = pprPrefixOcc (holeVarRdrName @p v) -ppr_expr (HsHole (HoleParseError x, _)) = case ghcPass @p of - GhcPs -> pprPrefixOcc unnamedHoleRdrName - GhcRn -> dataConCantHappen x - GhcTc -> dataConCantHappen x +ppr_expr (HsHole h) = pprPrefixOcc (holeRdrName @p h) ppr_expr (HsIPVar _ v) = ppr v ppr_expr (HsOverLabel s l) = case ghcPass @p of GhcPs -> helper s @@ -1010,11 +987,7 @@ instance Outputable XXExprGhcTc where ppr_infix_expr :: forall p. (OutputableBndrId p) => HsExpr (GhcPass p) -> Maybe SDoc ppr_infix_expr (HsVar _ (L _ v)) = Just (pprInfixOcc v) -ppr_infix_expr (HsHole (HoleVar hv, _)) = Just (pprInfixOcc (holeVarRdrName @p hv)) -ppr_infix_expr (HsHole (HoleParseError x, _)) = case ghcPass @p of - GhcPs -> Just (pprInfixOcc unnamedHoleRdrName) -- TODO: Why not print the actual source text in case of a parse error? - GhcRn -> dataConCantHappen x - GhcTc -> dataConCantHappen x +ppr_infix_expr (HsHole h) = Just (pprInfixOcc (holeRdrName @p h)) ppr_infix_expr (XExpr x) = case ghcPass @p of GhcRn -> ppr_infix_expr_rn x GhcTc -> ppr_infix_expr_tc x ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -8,6 +8,7 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE DataKinds #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -353,8 +354,9 @@ rnExpr (HsVar _ (L l v)) rnExpr (HsIPVar x v) = return (HsIPVar x v, emptyFVs) -rnExpr (HsHole (HoleVar _, NoExtField)) - = return (HsHole (HoleVar unnamedHoleRdrName, NoExtField), emptyFVs) +rnExpr (HsHole xh@(HoleVar _, NoExtField)) + -- Using holeRdrName avoids repeating the "_" literal for unnamed holes: + = return (HsHole (HoleVar (holeRdrName @'Parsed xh), NoExtField), emptyFVs) rnExpr (HsHole (HoleParseError NoExtField, NoExtField)) = panic "rnExpr tried to rename a HoleParseError" ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -2882,7 +2882,7 @@ instance ExactPrint (HsExpr GhcPs) where exact (HsHole (HoleVar an, NoExtField)) = do case an of Just (EpAnnHole (ob,cb) l) -> do - ob' <- markEpToken ob + ob' <- markEpToken ob l' <- markEpToken l cb' <- markEpToken cb return (HsHole (HoleVar (Just (EpAnnHole (ob',cb') l')), NoExtField)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06add9dbe979249856f7963c1986eb88c364003a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/06add9dbe979249856f7963c1986eb88c364003a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 00:38:23 2025 From: gitlab at gitlab.haskell.org (Adriaan Leijnse (@aidylns)) Date: Tue, 21 Jan 2025 19:38:23 -0500 Subject: [Git][ghc/ghc] Pushed new branch origin/wip/aidylns/hsexpr-hshole-with-located-rdrname-holevar Message-ID: <67903dffcfe7e_2754613bca18854ec@gitlab.mail> Adriaan Leijnse pushed new branch origin/wip/aidylns/hsexpr-hshole-with-located-rdrname-holevar at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/origin/wip/aidylns/hsexpr-hshole-with-located-rdrname-holevar You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 02:44:50 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Tue, 21 Jan 2025 21:44:50 -0500 Subject: [Git][ghc/ghc][wip/T25609] Add some more tests Message-ID: <67905ba275ad3_2aef4e67366c888a4@gitlab.mail> Brandon Chinn pushed to branch wip/T25609 at Glasgow Haskell Compiler / GHC Commits: 839e56e9 by Brandon Chinn at 2025-01-21T18:44:41-08:00 Add some more tests - - - - - 4 changed files: - testsuite/tests/parser/should_run/NumericUnderscores0.hs - testsuite/tests/parser/should_run/NumericUnderscores0.stdout - testsuite/tests/parser/should_run/T25609.hs - testsuite/tests/parser/should_run/T25609.stdout Changes: ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.hs ===================================== @@ -99,3 +99,6 @@ main = do 0x_ff == 0xff, 0x__ff == 0xff ] + + -- ensure that strings are unaffected + print ["\o16_000", "\16_000", "\x16_000"] ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.stdout ===================================== @@ -11,3 +11,4 @@ [True,True,True] [True,True,True] [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] +["\SO_000","\DLE_000","\SYN_000"] ===================================== testsuite/tests/parser/should_run/T25609.hs ===================================== @@ -24,3 +24,11 @@ main = do """ + + -- strings with unicode + print """ + ★ + ★ + ★ + ★ + """ ===================================== testsuite/tests/parser/should_run/T25609.stdout ===================================== @@ -12,3 +12,4 @@ "-- $ test" " " "\n" +" ★\n★\n ★\n★" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/839e56e9d985ae4d3acda74a99fd2c6e072e7d29 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/839e56e9d985ae4d3acda74a99fd2c6e072e7d29 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 04:33:44 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Tue, 21 Jan 2025 23:33:44 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] add 9.6.7 release notes Message-ID: <67907528c016a_2ee636117bdc2042@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 14e45f2d by Luite Stegeman at 2025-01-22T05:32:54+01:00 add 9.6.7 release notes - - - - - 3 changed files: - docs/users_guide/9.6.6-notes.rst - + docs/users_guide/9.6.7-notes.rst - docs/users_guide/release-notes.rst Changes: ===================================== docs/users_guide/9.6.6-notes.rst ===================================== @@ -59,49 +59,3 @@ Core libraries -------------- - Bump ``directory`` to 1.3.8.5 - -Included libraries ------------------- - -The package database provided with this distribution also contains a number of -packages other than GHC itself. See the changelogs provided with these packages -for further change information. - -.. ghc-package-list:: - - libraries/array/array.cabal: Dependency of ``ghc`` library - libraries/base/base.cabal: Core library - libraries/binary/binary.cabal: Dependency of ``ghc`` library - libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library - libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility - libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility - libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library - libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library - libraries/directory/directory.cabal: Dependency of ``ghc`` library - libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library - libraries/filepath/filepath.cabal: Dependency of ``ghc`` library - compiler/ghc.cabal: The compiler itself - libraries/ghci/ghci.cabal: The REPL interface - libraries/ghc-boot/ghc-boot.cabal: Internal compiler library - libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library - libraries/ghc-compact/ghc-compact.cabal: Core library - libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library - libraries/ghc-prim/ghc-prim.cabal: Core library - libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable - libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable - libraries/integer-gmp/integer-gmp.cabal: Core library - libraries/libiserv/libiserv.cabal: Internal compiler library - libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library - libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library - libraries/pretty/pretty.cabal: Dependency of ``ghc`` library - libraries/process/process.cabal: Dependency of ``ghc`` library - libraries/stm/stm.cabal: Dependency of ``haskeline`` library - libraries/template-haskell/template-haskell.cabal: Core library - libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library - libraries/text/text.cabal: Dependency of ``Cabal`` library - libraries/time/time.cabal: Dependency of ``ghc`` library - libraries/transformers/transformers.cabal: Dependency of ``ghc`` library - libraries/unix/unix.cabal: Dependency of ``ghc`` library - libraries/Win32/Win32.cabal: Dependency of ``ghc`` library - libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable - ===================================== docs/users_guide/9.6.7-notes.rst ===================================== @@ -0,0 +1,112 @@ +.. _release-9-6-7: + +Version 9.6.7 +============== + +The :ghc-flag:`LLVM backend <-fllvm>` of this release is to be used with LLVM +11, 12, 13, 14 or 15. + +Significant Changes +~~~~~~~~~~~~~~~~~~~~ + +Issues fixed in this release include: + +Compiler +-------- + +- Fixed a bug that caused GHC to panic when using the AArch64 ncg and :ghc-flag:`-fregs-graph` on certain programs (:ghc-ticket:`24941`). +- Fix invalid optimisation of Cmm programs on 32-bit platforms when targetting 64-bit targets (:ghc-ticket:`24893` and :ghc-ticket:`24700`). +- Improve float-out surrounding applications of ``runRW#`` (:ghc-ticket:`25055`). +- Fix :ghc-flag:`-fregs-graph` crash when targetting AArch64 (:ghc-ticket:`24941`). +- Fix code generation of foreign exports with more than 6 arguments when some are subword-width (:ghc-ticket:`24314`). +- Fix recompilation avoidance behavior of :ghc-flag:`-fwrite-if-simplified-core` (:ghc-ticket:`24656`). +- Fix linking error when :extension:`TypeData` and :extension:`StrictData` are in use (:ghc-ticket:`24620`). +- :ghc-flag:`-Wmissing-home-modules` now behaves correctly when multiple units have expose the same module name (:ghc-ticket:`25122`). +- Adjust the demand signature of the ``prompt#`` to avoid invalid optimisation of non-terminating programs (:ghc-ticket:`25439`). +- GHC's internal ``Unique`` type has been widened to 64-bits on 32-bit architectures, avoiding potential miscompilations on large projects (:ghc-ticket:`22010`). +- Fix LLVM version detection on newer LLVM versions (:ghc-ticket:`25606`). +- Determine ``max_n_capabilities`` at RTS startup, removing the previous static cap at 256 (:ghc-ticket:`25560`). +- Fix out-of-bounds memory mapping logic, resolving an infinite loop on FreeBSD (:ghc-ticket:`25492`). +- Find C++ probing when GCC version is the latest but G++ is old (:ghc-ticket:`23118`). +- Consider Wanteds with rewriters as insoluble, fixing a situation where the program fails to typecheck but no errors are reported (:ghc-ticket:`25325`). +- Fix x86 NCG foreign argument promotion. The x86 NCG now correctly promotes 8 bit and 16 bits arguments by sign extension (:ghc-ticket:`25018`). +- Fix GHC flag ``-working-dir`` for foreign files (:ghc-ticket:`25150`). +- Added new flags :ghc-flag:`-fspec-eval` and :ghc-flag:`-fspec-eval-dictfun` to allow switching off speculative evaluation (:ghc-ticket:`25284`). +- Fix a runtime crash when using the compacting GC, caused by black holes in large objects (:ghc-ticket:`24791`). + +Hadrian and builds +------------------ + +- Bump the minimum version of the `directory` dependency for Hadrian to 1.3.9.0 to avoid a race condition on Windows (:ghc-ticket:`#24382`). Also updated the bootstrap build plans for hadrian. +- Hadrian: Set `-this-package-name`. This fixes package imports for `ghci-multi` and was required to update the `unix` package. +- Add Ubuntu 22.04 builds for nightlies and release (:ghc-ticket:`25317`). + +JavaScript backend +------------------ + +- Fix compiler crash involving rubbish literals (:ghc-ticket:`25177`, :ghc-ticket:`24664`). + +``base`` +-------- + +- Bump version to 4.18.2.2 +- Fix spurious closing of file descriptors after ``fork`` on platforms using + the KQueue event manager backend (:ghc-ticket:`24672`), visible on FreeBSD. + +Other Core Libraries +-------------------- + +- The ``filepath`` library has been upgraded to 1.4.301.0, fixing a potentially + exploitable behavior with ``splitFileName`` on Windows (:ghc-ticket:`24597`). +- ``unix-2.8.6.0`` is included, fixing an `issue + `_ affecting ``musl`` targets. +- ``bytestring`` has been upgraded to 0.11.5.4, fixing a race condition in + ``toLazyByteString`` that could generate wrong results if two threads + concurrently evaluated the result. +- ``array`` has been upgraded to 0.5.8.0. +- ``ghc-bignum``: the bundled gmp library has been upgraded to 6.3.0. + +Included libraries +------------------ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + compiler/ghc.cabal: The compiler itself + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/libiserv/libiserv.cabal: Internal compiler library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable \ No newline at end of file ===================================== docs/users_guide/release-notes.rst ===================================== @@ -10,3 +10,4 @@ Release notes 9.6.4-notes 9.6.5-notes 9.6.6-notes + 9.6.7-notes \ No newline at end of file View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14e45f2d25332f93a730bc220aa99d0b9372ed7d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/14e45f2d25332f93a730bc220aa99d0b9372ed7d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 05:32:51 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Wed, 22 Jan 2025 00:32:51 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] update CI images Message-ID: <67908303b252a_2ee636e2e67c6096@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 025e5fd7 by Luite Stegeman at 2025-01-22T06:32:21+01:00 update CI images - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: 572353e0644044fe3a5465bba4342a9a0b0eb60e + DOCKER_REV: eb4d3389fd62e4f7321a0c8799014ec1f4da0708 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/025e5fd75378b6136287a7f4b6a0fb837b5a25d0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/025e5fd75378b6136287a7f4b6a0fb837b5a25d0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 06:25:36 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Wed, 22 Jan 2025 01:25:36 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] update CI images Message-ID: <67908f60b2580_2ee63618ec99c15863@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 69969162 by Luite Stegeman at 2025-01-22T07:24:46+01:00 update CI images - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: 572353e0644044fe3a5465bba4342a9a0b0eb60e + DOCKER_REV: 9cb7b2a2bc9a7c6662f66758a52c75051b3af3d6 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/699691620bded97ac38aacb3ad510b6730306f6e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/699691620bded97ac38aacb3ad510b6730306f6e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 07:55:37 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Wed, 22 Jan 2025 02:55:37 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] update CI images Message-ID: <6790a479acc9d_354c2caee78c538a9@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: ce0bee82 by Luite Stegeman at 2025-01-22T08:55:06+01:00 update CI images - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: 572353e0644044fe3a5465bba4342a9a0b0eb60e + DOCKER_REV: c3901b52d3ea900c844ecdbba2a3996518f37e5e # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce0bee82e423944c7890d7440f2dff729154fd9b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ce0bee82e423944c7890d7440f2dff729154fd9b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 07:57:40 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Wed, 22 Jan 2025 02:57:40 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add doc field to CFS Message-ID: <6790a4f465394_354c2caee7b454244@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 146774f9 by Sjoerd Visscher at 2025-01-22T08:57:09+01:00 Add doc field to CFS - - - - - 24 changed files: - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/printer/T18791.stderr - utils/check-exact/ExactPrint.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/Rename.hs Changes: ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -61,7 +61,7 @@ module GHC.Hs.Type ( HsConDetails(..), noTypeArgs, HsConFieldSpec(..), pprHsConFieldSpecWith, pprHsConFieldSpecNoMult, - hsPlainTypeField, hsConFieldSpecToHsTypes, mkConFieldSpec, + hsPlainTypeField, mkConFieldSpec, FieldOcc(..), LFieldOcc, mkFieldOcc, fieldOccRdrName, fieldOccLRdrName, @@ -570,7 +570,7 @@ type instance XXConDeclField (GhcPass _) = DataConCantHappen instance OutputableBndrId p => Outputable (ConDeclField (GhcPass p)) where - ppr (ConDeclField _ fld_n cfs _) = ppr_names fld_n <+> pprHsConFieldSpecWith ppr_mult cfs + ppr (ConDeclField _ fld_n cfs) = pprMaybeWithDoc (cfs_doc cfs) (ppr_names fld_n <+> pprHsConFieldSpecWith ppr_mult cfs { cfs_doc = Nothing }) where ppr_names :: [LFieldOcc (GhcPass p)] -> SDoc ppr_names [n] = pprPrefixOcc n @@ -1286,24 +1286,22 @@ instance (Outputable tyarg, Outputable arg, Outputable rec) ppr (RecCon rec) = text "RecCon:" <+> ppr rec ppr (InfixCon l r) = text "InfixCon:" <+> ppr [l, r] -pprHsConFieldSpecWith :: (OutputableBndrId p) => (HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc) -> HsConFieldSpec on (GhcPass p) -> SDoc -pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult (L _ (HsDocTy _ ty doc))) = ppr_mult mult (pprWithDoc doc $ ppr prag <+> ppr mark <> ppr ty) -pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty) = ppr_mult mult (ppr prag <+> ppr mark <> ppr ty) +pprHsConFieldSpecWith :: (OutputableBndrId p) + => (HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc) + -> HsConFieldSpec on (GhcPass p) -> SDoc +pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty doc) = + pprMaybeWithDoc doc (ppr_mult mult (ppr prag <+> ppr mark <> ppr ty)) pprHsConFieldSpecNoMult :: (OutputableBndrId p) => HsConFieldSpec on (GhcPass p) -> SDoc pprHsConFieldSpecNoMult = pprHsConFieldSpecWith (\_ d -> d) -hsConFieldSpecToHsTypes :: HsConFieldSpec on GhcRn -> [LHsType GhcRn] -hsConFieldSpecToHsTypes (CFS _ _ _ arr t) = [multAnnToHsType arr, t] - hsPlainTypeField :: LHsType GhcPs -> HsConFieldSpec OnArrow GhcPs hsPlainTypeField = mkConFieldSpec (HsLinearAnn noAnn) mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs -mkConFieldSpec mult (L l (HsDocTy x ty lds)) = case mkConFieldSpec mult ty of - CFS ann unp str mult' t -> CFS ann unp str mult' (L l (HsDocTy x t lds)) -mkConFieldSpec mult (L _ (XHsType (HsBangTy ann (HsBang unp str) t))) = CFS ann unp str mult t -mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t +mkConFieldSpec mult (L _ (HsDocTy _ ty lds)) = (mkConFieldSpec mult ty) { cfs_doc = Just lds } +mkConFieldSpec mult (L _ (XHsType (HsBangTy ann (HsBang unp str) t))) = CFS ann unp str mult t Nothing +mkConFieldSpec mult t = CFS noAnn NoSrcUnpack NoSrcStrict mult t Nothing instance Outputable (XRecGhc (IdGhcP p)) => Outputable (FieldOcc (GhcPass p)) where @@ -1379,11 +1377,7 @@ pprLHsContextAlways (L _ ctxt) pprConDeclFields :: forall p. OutputableBndrId p => [LConDeclField (GhcPass p)] -> SDoc -pprConDeclFields fields = braces (sep (punctuate comma (map ppr_fld fields))) - where - ppr_fld :: LConDeclField (GhcPass p) -> SDoc - ppr_fld (L _ (cdf at ConDeclField { cd_fld_doc = doc })) - = pprMaybeWithDoc doc (ppr cdf) +pprConDeclFields fields = braces (sep (punctuate comma (map ppr fields))) -- Printing works more-or-less as for Types ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -399,7 +399,7 @@ subordinates env instMap decl = case decl of | c <- toList cons, cname <- getConNames c ] fields = [ (unLoc $ foLabel n, maybeToList $ fmap unLoc doc, IM.empty) | Just flds <- toList $ fmap getRecConArgs_maybe cons - , (L _ (ConDeclField _ ns _ doc)) <- (unLoc flds) + , (L _ (ConDeclField _ ns (CFS { cfs_doc = doc }))) <- (unLoc flds) , (L _ n) <- ns ] derivs = [ (instName, [unLoc doc], IM.empty) | (l, doc) <- concatMap (extract_deriv_clause_tys . @@ -430,20 +430,23 @@ conArgDocs (ConDeclGADT{con_g_args = args, con_res_ty = res_ty}) = h98ConArgDocs :: HsConDeclH98Details GhcRn -> IntMap (HsDoc GhcRn) h98ConArgDocs con_args = case con_args of - PrefixCon _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args - InfixCon arg1 arg2 -> con_arg_docs 0 [ unLoc (cfs_type arg1) - , unLoc (cfs_type arg2) ] + PrefixCon _ args -> con_arg_docs 0 $ map cfs_doc args + InfixCon arg1 arg2 -> con_arg_docs 0 [ cfs_doc arg1, cfs_doc arg2 ] RecCon _ -> IM.empty gadtConArgDocs :: HsConDeclGADTDetails GhcRn -> HsType GhcRn -> IntMap (HsDoc GhcRn) gadtConArgDocs con_args res_ty = case con_args of - PrefixConGADT _ args -> con_arg_docs 0 $ map (unLoc . cfs_type) args ++ [res_ty] - RecConGADT _ _ -> con_arg_docs 1 [res_ty] + PrefixConGADT _ args -> con_arg_docs 0 $ map cfs_doc args ++ [res_doc] + RecConGADT _ _ -> con_arg_docs 1 [res_doc] + where + res_doc = case res_ty of + HsDocTy _ _ lds -> Just lds + _ -> Nothing -con_arg_docs :: Int -> [HsType GhcRn] -> IntMap (HsDoc GhcRn) +con_arg_docs :: Int -> [Maybe (LHsDoc GhcRn)] -> IntMap (HsDoc GhcRn) con_arg_docs n = IM.fromList . catMaybes . zipWith f [n..] where - f n (HsDocTy _ _ lds) = Just (n, unLoc lds) + f n (Just lds) = Just (n, unLoc lds) f _ _ = Nothing isValD :: HsDecl a -> Bool ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -921,7 +921,7 @@ repSrcStrictness SrcStrict = rep2 sourceStrictName [] repSrcStrictness NoSrcStrict = rep2 noSourceStrictnessName [] repConFieldSpec :: HsConFieldSpec on GhcRn -> MetaM (Core (M TH.BangType)) -repConFieldSpec (CFS _ su ss _ ty') = do +repConFieldSpec (CFS _ su ss _ ty' _) = do MkC u <- repSrcUnpackedness su MkC s <- repSrcStrictness ss MkC b <- rep2 bangName [u, s] ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1796,7 +1796,11 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where ] instance ToHie (HsConFieldSpec on GhcRn) where - toHie (CFS _ _ _ w t) = concatM [toHie (multAnnToHsType w), toHie t] + toHie (CFS _ _ _ w t doc) = concatM + [ toHie (multAnnToHsType w) + , toHie t + , toHie doc + ] instance ToHie (TScoped (HsWildCardBndrs GhcRn (LocatedA (HsSigType GhcRn)))) where toHie (TS sc (HsWC names a)) = concatM $ @@ -1993,10 +1997,9 @@ instance HiePass p => ToHie (LocatedC [LocatedA (HsExpr (GhcPass p))]) where instance ToHie (LocatedA (ConDeclField GhcRn)) where toHie (L span field) = concatM $ makeNode field (locA span) : case field of - ConDeclField _ fields typ doc -> + ConDeclField _ fields typ -> [ toHie $ map (RFC RecFieldDecl (getRealSpan $ getHasLoc $ cfs_type typ)) fields , toHie typ - , toHie doc ] instance ToHie (LHsExpr a) => ToHie (ArithSeqInfo a) where ===================================== compiler/GHC/Parser.y ===================================== @@ -2598,15 +2598,13 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3) - Nothing))} + (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3)))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (mkMultField (epTok $2) $3 (epUniTok $4) $5) - Nothing))} + (mkMultField (epTok $2) $3 (epUniTok $4) $5)))} -- Reversed! maybe_derivings :: { Located (HsDeriving GhcPs) } ===================================== compiler/GHC/Parser/PostProcess/Haddock.hs ===================================== @@ -215,9 +215,8 @@ collectHdkWarnings HdkSt{ hdk_st_pending, hdk_st_warnings } = -- But having a single name for all of them is just easier to read, and makes it clear -- that they all are of the form t -> HdkA t for some t. -- --- If you need to handle a more complicated scenario that doesn't fit this --- pattern, it's always possible to define separate functions outside of this --- class, as is done in case of e.g. addHaddockConDeclField. +-- If you need to handle a more complicated scenario that doesn't fit this pattern, +-- it's always possible to define separate functions outside of this class. -- -- See Note [Adding Haddock comments to the syntax tree]. class HasHaddock a where @@ -711,7 +710,7 @@ instance HasHaddock (LocatedA (ConDecl GhcPs)) where case con_g_args of PrefixConGADT x ts -> PrefixConGADT x <$> addHaddock ts RecConGADT arr (L l_rec flds) -> do - flds' <- traverse addHaddockConDeclField flds + flds' <- traverse addHaddock flds pure $ RecConGADT arr (L l_rec flds') con_res_ty' <- addHaddock con_res_ty pure $ L l_con_decl $ @@ -735,22 +734,22 @@ instance HasHaddock (LocatedA (ConDecl GhcPs)) where case con_args of PrefixCon _ ts -> do con_doc' <- getConDoc (getLocA con_name) - ts' <- traverse addHaddockConDeclFieldTy ts + ts' <- traverse addHaddock ts pure $ L l_con_decl $ ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt, con_doc = lexLHsDocString <$> con_doc', con_args = PrefixCon noTypeArgs ts' } InfixCon t1 t2 -> do - t1' <- addHaddockConDeclFieldTy t1 + t1' <- addHaddock t1 con_doc' <- getConDoc (getLocA con_name) - t2' <- addHaddockConDeclFieldTy t2 + t2' <- addHaddock t2 pure $ L l_con_decl $ ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt, con_doc = lexLHsDocString <$> con_doc', con_args = InfixCon t1' t2' } RecCon (L l_rec flds) -> do con_doc' <- getConDoc (getLocA con_name) - flds' <- traverse addHaddockConDeclField flds + flds' <- traverse addHaddock flds pure $ L l_con_decl $ ConDeclH98 { con_ext, con_name, con_forall, con_ex_tvs, con_mb_cxt, con_doc = lexLHsDocString <$> con_doc', @@ -785,25 +784,11 @@ getConDoc -> HdkA (Maybe (Located HsDocString)) getConDoc l = extendHdkA l $ liftHdkA $ getPrevNextDoc l --- Add documentation comment to a data constructor field. --- Used for PrefixCon and InfixCon. -addHaddockConDeclFieldTy - :: HsConFieldSpec on GhcPs - -> HdkA (HsConFieldSpec on GhcPs) -addHaddockConDeclFieldTy (CFS ann unpack strict mult (L l t)) = - extendHdkA (locA l) $ liftHdkA $ do - mDoc <- getPrevNextDoc (locA l) - return (CFS ann unpack strict mult (mkLHsDocTy (L l t) mDoc)) - --- Add documentation comment to a data constructor field. --- Used for RecCon. -addHaddockConDeclField - :: LConDeclField GhcPs - -> HdkA (LConDeclField GhcPs) -addHaddockConDeclField (L l_fld fld) = - extendHdkA (locA l_fld) $ liftHdkA $ do - cd_fld_doc <- fmap lexLHsDocString <$> getPrevNextDoc (locA l_fld) - return (L l_fld (fld { cd_fld_doc })) +instance HasHaddock (LocatedA (ConDeclField GhcPs)) where + addHaddock (L l_fld (ConDeclField ext nms cfs)) = + extendHdkA (locA l_fld) $ liftHdkA $ do + cfs_doc <- fmap lexLHsDocString <$> getPrevNextDoc (locA l_fld) + return $ L l_fld (ConDeclField ext nms (cfs { cfs_doc })) {- Note [Leading and trailing comments on H98 constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -907,7 +892,11 @@ We implement this in two steps: -} instance HasHaddock (HsConFieldSpec on GhcPs) where - addHaddock (CFS ann unp str mult a) = CFS ann unp str mult <$> addHaddock a + addHaddock cfs = do + cfs_type <- addHaddock (cfs_type cfs) + return $ case cfs_type of + L _ (HsDocTy _ ty doc) -> cfs { cfs_type = ty, cfs_doc = Just doc } + _ -> cfs { cfs_type } instance HasHaddock a => HasHaddock (HsWildCardBndrs GhcPs a) where addHaddock (HsWC _ t) = HsWC noExtField <$> addHaddock t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -451,15 +451,16 @@ rnLHsTypes :: HsDocContext -> [LHsType GhcPs] -> RnM ([LHsType GhcRn], FreeVars) rnLHsTypes doc tys = mapFvRn (rnLHsType doc) tys rnHsConFieldSpec :: HsDocContext -> HsConFieldSpec on GhcPs - -> RnM (HsConFieldSpec on GhcRn, FreeVars) + -> RnM (HsConFieldSpec on GhcRn, FreeVars) rnHsConFieldSpec doc = rnHsConFieldSpecTyKi (mkTyKiEnv doc TypeLevel RnTypeBody) rnHsConFieldSpecTyKi :: RnTyKiEnv -> HsConFieldSpec on GhcPs - -> RnM (HsConFieldSpec on GhcRn, FreeVars) -rnHsConFieldSpecTyKi env (CFS ext unp str w ty) = do + -> RnM (HsConFieldSpec on GhcRn, FreeVars) +rnHsConFieldSpecTyKi env (CFS ext unp str w ty doc) = do (w' , fvs_w) <- rnHsMultAnnOn env w (ty', fvs) <- rnLHsTyKi env ty - return (CFS ext unp str w' ty', fvs `plusFV` fvs_w) + doc' <- traverse rnLHsDoc doc + return (CFS ext unp str w' ty' doc', fvs `plusFV` fvs_w) rnHsType :: HsDocContext -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) @@ -1329,11 +1330,10 @@ rnConDeclFields ctxt fls fields rnField :: FastStringEnv FieldLabel -> RnTyKiEnv -> LConDeclField GhcPs -> RnM (LConDeclField GhcRn, FreeVars) -rnField fl_env env (L l (ConDeclField _ names ty haddock_doc)) +rnField fl_env env (L l (ConDeclField _ names ty)) = do { let new_names = map (fmap (lookupField fl_env)) names ; (new_ty, fvs) <- rnHsConFieldSpecTyKi env ty - ; haddock_doc' <- traverse rnLHsDoc haddock_doc - ; return (L l (ConDeclField noExtField new_names new_ty haddock_doc') + ; return (L l (ConDeclField noExtField new_names new_ty) , fvs) } lookupField :: FastStringEnv FieldLabel -> FieldOcc GhcPs -> FieldOcc GhcRn @@ -2049,7 +2049,7 @@ extract_scaled_ltys args acc = foldr extract_scaled_lty acc args extract_scaled_lty :: HsConFieldSpec on GhcPs -> FreeKiTyVars -> FreeKiTyVars -extract_scaled_lty (CFS _ _ _ m ty) acc = extract_lty ty $ extract_hs_mult_ann_on m acc +extract_scaled_lty (CFS _ _ _ m ty _) acc = extract_lty ty $ extract_hs_mult_ann_on m acc extract_ltys :: [LHsType GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_ltys tys acc = foldr extract_lty acc tys ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1802,8 +1802,8 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc kcConArgTys :: NewOrData -> TcKind -> [HsConFieldSpec on GhcRn] -> TcM () kcConArgTys new_or_data res_kind arg_tys = do { let exp_kind = getArgExpKind new_or_data res_kind - ; forM_ arg_tys (\(CFS _ _ _ mult ty) -> do _ <- tcCheckLHsTypeInContext ty exp_kind - tcMult mult) + ; forM_ arg_tys (\(CFS _ _ _ mult ty _) -> do _ <- tcCheckLHsTypeInContext ty exp_kind + tcMult mult) -- See Note [Implementation of UnliftedNewtypes], STEP 2 } @@ -3925,7 +3925,7 @@ tcConGADTArgs exp_kind (RecConGADT _ fields) tcConArg :: ContextKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) -tcConArg exp_kind (CFS (_, src) unp str w bty) +tcConArg exp_kind (CFS (_, src) unp str w bty _) = do { traceTc "tcConArg 1" (ppr bty) ; arg_ty <- tcCheckLHsTypeInContext bty exp_kind ; w' <- tcDataConMult w ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -782,7 +782,7 @@ cvt_arg (Bang su ss, ty) ; let ty' = parenthesizeHsType appPrec ty'' su' = cvtSrcUnpackedness su ss' = cvtSrcStrictness ss - ; return $ CFS noAnn su' ss' hsNoMultAnn ty' } + ; return $ CFS noAnn su' ss' hsNoMultAnn ty' Nothing } cvt_id_arg :: TH.Name -- ^ parent constructor name -> (TH.Name, TH.Bang, TH.Type) -> CvtM (LConDeclField GhcPs) @@ -793,8 +793,7 @@ cvt_id_arg parent_con (i, str, ty) { cd_fld_ext = noExtField , cd_fld_names = [L (l2l li) $ FieldOcc noExtField (L li i')] - , cd_fld_spec = ty' - , cd_fld_doc = Nothing} } + , cd_fld_spec = ty' } } cvtDerivs :: [TH.DerivClause] -> CvtM (HsDeriving GhcPs) cvtDerivs cs = do { mapM cvtDerivClause cs } ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -1077,12 +1077,11 @@ data HsTupleSort = HsUnboxedTuple type LConDeclField pass = XRec pass (ConDeclField pass) -- | Constructor Declaration Field -data ConDeclField pass -- Record fields have Haddock docs on them +data ConDeclField pass = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_spec :: HsConFieldSpec OnRecField pass, - cd_fld_doc :: Maybe (LHsDoc pass)} + cd_fld_spec :: HsConFieldSpec OnRecField pass } | XConDeclField !(XXConDeclField pass) -- | Describes the arguments to a data constructor. This is a common @@ -1117,7 +1116,8 @@ data HsConFieldSpec on pass , cfs_unpack :: SrcUnpackedness , cfs_bang :: SrcStrictness , cfs_multiplicity :: HsMultAnnOn on (LHsType pass) pass - , cfs_type :: LHsType pass } + , cfs_type :: LHsType pass + , cfs_doc :: Maybe (LHsDoc pass) } hsConFieldSpecGeneralize :: HsConFieldSpec on pass -> HsConFieldSpec on1 pass hsConFieldSpecGeneralize = unsafeCoerce ===================================== testsuite/tests/ghc-api/exactprint/Test20239.stderr ===================================== @@ -192,7 +192,8 @@ (EpaComments [])) (Unqual - {OccName: Query})))))]) + {OccName: Query})))) + (Nothing))]) (Nothing))) ,(L (EpAnn @@ -390,7 +391,8 @@ (EpTok (EpaSpan { Test20239.hs:7:84 }))) (HsBoxedOrConstraintTuple) - [])))))))))))))]) + [])))))))))))) + (Nothing))]) (Nothing)))]) []))))))])) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr ===================================== @@ -272,7 +272,8 @@ (EpTok (EpaSpan { T17544_kw.hs:19:19 }))) (HsBoxedOrConstraintTuple) - [])))]) + [])) + (Nothing))]) (L (EpAnn (EpaSpan { T17544_kw.hs:19:24-26 }) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr ===================================== @@ -140,7 +140,8 @@ (EpaComments [])) (Unqual - {OccName: Int})))))]) + {OccName: Int})))) + (Nothing))]) (Just (L { T24221.hs:4:3-20 } @@ -213,7 +214,8 @@ (EpaComments [])) (Unqual - {OccName: Int})))))]) + {OccName: Int})))) + (Nothing))]) (Just (L { T24221.hs:6:3-20 } @@ -283,7 +285,8 @@ (EpaComments [])) (Unqual - {OccName: Int}))))) + {OccName: Int})))) + (Nothing)) (CFS ((,) ((,,) @@ -315,7 +318,8 @@ (EpaComments [])) (Unqual - {OccName: Bool})))))) + {OccName: Bool})))) + (Nothing))) (Just (L { T24221.hs:8:3-33 } @@ -430,7 +434,8 @@ (EpaComments [])) (Unqual - {OccName: Int}))))) + {OccName: Int})))) + (Nothing)) (CFS ((,) ((,,) @@ -462,7 +467,8 @@ (EpaComments [])) (Unqual - {OccName: Bool})))))) + {OccName: Bool})))) + (Nothing))) (Just (L { T24221.hs:12:15-45 } @@ -566,39 +572,31 @@ []) (EpaComments [])) - (HsDocTy - (NoExtField) + (HsTyVar + (NoEpTok) + (NotPromoted) (L (EpAnn (EpaSpan { T24221.hs:15:3-5 }) - (AnnListItem + (NameAnnTrailing []) (EpaComments [])) - (HsTyVar - (NoEpTok) - (NotPromoted) - (L - (EpAnn - (EpaSpan { T24221.hs:15:3-5 }) - (NameAnnTrailing - []) - (EpaComments - [])) - (Unqual - {OccName: Int})))) - (L - { T24221.hs:15:10-26 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringPrevious) - (:| - (L - { T24221.hs:15:14-26 } - (HsDocStringChunk - " Docs for Int")) - [])) - []))))) + (Unqual + {OccName: Int})))) + (Just + (L + { T24221.hs:15:10-26 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringPrevious) + (:| + (L + { T24221.hs:15:14-26 } + (HsDocStringChunk + " Docs for Int")) + [])) + [])))) (CFS ((,) ((,,) @@ -619,39 +617,31 @@ []) (EpaComments [])) - (HsDocTy - (NoExtField) + (HsTyVar + (NoEpTok) + (NotPromoted) (L (EpAnn (EpaSpan { T24221.hs:17:3-6 }) - (AnnListItem + (NameAnnTrailing []) (EpaComments [])) - (HsTyVar - (NoEpTok) - (NotPromoted) - (L - (EpAnn - (EpaSpan { T24221.hs:17:3-6 }) - (NameAnnTrailing - []) - (EpaComments - [])) - (Unqual - {OccName: Bool})))) - (L - { T24221.hs:17:10-27 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringPrevious) - (:| - (L - { T24221.hs:17:14-27 } - (HsDocStringChunk - " Docs for Bool")) - [])) - [])))))) + (Unqual + {OccName: Bool})))) + (Just + (L + { T24221.hs:17:10-27 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringPrevious) + (:| + (L + { T24221.hs:17:14-27 } + (HsDocStringChunk + " Docs for Bool")) + [])) + []))))) (Just (L { T24221.hs:16:10-40 } @@ -755,39 +745,31 @@ []) (EpaComments [])) - (HsDocTy - (NoExtField) + (HsTyVar + (NoEpTok) + (NotPromoted) (L (EpAnn (EpaSpan { T24221.hs:21:3-5 }) - (AnnListItem + (NameAnnTrailing []) (EpaComments [])) - (HsTyVar - (NoEpTok) - (NotPromoted) - (L - (EpAnn - (EpaSpan { T24221.hs:21:3-5 }) - (NameAnnTrailing - []) - (EpaComments - [])) - (Unqual - {OccName: Int})))) - (L - { T24221.hs:20:3-19 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringNext) - (:| - (L - { T24221.hs:20:7-19 } - (HsDocStringChunk - " Docs for Int")) - [])) - []))))) + (Unqual + {OccName: Int})))) + (Just + (L + { T24221.hs:20:3-19 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringNext) + (:| + (L + { T24221.hs:20:7-19 } + (HsDocStringChunk + " Docs for Int")) + [])) + [])))) (CFS ((,) ((,,) @@ -808,39 +790,31 @@ []) (EpaComments [])) - (HsDocTy - (NoExtField) + (HsTyVar + (NoEpTok) + (NotPromoted) (L (EpAnn (EpaSpan { T24221.hs:25:3-6 }) - (AnnListItem + (NameAnnTrailing []) (EpaComments [])) - (HsTyVar - (NoEpTok) - (NotPromoted) - (L - (EpAnn - (EpaSpan { T24221.hs:25:3-6 }) - (NameAnnTrailing - []) - (EpaComments - [])) - (Unqual - {OccName: Bool})))) - (L - { T24221.hs:24:3-20 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringNext) - (:| - (L - { T24221.hs:24:7-20 } - (HsDocStringChunk - " Docs for Bool")) - [])) - [])))))) + (Unqual + {OccName: Bool})))) + (Just + (L + { T24221.hs:24:3-20 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringNext) + (:| + (L + { T24221.hs:24:7-20 } + (HsDocStringChunk + " Docs for Bool")) + [])) + []))))) (Just (L { T24221.hs:22:3-33 } @@ -999,20 +973,20 @@ (EpaComments [])) (Unqual - {OccName: Int}))))) - (Just - (L - { T24221.hs:28:24-39 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringPrevious) - (:| - (L - { T24221.hs:28:28-39 } - (HsDocStringChunk - " Docs for a6")) - [])) - []))))) + {OccName: Int})))) + (Just + (L + { T24221.hs:28:24-39 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringPrevious) + (:| + (L + { T24221.hs:28:28-39 } + (HsDocStringChunk + " Docs for a6")) + [])) + [])))))) ,(L (EpAnn (EpaSpan { T24221.hs:29:12-20 }) @@ -1072,20 +1046,20 @@ (EpaComments [])) (Unqual - {OccName: Int}))))) - (Just - (L - { T24221.hs:29:24-39 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringPrevious) - (:| - (L - { T24221.hs:29:28-39 } - (HsDocStringChunk - " Docs for b6")) - [])) - [])))))])) + {OccName: Int})))) + (Just + (L + { T24221.hs:29:24-39 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringPrevious) + (:| + (L + { T24221.hs:29:28-39 } + (HsDocStringChunk + " Docs for b6")) + [])) + []))))))])) (Nothing)))]) [])))) ,(L @@ -1232,20 +1206,20 @@ (EpaComments [])) (Unqual - {OccName: Int}))))) - (Just - (L - { T24221.hs:33:20-35 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringPrevious) - (:| - (L - { T24221.hs:33:24-35 } - (HsDocStringChunk - " Docs for a7")) - [])) - []))))) + {OccName: Int})))) + (Just + (L + { T24221.hs:33:20-35 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringPrevious) + (:| + (L + { T24221.hs:33:24-35 } + (HsDocStringChunk + " Docs for a7")) + [])) + [])))))) ,(L (EpAnn (EpaSpan { T24221.hs:34:7-15 }) @@ -1305,20 +1279,20 @@ (EpaComments [])) (Unqual - {OccName: Int}))))) - (Just - (L - { T24221.hs:34:20-35 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringPrevious) - (:| - (L - { T24221.hs:34:24-35 } - (HsDocStringChunk - " Docs for b7")) - [])) - [])))))])) + {OccName: Int})))) + (Just + (L + { T24221.hs:34:20-35 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringPrevious) + (:| + (L + { T24221.hs:34:24-35 } + (HsDocStringChunk + " Docs for b7")) + [])) + []))))))])) (Just (L { T24221.hs:32:10-29 } @@ -1477,20 +1451,20 @@ (EpaComments [])) (Unqual - {OccName: Int}))))) - (Just - (L - { T24221.hs:39:5-20 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringNext) - (:| - (L - { T24221.hs:39:9-20 } - (HsDocStringChunk - " Docs for a8")) - [])) - []))))) + {OccName: Int})))) + (Just + (L + { T24221.hs:39:5-20 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringNext) + (:| + (L + { T24221.hs:39:9-20 } + (HsDocStringChunk + " Docs for a8")) + [])) + [])))))) ,(L (EpAnn (EpaSpan { T24221.hs:42:5-13 }) @@ -1550,20 +1524,20 @@ (EpaComments [])) (Unqual - {OccName: Int}))))) - (Just - (L - { T24221.hs:41:5-20 } - (WithHsDocIdentifiers - (MultiLineDocString - (HsDocStringNext) - (:| - (L - { T24221.hs:41:9-20 } - (HsDocStringChunk - " Docs for b8")) - [])) - [])))))])) + {OccName: Int})))) + (Just + (L + { T24221.hs:41:5-20 } + (WithHsDocIdentifiers + (MultiLineDocString + (HsDocStringNext) + (:| + (L + { T24221.hs:41:9-20 } + (HsDocStringChunk + " Docs for b8")) + [])) + []))))))])) (Just (L { T24221.hs:37:3-22 } ===================================== testsuite/tests/parser/should_compile/DumpParsedAst.stderr ===================================== @@ -204,7 +204,8 @@ (EpaComments [])) (Unqual - {OccName: Peano})))))]) + {OccName: Peano})))) + (Nothing))]) (Nothing)))]) [])))) ,(L @@ -909,7 +910,8 @@ (EpaComments [])) (Unqual - {OccName: a})))))))))]) + {OccName: a})))))))) + (Nothing))]) (Nothing)))]) [])))) ,(L @@ -2075,7 +2077,8 @@ (EpaComments [])) (Unqual - {OccName: xx})))))))))))))]) + {OccName: xx})))))))))))) + (Nothing))]) (L (EpAnn (EpaSpan { DumpParsedAst.hs:23:39-45 }) ===================================== testsuite/tests/parser/should_compile/DumpRenamedAst.stderr ===================================== @@ -248,7 +248,8 @@ []) (EpaComments [])) - {Name: DumpRenamedAst.Peano}))))]) + {Name: DumpRenamedAst.Peano}))) + (Nothing))]) (Nothing)))]) [])))] [] @@ -1249,7 +1250,8 @@ []) (EpaComments [])) - {Name: xx}))))))))))))]) + {Name: xx}))))))))))) + (Nothing))]) (L (EpAnn (EpaSpan { DumpRenamedAst.hs:20:39-45 }) @@ -1530,7 +1532,8 @@ []) (EpaComments [])) - {Name: a}))))))))]) + {Name: a}))))))) + (Nothing))]) (Nothing)))]) [])))] [] ===================================== testsuite/tests/parser/should_compile/T14189.stderr ===================================== @@ -106,7 +106,8 @@ []) (EpaComments [])) - {Name: GHC.Types.Int}))))]) + {Name: GHC.Types.Int}))) + (Nothing))]) (Nothing))) ,(L (EpAnn @@ -225,8 +226,8 @@ []) (EpaComments [])) - {Name: GHC.Types.Int})))) - (Nothing)))])) + {Name: GHC.Types.Int}))) + (Nothing))))])) (Nothing)))]) [])))] [] ===================================== testsuite/tests/printer/T18791.stderr ===================================== @@ -150,7 +150,8 @@ (EpaComments [])) (Unqual - {OccName: Int})))))]) + {OccName: Int})))) + (Nothing))]) (L (EpAnn (EpaSpan { T18791.hs:5:17 }) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -4424,10 +4424,10 @@ instance ExactPrint (ConDeclField GhcPs) where getAnnotationEntry _ = NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (ConDeclField _ names ftype mdoc) = do + exact (ConDeclField _ names ftype) = do names' <- markAnnotated names ftype' <- markAnnotated ftype - return (ConDeclField noExtField names' ftype' mdoc) + return (ConDeclField noExtField names' ftype') -- --------------------------------------------------------------------- @@ -4443,20 +4443,20 @@ instance ExactPrint (FieldOcc GhcPs) where instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (CFS an unp str arr t) = do + exact (CFS an unp str arr t doc) = do an' <- exactBang an str t' <- markAnnotated t arr' <- markArrow arr - return (CFS an' unp str arr' t') + return (CFS an' unp str arr' t' doc) instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a - exact (CFS an unp str mult t) = do + exact (CFS an unp str mult t doc) = do mult' <- markRecFieldMult mult an' <- exactBang an str t' <- markAnnotated t - return (CFS an' unp str mult' t') + return (CFS an' unp str mult' t' doc) exactBang :: (Monoid w, Monad m) => XConFieldSpec GhcPs -> SrcStrictness -> EP w m (XConFieldSpec GhcPs) exactBang ((o,c,tk), mt) str = do ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -1031,7 +1031,7 @@ ppSideBySideConstr subdocs unicode leader (L _ con) = -- | Pretty-print a record field ppSideBySideField :: [(DocName, DocForDecl DocName)] -> Bool -> ConDeclField DocNameI -> LaTeX -ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = +ppSideBySideField subdocs unicode (ConDeclField _ names ltype) = decltt ( cat (punctuate comma (map (ppBinder . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode ltype (dcolon unicode) @@ -1039,16 +1039,16 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype _) = ) <-> rDoc mbDoc where - -- don't use cd_fld_doc for same reason we don't use con_doc above - -- Where there is more than one name, they all have the same documentation mbDoc = lookup (unLoc . foLabel . unLoc $ name) subdocs >>= fmap _doc . combineDocumentation . fst name = case Maybe.listToMaybe names of Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd +-- don't use cfs_doc for same reason we don't use con_doc above +-- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX -ppRecFieldMultAnn unicode (CFS _ _ _ arr _) following = case arr of +ppRecFieldMultAnn unicode (CFS _ _ _ arr _ _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1533,7 +1533,7 @@ ppSideBySideField -> Qualification -> ConDeclField DocNameI -> SubDecl -ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = +ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype) = ( hsep ( punctuate comma @@ -1548,21 +1548,21 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype _) = , [] ) where - -- don't use cd_fld_doc for same reason we don't use con_doc above - -- Where there is more than one name, they all have the same documentation mbDoc = lookup (unLoc . foLabel $ unLoc declName) subdocs >>= combineDocumentation . fst declName = case Maybe.listToMaybe names of Nothing -> error "No names. An invariant was broken. Please report this to the Haddock project" Just hd -> hd +-- don't use cfs_doc for same reason we don't use con_doc above +-- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html -ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _) following = case arr of +ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _ _) following = case arr of HsUnannotated _ _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following ppShortField :: Bool -> Unicode -> Qualification -> ConDeclField DocNameI -> Html -ppShortField summary unicode qual (ConDeclField _ names ltype _) = +ppShortField summary unicode qual (ConDeclField _ names ltype) = hsep (punctuate comma (map ((ppBinder summary) . rdrNameOcc . foExt . unLoc) names)) <+> ppRecFieldMultAnn unicode qual ltype (dcolon unicode) <+> ppLType unicode qual HideEmptyContexts (hsConFieldSpecToHsTypeNoMult ltype) ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -497,7 +497,7 @@ synifyDataCon use_gadt_syntax dc = ( \(Scaled mult ty) (HsSrcBang st (HsBang unp str)) -> let tySyn = synifyType WithinType [] ty multSyn = synifyMultRec [] mult - in CFS (noAnn, st) unp str multSyn tySyn + in CFS (noAnn, st) unp str multSyn tySyn Nothing ) arg_tys (dataConSrcBangs dc) @@ -509,7 +509,6 @@ synifyDataCon use_gadt_syntax dc = noExtField [noLocA $ FieldOcc (mkVarUnqual $ field_label $ flLabel fl) (noLocA (flSelector fl))] synTy - Nothing mk_h98_arg_tys :: Either String (HsConDeclH98Details GhcRn) mk_h98_arg_tys = case (use_named_field_syntax, use_infix_syntax) of ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -196,10 +196,10 @@ hsConFieldSpecToFunTy (hsConFieldSpecGeneralize -> cfs) tgt = noLocA (HsFunTy noAnn (cfs_multiplicity cfs) (hsConFieldSpecToHsTypeNoMult cfs) tgt) hsConFieldSpecToHsTypeNoMult - :: (XRec pass (HsType pass) ~ GenLocated e (HsType pass), HasAnnotation e, NoAnn (XBangTy pass), XXType pass ~ HsTypeGhcPsExt pass) + :: (XRec pass (HsType pass) ~ GenLocated e (HsType pass), HasAnnotation e, NoAnn (XBangTy pass), NoAnn (XDocTy pass), XXType pass ~ HsTypeGhcPsExt pass) => HsConFieldSpec on pass -> LHsType pass -hsConFieldSpecToHsTypeNoMult (CFS _ unp str _ t) = case t of - L l (HsDocTy x ty doc) -> L l (HsDocTy x (mkBang unp str ty) doc) +hsConFieldSpecToHsTypeNoMult (CFS _ unp str _ t doc) = case doc of + Just doc' -> noLocA (HsDocTy noAnn (mkBang unp str t) doc') _ -> mkBang unp str t where mkBang NoSrcUnpack NoSrcStrict ty = ty @@ -373,11 +373,11 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] -- see above field_avail :: LConDeclField GhcRn -> Bool - field_avail (L _ (ConDeclField _ fs _ _)) = + field_avail (L _ (ConDeclField _ fs _)) = all (\f -> (unLoc . foLabel . unLoc $ f) `elem` names) fs field_types :: [LConDeclField GhcRn] -> [HsConFieldSpec OnArrow GhcRn] - field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t _) <- flds] + field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t) <- flds] keep _ = Nothing restrictDecls :: [Name] -> [LSig GhcRn] -> [LSig GhcRn] @@ -526,7 +526,7 @@ reparenBndrKind v at XBndrKind{} = v -- | Add parenthesis around the types in a 'ConDeclField' (see 'reparenTypePrec') reparenConDeclField :: XRecCond a => ConDeclField a -> ConDeclField a -reparenConDeclField (ConDeclField x n (CFS an unp str m t) d) = ConDeclField x n (CFS an unp str m (reparenLType t)) d +reparenConDeclField (ConDeclField x n (CFS an unp str m t d)) = ConDeclField x n (CFS an unp str m (reparenLType t) d) reparenConDeclField c at XConDeclField{} = c ------------------------------------------------------------------------------- ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Create.hs ===================================== @@ -998,13 +998,13 @@ extractRecSel _ _ _ [] = Left "extractRecSel: selector not found" extractRecSel nm t tvs (L _ con : rest) = case getRecConArgs_maybe con of Just (L _ fields) - | ((l, L _ (ConDeclField _ _nn ty _)) : _) <- matching_fields fields -> + | ((l, L _ (ConDeclField _ _nn ty)) : _) <- matching_fields fields -> pure (L (noAnnSrcSpan l) (TypeSig noAnn [noLocA nm] (mkEmptyWildCardBndrs $ mkEmptySigType (noLocA (HsFunTy noExtField (HsUnrestrictedArrow noExtField) data_ty (cfs_type ty)))))) _ -> extractRecSel nm t tvs rest where matching_fields :: [LConDeclField GhcRn] -> [(SrcSpan, LConDeclField GhcRn)] matching_fields flds = - [ (locA l, f) | f@(L _ (ConDeclField _ ns _ _)) <- flds, L l n <- ns, unLoc (foLabel n) == nm + [ (locA l, f) | f@(L _ (ConDeclField _ ns _)) <- flds, L l n <- ns, unLoc (foLabel n) == nm ] data_ty -- ResTyGADT _ ty <- con_res con = ty ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -719,7 +719,11 @@ renameCon renameHsConFieldSpec :: HsConFieldSpec on GhcRn -> RnM (HsConFieldSpec on DocNameI) -renameHsConFieldSpec (CFS _ unp str w ty) = CFS noExtField unp str <$> renameMultAnnOn w <*> renameLType ty +renameHsConFieldSpec (CFS _ unp str w ty doc) = do + w' <- renameMultAnnOn w + ty' <- renameLType ty + doc' <- mapM renameLDocHsSyn doc + return (CFS noExtField unp str w' ty' doc') renameH98Details :: HsConDeclH98Details GhcRn @@ -742,11 +746,10 @@ renameGADTDetails (RecConGADT _ (L l fields)) = do renameGADTDetails (PrefixConGADT _ ps) = PrefixConGADT noExtField <$> mapM renameHsConFieldSpec ps renameConDeclFieldField :: LConDeclField GhcRn -> RnM (LConDeclField DocNameI) -renameConDeclFieldField (L l (ConDeclField _ names t doc)) = do +renameConDeclFieldField (L l (ConDeclField _ names t)) = do names' <- mapM renameLFieldOcc names t' <- renameHsConFieldSpec t - doc' <- mapM renameLDocHsSyn doc - return $ L (locA l) (ConDeclField noExtField names' t' doc') + return $ L (locA l) (ConDeclField noExtField names' t') renameLFieldOcc :: LFieldOcc GhcRn -> RnM (LFieldOcc DocNameI) renameLFieldOcc (L l (FieldOcc rdr (L n sel))) = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/146774f9da422bae3779e6a228df0891e66a4869 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/146774f9da422bae3779e6a228df0891e66a4869 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 09:31:16 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Wed, 22 Jan 2025 04:31:16 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] update CI images Message-ID: <6790bae461fbe_3afff936856c5329d@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: d8751ef9 by Luite Stegeman at 2025-01-22T10:19:20+01:00 update CI images - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: 572353e0644044fe3a5465bba4342a9a0b0eb60e + DOCKER_REV: 6d7180996b9ea0a04bac7f3b056312451db5251d # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d8751ef948df7267442811526b13f719eef9488a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d8751ef948df7267442811526b13f719eef9488a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 09:42:06 2025 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Wed, 22 Jan 2025 04:42:06 -0500 Subject: [Git][ghc/ghc][wip/int-index/list-tuple-cleanup] 3 commits: Fix .stdout-mingw32 Message-ID: <6790bd6e5cfba_3afff946111c556ab@gitlab.mail> Vladislav Zavialov pushed to branch wip/int-index/list-tuple-cleanup at Glasgow Haskell Compiler / GHC Commits: a60830e3 by Vladislav Zavialov at 2025-01-21T15:43:57+03:00 Fix .stdout-mingw32 - - - - - 77c42729 by Vladislav Zavialov at 2025-01-22T00:23:07+03:00 Check namespaces and arity ranges - - - - - b2ece451 by Vladislav Zavialov at 2025-01-22T00:23:39+03:00 Comments only - - - - - 3 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Types/Name/Cache.hs - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -847,12 +847,20 @@ Note [isBuiltInOcc_maybe] syntax, i.e. unqualified names that can be unambiguously resolved even without knowing what's currently in scope (such names also can't be imported, exported, or redefined in another module). +More on that in Note [Built-in syntax and the OrigNameCache] in GHC.Types.Name.Cache. -* Use case #1: making TH's `mkName` work with built-in syntax, - e.g. $(conT (mkName "[]")) is the same as [] +In GHC, there are two use cases for `isBuiltInOcc_maybe`: -* Use case #2: detecting bulit-in syntax in `infix` declarations, - e.g. users can't write `infixl 6 :` (#15233) +1. Making TH's `mkName` work with built-in syntax, + e.g. $(conT (mkName "[]")) is the same as [] + +2. Detecting bulit-in syntax in `infix` declarations, + e.g. users can't write `infixl 6 :` (#15233) + +The parser takes a shortcut and produces Exact RdrNames directly, +so it doesn't need to match on an OccName with isBuiltInOcc_maybe. + +And here are the properties of `isBuiltInOcc_maybe`: * The set of names recognized by `isBuiltInOcc_maybe` is essentialy the same as the set of names that the parser resolves to Exact RdrNames, @@ -889,16 +897,23 @@ or redefined in another module). * The /input/ to `isBuiltInOcc_maybe` needs to be built-in syntax for the predicate to match, but the /output/ is not necessarily built-in syntax. For example, - 1) listTyConName - input: mkOccName tcClsName "[]" ("[]" is built-in syntax) - output: GHC.Types.List ("List" is a normal name) - 2) tupleTyConName - input: mkOccName tcClsName "(,)" ("(,)" is built-in syntax) - output: GHC.Tuple.Tuple2 ("Tuple2" is a normal name) - 3) unboxedSumTyConName - input: mkOccName tcClsName "(#|#)" ("(#|#)" is built-in syntax) - output: GHC.Types.Sum2# - Therefore, `GHC.Types.Name.isBuiltInSyntax` may not hold for the name + + 1) input: mkTcOcc "[]" -- built-in syntax + output: Just listTyConName -- user syntax (GHC.Types.List) + + 2) input: mkDataOcc "[]" -- built-in syntax + output: Just nilDataConName -- built-in syntax [] + + 3) input: mkTcOcc "List" -- user syntax + output: Nothing -- no match + + 4) input: mkTcOcc "(,)" -- built-in syntax + output: Just (tupleTyConName BoxedTuple 2) -- user syntax (GHC.Types.Tuple2) + + 5) input: mkTcOcc "(#|#)" -- built-in syntax + output: Just (unboxedSumTyConName 2) -- user syntax (GHC.Types.Sum2#) + + Therefore, `GHC.Types.Name.isBuiltInSyntax` may or may not hold for the name returned by `isBuiltInOcc_maybe`. -} @@ -1037,20 +1052,21 @@ sbs_unboxed !sbs = n = SBS.length sbs -- O(1) -- (sbs_Sum sbs) checks if the string has form "SumN#" or "SumNM#", --- where N,M are decimal digits ['0'..'9'], and return the corresponding arity. +-- where "N" or "NM" is a decimal numeral in the [2..mAX_SUM_SIZE] range. sbs_Sum :: SBS.ShortByteString -> Maybe Arity sbs_Sum !sbs | n >= 3 && SBS.unsafeIndex sbs 0 == 83 -- ord 'S' && SBS.unsafeIndex sbs 1 == 117 -- ord 'u' && SBS.unsafeIndex sbs 2 == 109 -- ord 'm' , Just (Unboxed, arity) <- sbs_arity_boxity sbs 3 + , arity >= 2, arity <= mAX_SUM_SIZE = Just arity | otherwise = Nothing where n = SBS.length sbs -- O(1) -- (sbs_Tuple sbs) checks if the string has form "TupleN", "TupleNM", "TupleN#" or "TupleNM#", --- where N,M are decimal digits ['0'..'9'], and return the corresponding boxity and arity. +-- where "N" or "NM" is a decimal numeral in the [2..mAX_TUPLE_SIZE] range. sbs_Tuple :: SBS.ShortByteString -> Maybe (Boxity, Arity) sbs_Tuple !sbs | n >= 5 && SBS.unsafeIndex sbs 0 == 84 -- ord 'T' @@ -1058,13 +1074,15 @@ sbs_Tuple !sbs && SBS.unsafeIndex sbs 2 == 112 -- ord 'p' && SBS.unsafeIndex sbs 3 == 108 -- ord 'l' && SBS.unsafeIndex sbs 4 == 101 -- ord 'e' - = sbs_arity_boxity sbs 5 + , Just r@(_, arity) <- sbs_arity_boxity sbs 5 + , arity >= 2, arity <= mAX_TUPLE_SIZE + = Just r | otherwise = Nothing where n = SBS.length sbs -- O(1) -- (sbs_CTuple sbs) checks if the string has form "CTupleN" or "CTupleNM", --- where N,M are decimal digits ['0'..'9'], and return the corresponding arity. +-- where "N" or "NM" is a decimal numeral in the [2..mAX_CTUPLE_SIZE] range. sbs_CTuple :: SBS.ShortByteString -> Maybe Arity sbs_CTuple !sbs | n >= 6 && SBS.unsafeIndex sbs 0 == 67 -- ord 'C' @@ -1074,13 +1092,14 @@ sbs_CTuple !sbs && SBS.unsafeIndex sbs 4 == 108 -- ord 'l' && SBS.unsafeIndex sbs 5 == 101 -- ord 'e' , Just (Boxed, arity) <- sbs_arity_boxity sbs 6 + , arity >= 2, arity <= mAX_CTUPLE_SIZE = Just arity | otherwise = Nothing where n = SBS.length sbs -- O(1) -- (sbs_arity_boxity sbs i) parses bytes from position `i` to the end, --- matching single- and double-digit decimal numbers (i.e. from 0 to 99) +-- matching single- and double-digit decimals numerals (i.e. from 0 to 99) -- possibly followed by '#'. See Note [Small Ints parsing] sbs_arity_boxity :: SBS.ShortByteString -> Int -> Maybe (Boxity, Arity) sbs_arity_boxity !sbs !i = @@ -1119,39 +1138,94 @@ sbs_arity_boxity !sbs !i = = Just (Unboxed, from_digit x1 * 10 + from_digit x2) parse3 _ _ _ = Nothing +-- Identify original names of boxed and unboxed tuple type constructors. +-- Examples: +-- 0b) isTupleTyOrigName_maybe GHC.Tuple (mkTcOcc "Unit") = Just +-- 1b) isTupleTyOrigName_maybe GHC.Tuple (mkTcOcc "Solo") = Just +-- 2b) isTupleTyOrigName_maybe GHC.Tuple (mkTcOcc "Tuple2") = Just +-- 0u) isTupleTyOrigName_maybe GHC.Types (mkTcOcc "Unit#") = Just +-- 1u) isTupleTyOrigName_maybe GHC.Types (mkTcOcc "Solo#") = Just +-- 2u) isTupleTyOrigName_maybe GHC.Types (mkTcOcc "Tuple2#") = Just +-- ... +-- 64b) isTupleTyOrigName_maybe GHC.Tuple (mkTcOcc "Tuple64") = Just +-- 64u) isTupleTyOrigName_maybe GHC.Types (mkTcOcc "Tuple64#") = Just +-- +-- Non-examples: "()", "(##)", "(,)", "(#,#)", "(,,)", "(#,,#)", etc. +-- As far as tuple /types/ are concerned, these are not the original names +-- but rather punned names under ListTuplePuns. +-- +-- Also non-examples: "Tuple0", "Tuple0#", "Tuple1", and "Tuple1#". +-- These are merely type synonyms for "Unit", "Unit#", "Solo", and "Solo#". isTupleTyOrigName_maybe :: Module -> OccName -> Maybe Name isTupleTyOrigName_maybe mod occ - | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES - = match_occ + | mod == gHC_INTERNAL_TUPLE = match_occ_boxed + | mod == gHC_TYPES = match_occ_unboxed where fs = occNameFS occ + ns = occNameSpace occ sbs = fastStringToShortByteString fs -- O(1) field access - match_occ + + match_occ_boxed | occ == occName unitTyConName = Just unitTyConName | occ == occName soloTyConName = Just soloTyConName + | isTcClsNameSpace ns, Just (boxity at Boxed, n) <- sbs_Tuple sbs, n >= 2 + = Just (tyConName (tupleTyCon boxity n)) + | otherwise = Nothing + + match_occ_unboxed | occ == occName unboxedUnitTyConName = Just unboxedUnitTyConName | occ == occName unboxedSoloTyConName = Just unboxedSoloTyConName - - | Just (boxity, n) <- sbs_Tuple sbs, n >= 2 + | isTcClsNameSpace ns, Just (boxity at Unboxed, n) <- sbs_Tuple sbs, n >= 2 = Just (tyConName (tupleTyCon boxity n)) - | otherwise = Nothing + isTupleTyOrigName_maybe _ _ = Nothing +-- Identify original names of boxed and unboxed tuple data constructors. +-- Examples: +-- 0b) isTupleDataOrigName_maybe GHC.Tuple (mkDataOcc "()") = Just +-- 1b) isTupleDataOrigName_maybe GHC.Tuple (mkDataOcc "MkSolo") = Just +-- 2b) isTupleDataOrigName_maybe GHC.Tuple (mkDataOcc "(,)") = Just +-- ... +-- 0u) isTupleDataOrigName_maybe GHC.Types (mkDataOcc "(##)") = Just +-- 1u) isTupleDataOrigName_maybe GHC.Types (mkDataOcc "MkSolo#") = Just +-- 2u) isTupleDataOrigName_maybe GHC.Types (mkDataOcc "(#,#)") = Just +-- ... +-- +-- Non-examples: Tuple or Tuple#, as this is the name format of tuple /type/ constructors. isTupleDataOrigName_maybe :: Module -> OccName -> Maybe Name isTupleDataOrigName_maybe mod occ - | mod == gHC_INTERNAL_TUPLE || mod == gHC_TYPES - = match_occ + | mod == gHC_INTERNAL_TUPLE = match_occ_boxed + | mod == gHC_TYPES = match_occ_unboxed where - match_occ + match_occ_boxed | occ == occName soloDataConName = Just soloDataConName + | isDataConNameSpace ns, Just n <- (is_boxed_tup_syntax fs) + = Just (tupleDataConName Boxed n) + | otherwise = Nothing + match_occ_unboxed | occ == occName unboxedSoloDataConName = Just unboxedSoloDataConName - | Just n <- (is_boxed_tup_syntax fs) = Just (tupleDataConName Boxed n) - | Just n <- (is_unboxed_tup_syntax fs) = Just (tupleDataConName Unboxed n) + | isDataConNameSpace ns, Just n <- (is_unboxed_tup_syntax fs) + = Just (tupleDataConName Unboxed n) | otherwise = Nothing fs = occNameFS occ + ns = occNameSpace occ isTupleDataOrigName_maybe _ _ = Nothing +-- Identify original names of constraint tuples. +-- Examples: +-- 0) isCTupleOrigName_maybe GHC.Classes (mkClsOcc "CUnit") = Just +-- 1) isCTupleOrigName_maybe GHC.Classes (mkClsOcc "CSolo") = Just +-- 2) isCTupleOrigName_maybe GHC.Classes (mkClsOcc "CTuple2") = Just +-- ... +-- 64) isCTupleOrigName_maybe GHC.Classes (mkClsOcc "CTuple64") = Just +-- +-- Non-examples: "()", "(,)", "(,,)", etc. +-- As far as constraint tuples are concerned, these are not the original names +-- but rather punned names under ListTuplePuns. +-- +-- Also non-examples: "CTuple0" and "CTuple1". +-- These are merely type synonyms for "CUnit" and "CSolo". isCTupleOrigName_maybe :: Module -> OccName -> Maybe Name isCTupleOrigName_maybe mod occ | mod == gHC_CLASSES @@ -1170,22 +1244,47 @@ isCTupleOrigName_maybe mod occ isCTupleOrigName_maybe _ _ = Nothing +-- Identify original names of unboxed sum type constructors. +-- Examples: +-- 2) isSumTyOrigName_maybe GHC.Types (mkTcOcc "Sum2#") = Just +-- 3) isSumTyOrigName_maybe GHC.Types (mkTcOcc "Sum3#") = Just +-- 4) isSumTyOrigName_maybe GHC.Types (mkTcOcc "Sum4#") = Just +-- ... +-- 64) isSumTyOrigName_maybe GHC.Types (mkTcOcc "Sum64#") = Just +-- +-- Non-examples: "(#|#)", "(#||#)", "(#|||#)", etc. These are not valid syntax. +-- Also non-examples: "Sum0#", "Sum1#". These do not exist. isSumTyOrigName_maybe :: Module -> OccName -> Maybe Name isSumTyOrigName_maybe mod occ | mod == gHC_TYPES - , Just n <- sbs_Sum sbs, n >= 2 + , isTcClsNameSpace ns + , Just n <- sbs_Sum sbs + , n >= 2 = Just (tyConName (sumTyCon n)) where fs = occNameFS occ + ns = occNameSpace occ sbs = fastStringToShortByteString fs -- O(1) field access isSumTyOrigName_maybe _ _ = Nothing +-- Identify original names of unboxed sum data constructors. +-- "(#_|#)", "(#_||#)", (#|_|#)" +-- +-- Examples: +-- 1/2) isSumTyOrigName_maybe GHC.Types (mkDataOcc "(#_|#)") = Just +-- 1/3) isSumTyOrigName_maybe GHC.Types (mkDataOcc "(#_||#)") = Just +-- 2/3) isSumTyOrigName_maybe GHC.Types (mkDataOcc "(#|_|#)") = Just +-- ... +-- +-- Non-examples: Sum#, as this is the name format of unboxed sum /type/ constructors. isSumDataOrigName_maybe :: Module -> OccName -> Maybe Name isSumDataOrigName_maybe mod occ | mod == gHC_TYPES + , isDataConNameSpace ns , Just (k,n) <- (is_unboxed_sum_data_syntax fs) = Just (unboxedSumDataConName k n) where fs = occNameFS occ + ns = occNameSpace occ isSumDataOrigName_maybe _ _ = Nothing {- ===================================== compiler/GHC/Types/Name/Cache.hs ===================================== @@ -73,6 +73,8 @@ or exported. Such names come in two varieties: * unboxed sum type syntax `(#|#)`, `(#||#)`, `(#|||#)`, ... * unboxed sum data syntax `(#_|#)`, `(#|_#)`, `(#_||#), ... +Concretely, a built-in name is a WiredIn Name that has a BuiltInSyntax flag. + Historically, GHC used to avoid putting any built-in syntax in the OrigNameCache to avoid dealing with infinite families of names (tuples and sums). This measure has become inadequate with the introduction of NoListTuplePuns (GHC Proposal #475). ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 ===================================== @@ -4474,6 +4474,7 @@ module GHC.PrimOps where type role MVar# nominal representational type MVar# :: forall {l :: Levity}. * -> TYPE (BoxedRep l) -> UnliftedType data MVar# a b + MkSolo# :: forall (k :: RuntimeRep) (a :: TYPE k). a -> (# a #) type MultMul :: Multiplicity -> Multiplicity -> Multiplicity type family MultMul a b where forall (x :: Multiplicity). MultMul One x = x @@ -7485,9 +7486,9 @@ module Prelude.Experimental where data List a = ... pattern Solo :: forall a. a -> Solo a type Solo :: * -> * - data Solo a = ... + data Solo a = MkSolo a type Solo# :: forall (k :: GHC.Types.RuntimeRep). TYPE k -> TYPE (GHC.Types.TupleRep '[k]) - data Solo# a = ... + data Solo# a = MkSolo# a type Sum10# :: forall (k0 :: GHC.Types.RuntimeRep) (k1 :: GHC.Types.RuntimeRep) (k2 :: GHC.Types.RuntimeRep) (k3 :: GHC.Types.RuntimeRep) (k4 :: GHC.Types.RuntimeRep) (k5 :: GHC.Types.RuntimeRep) (k6 :: GHC.Types.RuntimeRep) (k7 :: GHC.Types.RuntimeRep) (k8 :: GHC.Types.RuntimeRep) (k9 :: GHC.Types.RuntimeRep). TYPE k0 -> TYPE k1 -> TYPE k2 -> TYPE k3 -> TYPE k4 -> TYPE k5 -> TYPE k6 -> TYPE k7 -> TYPE k8 -> TYPE k9 -> TYPE (GHC.Types.SumRep [k0, k1, k2, k3, k4, k5, k6, k7, k8, k9]) data Sum10# a b c d e f g h i j = ... type Sum11# :: forall (k0 :: GHC.Types.RuntimeRep) (k1 :: GHC.Types.RuntimeRep) (k2 :: GHC.Types.RuntimeRep) (k3 :: GHC.Types.RuntimeRep) (k4 :: GHC.Types.RuntimeRep) (k5 :: GHC.Types.RuntimeRep) (k6 :: GHC.Types.RuntimeRep) (k7 :: GHC.Types.RuntimeRep) (k8 :: GHC.Types.RuntimeRep) (k9 :: GHC.Types.RuntimeRep) (k10 :: GHC.Types.RuntimeRep). TYPE k0 -> TYPE k1 -> TYPE k2 -> TYPE k3 -> TYPE k4 -> TYPE k5 -> TYPE k6 -> TYPE k7 -> TYPE k8 -> TYPE k9 -> TYPE k10 -> TYPE (GHC.Types.SumRep [k0, k1, k2, k3, k4, k5, k6, k7, k8, k9, k10]) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3b0854288ed74134f69062a3fb1cbdd97315d98b...b2ece4510741c628ce600c32dec8184dc736d265 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3b0854288ed74134f69062a3fb1cbdd97315d98b...b2ece4510741c628ce600c32dec8184dc736d265 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 12:14:26 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Wed, 22 Jan 2025 07:14:26 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] update CI images Message-ID: <6790e122d1d74_cdf66c0214571cd@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: ea8e240b by Luite Stegeman at 2025-01-22T12:21:34+01:00 update CI images - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: 572353e0644044fe3a5465bba4342a9a0b0eb60e + DOCKER_REV: 12eb055c5c8291635ddcca773c806ed0f72ee963 # Sequential version number of all cached things. # Bump to invalidate GitLab CI cache. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ea8e240b3b66c3abf118aa9b69d9b37ea4f98125 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ea8e240b3b66c3abf118aa9b69d9b37ea4f98125 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 12:33:31 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Wed, 22 Jan 2025 07:33:31 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] hadrian: don't pass -this-package-name to GHC 9.2 Message-ID: <6790e59bc1174_cdf6cc71a85872e@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 7def1f40 by Luite Stegeman at 2025-01-22T13:32:28+01:00 hadrian: don't pass -this-package-name to GHC 9.2 it's not supported - - - - - 1 changed file: - hadrian/src/Settings/Builders/Ghc.hs Changes: ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -247,10 +247,10 @@ packageGhcArgs = do , packageDatabaseArgs -- We want to pass -this-unit-id for executables as well for multi-repl to -- work with executable packages but this is buggy on GHC-9.0.2 - , (isLibrary package || (ghc_ver >= makeVersion [9,2,1])) ? mconcat - [ arg ("-this-unit-id " ++ pkgId) - , arg ("-this-package-name " ++ pkgName) - ] + , (isLibrary package || (ghc_ver >= makeVersion [9,2,1])) ? + arg ("-this-unit-id " ++ pkgId) + , (isLibrary package || (ghc_ver >= makeVersion [9,4,1])) ? + arg ("-this-package-name " ++ pkgName) , map ("-package-id " ++) <$> getContextData depIds ] includeGhcArgs :: Args View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7def1f4088c508cb3aeb2d9d49a421311356d86c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7def1f4088c508cb3aeb2d9d49a421311356d86c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 13:54:41 2025 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 22 Jan 2025 08:54:41 -0500 Subject: [Git][ghc/ghc][wip/T18631] doc: Add documentation for -XDoAndIfThenElse Message-ID: <6790f8a110e6c_55b921c73d49621e@gitlab.mail> Teo Camarasu pushed to branch wip/T18631 at Glasgow Haskell Compiler / GHC Commits: e285f97b by Teo Camarasu at 2025-01-22T13:54:27+00:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4 changed files: - docs/users_guide/conf.py - docs/users_guide/expected-undocumented-flags.txt - + docs/users_guide/exts/doandifthenelse.rst - docs/users_guide/exts/syntax.rst Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -36,7 +36,6 @@ nitpick_ignore = [ ("c:type", "bool"), - ("extension", "DoAndIfThenElse"), ("extension", "RelaxedPolyRec"), ] ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -7,7 +7,6 @@ -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional -XAutoDeriveTypeable --XDoAndIfThenElse -XDoRec -XJavaScriptFFI -XParallelArrays ===================================== docs/users_guide/exts/doandifthenelse.rst ===================================== @@ -0,0 +1,30 @@ +.. _doandifthenelse: + +Do And If Then Else +============ + +.. extension:: DoAndIfThenElse + :shortdesc: Allow semicolons in ``if`` expressions. + + :since: 7.6.1 + + :status: Included in :extension:`Haskell2010` + + Allow semicolons in ``if`` expressions. + +Normally, a conditional is written like this: ``if cond then expr1 else expr2``. With the extension +:extension:`DoAndIfThenElse`, semicolons are allowed before the ``then`` and also before the ``else``, allowing +``if cond; then expr1; else expr2``. (You can also include either semicolon on its own.) + +Allowing semicolons in the middle of a conditional is useful in connection with layout-controlled +blocks, like ``do``\ -blocks. This is because GHC invisibly inserts a semicolon between each line of a +layout-controlled block. Accordingly, with :extension:`DoAndIfThenElse`, we can write code like this :: + + f mb x y = do + b <- mb + if b + then x + else y + +Without :extension:`DoAndIfThenElse`, the ``then`` and ``else`` lines would have to be indented with respect +to the rest of the lines in the ``do``\ -block. ===================================== docs/users_guide/exts/syntax.rst ===================================== @@ -20,6 +20,7 @@ Syntax lambda_case empty_case multiway_if + doandifthenelse local_fixity_decls block_arguments typed_holes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e285f97b1c056a722b08d7b979611b4eb258d35b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e285f97b1c056a722b08d7b979611b4eb258d35b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 14:02:28 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 22 Jan 2025 09:02:28 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] 2 commits: compiler: avoid saving foreign call target to local when there are no caller-save GlobalRegs Message-ID: <6790fa74b1c84_55b924bc3b4992a1@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 52ea7bde by Cheng Shao at 2025-01-22T14:36:37+01:00 compiler: avoid saving foreign call target to local when there are no caller-save GlobalRegs This patch makes the STG->Cmm backend avoid saving foreign call target to local when there are no caller-save GlobalRegs. Since 321941a8ebe25192cdeece723e1058f2f47809ea, when we lower a foreign call, we unconditionally save the foreign call target to a temporary local first, then rely on cmmSink to clean it up later, which only happens with -fcmm-sink (implied by -O) and not in unoptimized code. And this is troublesome for the wasm backend NCG, which needs to infer a foreign call target symbol's type signature from the Cmm call site. Previously, the NCG has been emitting incorrect type signatures for unoptimized code, which happens to work with `wasm-ld` most of the time, but this is never future-proof against upstream toolchain updates, and it causes horrible breakages when LTO objects are included in linker input. Hence this patch. (cherry picked from commit 8dd8a076058baca45ac52ace25b9c2797d61ef84) - - - - - 38da6843 by Cheng Shao at 2025-01-22T14:37:27+01:00 testsuite: add callee-no-local regression test (cherry picked from commit 986df1abe23aaad4142721fbdb7dd3791cf153ad) - - - - - 5 changed files: - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Foreign.hs - + testsuite/tests/codeGen/should_compile/callee-no-local.hs - + testsuite/tests/codeGen/should_compile/callee-no-local.stderr Changes: ===================================== compiler/GHC/Driver/Config/StgToCmm.hs ===================================== @@ -14,6 +14,7 @@ import GHC.Driver.Backend import GHC.Driver.Session import GHC.Platform import GHC.Platform.Profile +import GHC.Platform.Regs import GHC.Utils.Error import GHC.Unit.Module import GHC.Utils.Outputable @@ -84,6 +85,8 @@ initStgToCmmConfig dflags mod = StgToCmmConfig , stgToCmmAvx2 = isAvx2Enabled dflags , stgToCmmAvx512f = isAvx512fEnabled dflags , stgToCmmTickyAP = gopt Opt_Ticky_AP dflags + -- See Note [Saving foreign call target to local] + , stgToCmmSaveFCallTargetToLocal = any (callerSaves platform) $ activeStgRegs platform } where profile = targetProfile dflags platform = profilePlatform profile bk_end = backend dflags ===================================== compiler/GHC/StgToCmm/Config.hs ===================================== @@ -73,6 +73,8 @@ data StgToCmmConfig = StgToCmmConfig , stgToCmmAllowWordMul2Instr :: !Bool -- ^ Allowed to generate WordMul2 instruction , stgToCmmAllowFMAInstr :: FMASign -> Bool -- ^ Allowed to generate FMA instruction , stgToCmmTickyAP :: !Bool -- ^ Disable use of precomputed standard thunks. + , stgToCmmSaveFCallTargetToLocal :: !Bool -- ^ Save a foreign call target to a Cmm local, see + -- Note [Saving foreign call target to local] for details ------------------------------ SIMD flags ------------------------------------ -- Each of these flags checks vector compatibility with the backend requested -- during compilation. In essence, this means checking for @-fllvm@ which is ===================================== compiler/GHC/StgToCmm/Foreign.hs ===================================== @@ -277,23 +277,83 @@ load_target_into_temp (ForeignTarget expr conv) = do load_target_into_temp other_target@(PrimTarget _) = return other_target +-- Note [Saving foreign call target to local] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- -- What we want to do here is create a new temporary for the foreign -- call argument if it is not safe to use the expression directly, -- because the expression mentions caller-saves GlobalRegs (see -- Note [Register parameter passing]). -- -- However, we can't pattern-match on the expression here, because --- this is used in a loop by GHC.Cmm.Parser, and testing the expression --- results in a black hole. So we always create a temporary, and rely --- on GHC.Cmm.Sink to clean it up later. (Yuck, ToDo). The generated code --- ends up being the same, at least for the RTS .cmm code. +-- this is used in a loop by GHC.Cmm.Parser, and testing the +-- expression results in a black hole. So when there exist +-- caller-saves GlobalRegs, we create a temporary, and rely on +-- GHC.Cmm.Sink to clean it up later. The generated code ends up being +-- the same if -fcmm-sink is enabled (implied by -O). +-- +-- When there doesn't exist caller-save GlobalRegs, keep the original +-- target in place. This matters for the wasm backend, otherwise it +-- cannot infer the target symbol's correct foreign function type in +-- unoptimized Cmm. For instance: +-- +-- foreign import ccall unsafe "foo" c_foo :: IO () +-- +-- Without optimization, previously this would lower to something like: +-- +-- [Test.c_foo_entry() { // [] +-- { [] +-- } +-- {offset +-- cDk: +-- goto cDm; +-- cDm: +-- _cDj::I32 = foo; +-- call "ccall" arg hints: [] result hints: [] (_cDj::I32)(); +-- R1 = GHC.Tuple.()_closure+1; +-- call (I32[P32[Sp]])(R1) args: 4, res: 0, upd: 4; +-- } +-- }, -- +-- The wasm backend only sees "foo" being assigned to a local, but +-- there's no type signature associated with a CLabel! So it has to +-- emit a dummy .functype directive and fingers crossed that wasm-ld +-- tolerates function type mismatch. THis is horrible, not future +-- proof against upstream toolchain upgrades, and already known to +-- break in certain cases (e.g. when LTO objects are involved). +-- +-- Therefore, on wasm as well as other targets that don't risk +-- mentioning caller-saved GlobalRegs in a foreign call target, just +-- keep the original call target in place and don't assign it to a +-- local. So this would now lower to something like: +-- +-- [Test.c_foo_entry() { // [] +-- { [] +-- } +-- {offset +-- cDo: +-- goto cDq; +-- cDq: +-- call "ccall" arg hints: [] result hints: [] foo(); +-- R1 = GHC.Tuple.()_closure+1; +-- call (I32[P32[Sp]])(R1) args: 4, res: 0, upd: 4; +-- } +-- }, +-- +-- Since "foo" appears at call site directly, the wasm backend would +-- now be able to infer its type signature correctly. + maybe_assign_temp :: CmmExpr -> FCode CmmExpr maybe_assign_temp e = do - platform <- getPlatform - reg <- newTemp (cmmExprType platform e) - emitAssign (CmmLocal reg) e - return (CmmReg (CmmLocal reg)) + do_save <- stgToCmmSaveFCallTargetToLocal <$> getStgToCmmConfig + if do_save + then do + platform <- getPlatform + reg <- newTemp (cmmExprType platform e) + emitAssign (CmmLocal reg) e + return (CmmReg (CmmLocal reg)) + else + pure e -- ----------------------------------------------------------------------------- -- Save/restore the thread state in the TSO ===================================== testsuite/tests/codeGen/should_compile/callee-no-local.hs ===================================== @@ -0,0 +1,3 @@ +module Test where + +foreign import ccall unsafe "foo" c_foo :: IO () ===================================== testsuite/tests/codeGen/should_compile/callee-no-local.stderr ===================================== @@ -0,0 +1 @@ + call "ccall" arg hints: [] result hints: [] foo(); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d90494adfd4ad2c9b82d7dffe360f3e2a0675621...38da6843656aa72c112e5fa29e0e9ecd50bd8b0b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d90494adfd4ad2c9b82d7dffe360f3e2a0675621...38da6843656aa72c112e5fa29e0e9ecd50bd8b0b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 14:11:53 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 22 Jan 2025 09:11:53 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] 16 commits: Fix nasty bug in occurrence analyser Message-ID: <6790fca913f85_55b928421c81036a5@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 07393a24 by Simon Peyton Jones at 2025-01-22T14:45:04+01:00 Fix nasty bug in occurrence analyser As #25096 showed, the occurrence analyser was getting one-shot info flat out wrong. This commit does two things: * It fixes the bug and actually makes the code a bit tidier too. The work is done in the new function GHC.Core.Opt.OccurAnal.mkRhsOccEnv, especially the bit that prepares the `occ_one_shots` for the RHS. See Note [The OccEnv for a right hand side] * When floating out a binding we must be conservative about one-shot info. But we were zapping the entire demand info, whereas we only really need zap the /top level/ cardinality. See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels For some reason there is a 2.2% improvement in compile-time allocation for CoOpt_Read. Otherwise nickels and dimes. Metric Decrease: CoOpt_Read (cherry picked from commit f6b4c1c9be71fc6fe4688337752ffa4ad84180d9) - - - - - 1ecd6116 by Arnaud Spiwack at 2025-01-22T14:45:11+01:00 Add tests for 25081 (cherry picked from commit e2f2a56e42d25bae178ae1692390bbbd6275176c) - - - - - 850414e1 by Arnaud Spiwack at 2025-01-22T14:45:11+01:00 Scale multiplicity in list comprehension Fixes #25081 (cherry picked from commit 23f50640e705c132f1a0689d4850866d0f0d76a6) - - - - - 4c37bafd by doyougnu at 2025-01-22T14:45:11+01:00 Rts linker: add case for pc-rel 64 relocation part of the upstream haskell.nix patches (cherry picked from commit bfe4b3d3bbb98b39169fad063c6c32f06d167756) - - - - - 6d3d44bb by Sylvain Henry at 2025-01-22T14:45:11+01:00 Only lookup ghcversion.h file in the RTS include-dirs by default. The code was introduced in 3549c952b535803270872adaf87262f2df0295a4. It used `getPackageIncludePath` which name doesn't convey that it looks into all include paths of the preload units too. So this behavior is probably unintentional and it should be ok to change it. Fix #25106 (cherry picked from commit f954f42823f6ca3588425a0d543d93ace86d89e4) - - - - - 2486f9d0 by Andreas Klebinger at 2025-01-22T14:45:11+01:00 Add since annotation for -fkeep-auto-rules. This partially addresses #25082. - - - - - 77fadb7e by Andreas Klebinger at 2025-01-22T14:45:11+01:00 Mention `-fkeep-auto-rules` in release notes. It was added earlier but hadn't appeared in any release notes yet. Partially addresses #25082. - - - - - 0889c9e7 by Sylvain Henry at 2025-01-22T14:45:11+01:00 Cmm: don't perform unsound optimizations on 32-bit compiler hosts - beef61351b240967b49169d27a9a19565cf3c4af enabled the use of MO_Add/MO_Sub for 64-bit operations in the C and LLVM backends - 6755d833af8c21bbad6585144b10e20ac4a0a1ab did the same for the x86 NCG backend However we store some literal values as `Int` in the compiler. As a result, some Cmm optimizations transformed target 64-bit literals into compiler `Int`. If the compiler is 32-bit, this leads to computing with wrong literals (see #24893 and #24700). This patch disables these Cmm optimizations for 32-bit compilers. This is unsatisfying (optimizations shouldn't be compiler-word-size dependent) but it fixes the bug and it makes the patch easy to backport. A proper fix would be much more invasive but it shall be implemented in the future. Co-authored-by: amesgen <amesgen at amesgen.de> (cherry picked from commit 7446a09a2d5b04b95cd43c03659b5647853124ce) - - - - - cec2db29 by Sylvain Henry at 2025-01-22T14:45:11+01:00 AARCH64 linker: skip NONE relocations This patch is part of the patches upstreamed from haskell.nix. See https://github.com/input-output-hk/haskell.nix/pull/1960 for the original report/patch. (cherry picked from commit c749bdfd3e21d712dc2b966482eb010165bdeebe) - - - - - 2ecb9d68 by sheaf at 2025-01-22T14:45:11+01:00 GHCi debugger: drop record name spaces for Ids When binding new local variables at a breakpoint, we should create Ids with variable namespace, and not record field namespace. Otherwise the rest of the compiler falls over because the IdDetails are wrong. Fixes #25109 (cherry picked from commit c29b2b5a77611b2bd6c3089765079bc43aec3e22) - - - - - 0028decc by Sylvain Henry at 2025-01-22T14:45:11+01:00 JS: support rubbish static literals (#25177) Support for rubbish dynamic literals was added in #24664. This patch does the same for static literals. Fix #25177 (cherry picked from commit 5092dbff750ee5b6fd082b7eed8574922a2b0bf4) - - - - - 14c6b834 by Arsen Arsenović at 2025-01-22T14:45:11+01:00 ghc-toolchain: Don't leave stranded a.outs when testing for -g0 This happened because, when ghc-toolchain tests for -g0, it does so by compiling an empty program. This compilation creates an a.out. Since we create a temporary directory, lets place the test program compilation in it also, so that it gets cleaned up. Fixes: 25b0b40467d0a12601497117c0ad14e1fcab0b74 Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/25203 (cherry picked from commit b16605e7c135f8cfd357a60c7f358132faec6a84) - - - - - 91e1572a by Cheng Shao at 2025-01-22T14:45:11+01:00 rts: fix checkClosure error message This patch fixes an error message in checkClosure() when the closure has already been evacuated. The previous logic was meant to print the evacuated closure's type in the error message, but it was completely wrong, given info was not really an info table, but a tagged pointer that points to the closure's new address. (cherry picked from commit 0d3bc2fa3a9a8c342ec34bb9d32e493655a4ec69) - - - - - 90b3ad99 by Simon Peyton Jones at 2025-01-22T14:45:11+01:00 Add ZonkAny and document it This MR fixed #24817 by adding ZonkAny, which takes a Nat argument. See Note [Any types] in GHC.Builtin.Types, especially wrinkle (Any4). (cherry picked from commit cfbff65a8bde902b4510cdaead847bf7a52b4018) - - - - - 9f5046b3 by Cheng Shao at 2025-01-22T14:45:11+01:00 compiler: avoid saving foreign call target to local when there are no caller-save GlobalRegs This patch makes the STG->Cmm backend avoid saving foreign call target to local when there are no caller-save GlobalRegs. Since 321941a8ebe25192cdeece723e1058f2f47809ea, when we lower a foreign call, we unconditionally save the foreign call target to a temporary local first, then rely on cmmSink to clean it up later, which only happens with -fcmm-sink (implied by -O) and not in unoptimized code. And this is troublesome for the wasm backend NCG, which needs to infer a foreign call target symbol's type signature from the Cmm call site. Previously, the NCG has been emitting incorrect type signatures for unoptimized code, which happens to work with `wasm-ld` most of the time, but this is never future-proof against upstream toolchain updates, and it causes horrible breakages when LTO objects are included in linker input. Hence this patch. (cherry picked from commit 8dd8a076058baca45ac52ace25b9c2797d61ef84) - - - - - c6e5b188 by Cheng Shao at 2025-01-22T14:45:11+01:00 testsuite: add callee-no-local regression test (cherry picked from commit 986df1abe23aaad4142721fbdb7dd3791cf153ad) - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToJS/Literal.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Zonk/Type.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Utils/Outputable.hs - docs/users_guide/9.10.2-notes.rst - docs/users_guide/using-optimisation.rst - rts/linker/PEi386.c - rts/linker/elf_reloc_aarch64.c - rts/sm/Sanity.c - + testsuite/tests/codeGen/should_compile/T25177.hs - + testsuite/tests/codeGen/should_compile/T25177.stderr - testsuite/tests/codeGen/should_compile/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/38da6843656aa72c112e5fa29e0e9ecd50bd8b0b...c6e5b18825363b4a89d262de6d41a7844fab188d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/38da6843656aa72c112e5fa29e0e9ecd50bd8b0b...c6e5b18825363b4a89d262de6d41a7844fab188d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 16:06:06 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 22 Jan 2025 11:06:06 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] 15 commits: compiler: Fix CPP guards around ghc_unique_counter64 Message-ID: <6791176ee35ca_9accd541640155b1@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 62e24547 by Patrick at 2025-01-23T00:05:35+08:00 update kcConDecl to also consider the result type in newtype GADT instance - - - - - 3545b055 by Patrick at 2025-01-23T00:05:35+08:00 peek at the result kind - - - - - 063ca3d3 by Patrick at 2025-01-23T00:05:35+08:00 test if gadt has UserSuppliedResultKind in lhs, we let tc_res_kind to unify with rhs result kind if not to gain more inference - - - - - c6a6509b by Patrick at 2025-01-23T00:05:35+08:00 format and remove getTyConResultKind - - - - - 4fccd34b by Patrick at 2025-01-23T00:05:35+08:00 format - - - - - c4089c8a by Patrick at 2025-01-23T00:05:35+08:00 add comment - - - - - 216fd425 by Patrick at 2025-01-23T00:05:36+08:00 cleanup - - - - - af1497c8 by Patrick at 2025-01-23T00:05:36+08:00 cleanup - - - - - 20f0006a by Patrick at 2025-01-23T00:05:36+08:00 update T25611a - - - - - a9d85561 by Patrick at 2025-01-23T00:05:36+08:00 rename and add note - - - - - 193fe271 by Patrick at 2025-01-23T00:05:36+08:00 update note - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Instance/Family.hs - compiler/GHC/Tc/Module.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1cdef6841ac7d3ce7753df7125f70e5e509f3b5f...193fe27100b476e930292ab22ee527f6e93e4d9f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1cdef6841ac7d3ce7753df7125f70e5e509f3b5f...193fe27100b476e930292ab22ee527f6e93e4d9f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 16:07:47 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 22 Jan 2025 11:07:47 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] update note Message-ID: <679117d341f4a_9accd4ba9241583d@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 1468ce97 by Patrick at 2025-01-23T00:07:39+08:00 update note - - - - - 1 changed file: - compiler/GHC/Tc/TyCl.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1976,7 +1976,7 @@ Again there are two cases to consider in `kcConDecl`: `S g a`) and, for newtypes, ensure that the arugment has that same kind. (KCD3) The tycon's result kind `tc_res_kind` is not used at all in the GADT - case except being newtype without user header kind signature(KCD4); rather it is + case except being newtype without user header kind signature; rather it is accessed via looking up S's kind in the type environment when kind-checking the result type of the data constructor. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1468ce9723add62f0200f1606826c4046cbbf190 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1468ce9723add62f0200f1606826c4046cbbf190 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 16:14:53 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 22 Jan 2025 11:14:53 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] format Message-ID: <6791197dd7556_9accda312a416139@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 6df0b1b3 by Patrick at 2025-01-23T00:14:45+08:00 format - - - - - 2 changed files: - compiler/GHC/Tc/TyCl.hs - compiler/GHC/Tc/TyCl/Instance.hs Changes: ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -14,7 +14,7 @@ -- | Typecheck type and class declarations module GHC.Tc.TyCl ( - UserHeaderKindSig(..), + HasHeaderKindSig(..), tcTyAndClassDecls, -- Functions used by GHC.Tc.TyCl.Instance to check -- data/type family instance declarations @@ -1775,8 +1775,8 @@ kcTyClDecl (DataDecl { tcdLName = (L _ _name) do { traceTc "kcTyClDecl" (ppr tycon $$ ppr (tyConTyVars tycon) $$ ppr (tyConResKind tycon)) ; _ <- tcHsContext ctxt ; kcConDecls (tyConResKind tycon) (if (isJust kindSig) - then UserHeaderKindSig - else NoUserHeaderKindSig) cons + then HasHeaderKindSig + else NoHeaderKindSig) cons } kcTyClDecl (SynDecl { tcdLName = L _ _name, tcdRhs = rhs }) tycon @@ -1841,16 +1841,16 @@ kcConGADTArgs exp_kind con_args = case con_args of ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Specifically for GADT style declarations. User supplied header kind signature as in -`data xxx :: UserHeaderKindSig where ...` +`data xxx :: HasHeaderKindSig where ...` See (KCD4) in Note [kcConDecls: kind-checking data type decls] for why we need to check this. -} -- see Note [Header kind signatures for GADTs] -data UserHeaderKindSig = UserHeaderKindSig | NoUserHeaderKindSig deriving Eq +data HasHeaderKindSig = HasHeaderKindSig | NoHeaderKindSig deriving Eq kcConDecls :: TcKind -- Result kind of tycon -- Used only in H98 case - -> UserHeaderKindSig + -> HasHeaderKindSig -> DataDefnCons (LConDecl GhcRn) -> TcM () -- See Note [kcConDecls: kind-checking data type decls] kcConDecls tc_res_kind usrk cons @@ -1863,7 +1863,7 @@ kcConDecls tc_res_kind usrk cons -- declared with data or newtype, and we need to know the result kind of -- this type. See Note [Implementation of UnliftedNewtypes] for why -- we need the first two arguments. -kcConDecl :: NewOrData -> UserHeaderKindSig -> TcKind -> ConDecl GhcRn -> TcM () +kcConDecl :: NewOrData -> HasHeaderKindSig -> TcKind -> ConDecl GhcRn -> TcM () kcConDecl new_or_data _usrk tc_res_kind (ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs , con_mb_cxt = ex_ctxt, con_args = args }) @@ -1898,7 +1898,7 @@ kcConDecl new_or_data usrk tc_res_kind ; traceTc "kcConDecl:GADT {" (ppr names $$ ppr res_ty $$ ppr tc_res_kind) -- We handle the case of newtypes without user header kind signatures specially -- see (KCD4) in Note [kcConDecls: kind-checking data type decls] - ; con_res_kind <- if NewType == new_or_data && NoUserHeaderKindSig == usrk + ; con_res_kind <- if NewType == new_or_data && NoHeaderKindSig == usrk then return tc_res_kind else newOpenTypeKind ; _ <- tcCheckLHsTypeInContext res_ty $ (TheKind con_res_kind) ===================================== compiler/GHC/Tc/TyCl/Instance.hs ===================================== @@ -946,10 +946,10 @@ tcDataFamInstHeader mb_clsinfo skol_info fam_tc hs_outer_bndrs fixity -- Add constraints from the data constructors -- Fix #25611 -- See DESIGN CHOICE in Note [Kind inference for data family instances] - ; when is_H98_or_newtype $ kcConDecls lhs_applied_kind (if (isJust m_ksig) - then UserHeaderKindSig - else NoUserHeaderKindSig) - hs_cons + ; when is_H98_or_newtype $ + kcConDecls lhs_applied_kind (if (isJust m_ksig) + then HasHeaderKindSig + else NoHeaderKindSig) hs_cons -- Check that the result kind of the TyCon applied to its args View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6df0b1b34b6bd307db0087ce9d3852bf24980c01 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6df0b1b34b6bd307db0087ce9d3852bf24980c01 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 16:27:25 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 22 Jan 2025 11:27:25 -0500 Subject: [Git][ghc/ghc][wip/splice-imports-2024] 381 commits: testsuite: Normalise trailing digits from hole fits output Message-ID: <67911c6dba3df_9accd9ead40186ae@gitlab.mail> Matthew Pickering pushed to branch wip/splice-imports-2024 at Glasgow Haskell Compiler / GHC Commits: d029f170 by Ben Gamari at 2024-10-11T23:43:17-04:00 testsuite: Normalise trailing digits from hole fits output The type variables in the holes fit output from `abstract_refinement_hole_fits` is quite sensitive to compiler configuration. Specifically, a slight change in the inlining behavior of `throw` changes type variable naming in `(>>=)` and a few others. Ideally we would make hole fits output more deterministic but in the meantime we simply normalise this difference away as it not relevant to the test's goal. - - - - - da5d7d0d by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Add test for #25066 - - - - - eb7ddae1 by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Fix #25066 As noted in #25066, the exception backtrace proposal introduced a rather subtle performance regression due to simplification producing Core which the demand analyser concludes may diverge with a precise exception. The nature of the problem is more completely described in the new Note [Hiding precise exception signature in throw]. The (rather hacky) solution we use here hides the problematic optimisation through judicious use of `noinline`. Ultimately however we will want a more principled solution (e.g. #23847). Fixes #255066 CLC proposal: https://github.com/haskell/core-libraries-committee/issues/290 Metric Decrease: T9872d - - - - - 0060ece7 by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Improve documentation of Control.Exception.Backtrace - - - - - 18f532f3 by Ben Gamari at 2024-10-11T23:43:53-04:00 Bump process submodule to v1.6.25.0 - - - - - a9a3badf by Hassan Al-Awwadi at 2024-10-11T23:44:29-04:00 Move HsInteger and HsRat to an extension constructor These constructors were only used during the TC stage, or during template haskell. It seemed clear that it was independent of the source syntax represented in L.H.S, and thus we removed it according to #21592. - - - - - 4dd30cba by Artem Pelenitsyn at 2024-10-11T23:45:09-04:00 Docs: Linear types: link Strict Patterns subsection Also, fix a bug in RST with missing newline before a listing. Co-authored-by: Arnaud Spiwack <arnaud at spiwack.net> - - - - - adca5f2b by Ben Gamari at 2024-10-11T23:45:45-04:00 users guide: Address remaining TODOs in eventlog format docs Closes #25296. - - - - - 9291c125 by Sylvain Henry at 2024-10-11T23:46:26-04:00 Fix z-encoding of tuples (#25364) Tuples with prefix/suffix strings weren't always properly encoded with their shortcut notations. Fix this. - - - - - c08b68bc by Sven Tennie at 2024-10-11T23:47:01-04:00 Delete constants that can be deduced There are macros in MachRegs.h to figure those out. - - - - - 8b402da2 by Zubin Duggal at 2024-10-12T20:36:57+00:00 hadrian: Handle broken symlinks properly when creating source dist directories If we have a broken symlink in the repository, don't try to `need` the symlink or the target of the symlink. Attempting to do so has `shake` attempt to read the target to compute its hash, which fails because the target doesn't exist. - - - - - 16f97667 by Zubin Duggal at 2024-10-12T20:36:57+00:00 hadrian: exclude cabal.project.symlink.broken from source archives Cabal 3.14 introduced a broken symlink in its testsuite. Unfortunately, this broke our source distribution as we use use `tar --dereference` to avoid issues with symlink compatibility on windows, and `tar --dereference` chokes when it encounters any broken symlinks. We can't get rid of `--dereference` because symlinks are generally broken on windows, so the only option is to exclude this file from source archives. see also https://github.com/haskell/cabal/issues/10442 - - - - - f1a2c9fc by Zubin Duggal at 2024-10-12T20:36:57+00:00 Bump Cabal submodule to 3.14 Metric Decrease: MultiLayerModulesTH_OneShot Metric Increase: haddock.Cabal - - - - - 745dd590 by Ben Gamari at 2024-10-14T09:13:12-04:00 users-guide: Document GHCi :where command Resolve #24509. - - - - - e9cc4699 by Alan Zimmerman at 2024-10-14T09:13:48-04:00 EPA: Remove [AddEpAnn] from IE, Pat and some Tys EPA: Remove [AddEpAnn] from LazyPat EPA: Remove [AddEpAnn] from RecordCon/RecordUpd/ConPat EPA: Remove [AddEpAnn] from HsFieldBind EPA: Remove [AddEpAnn] from PatSynBind EPA: Remove [AddEpAnn] from IPBind EPA: Remove [AddEpAnn] from FixSig EPA: Remove [AddEpAnn] from activation rules EPA: Remove [AddEpann] from SpecInstSig EPA: Remove [AddEpAnn] from MinimalSig EPA: Remove [AddEpAnn] from SCCFunSig EPA: Remove [AddEpAnn] from CompleteMatchSig EPA: Remove [AddEpAnn] from AnnSig, as used in PatSynSig, ClassOpSig, TypeSig EPA: Remove [AddEpAnn] from IEThingAbs EPA: Remove [AddEpAnn] from IEThingAll / IEThingWith EPA: Remove [AddEpAnn] from IEModuleContents EPA: Remove [AddEpAnn] from HsOpTy EPA: Remove [AddEpAnn] for various binders EPA: Remove [AddEpAnn] for HsIParamTy - - - - - 81a570bf by Sebastian Graf at 2024-10-14T22:15:31-04:00 Desugaring, plus -Wincomplete-record-selectors This commit does several related things: * Major refactor of the handling of applications in the desugarer. Now all applications are handled in `dsApp`, `ds_app` and related functions. This dramatically simplifies the code and removes complicated cruft that had accumulated. Hooray. Fixes #25281. * Improve the handling of -Wincomplete-record-selectors. We now incorporate the result type of unsaturated record selector applications as well as consider long-distance information in getField applications. Plus, the implmentation now builds the improved `dsApp` stuff above, so it is much easier to understand. Plus, incorporates improved error message wording suggested by Adam Gundry in !12685. Fixes #24824, #24891 See the long Note [Detecting incomplete record selectors] * Add -Wincomplete-record-selectors to -Wall, as specified in GHC Proposal 516. To do this, I also had to add -Wno-incomplete-record-selectors to the build flags for Cabal in GHC's CI. See hadrian/src/Settings/Warnings.hs. We can remove this when Cabal is updated so that it doesn't trigger the warning: https://github.com/haskell/cabal/issues/10402 2.6% decrease in compile time allocation in RecordUpPerf Metric Decrease: RecordUpdPerf - - - - - ae7bc08e by Simon Peyton Jones at 2024-10-14T22:15:31-04:00 Elmininate incomplete record selectors This patch is a pure refactor of GHC's source code, to avoid the use of partial record selectors. It was provoked by adding -Wincomplete-record-selectors to -Wall (as the GHC Proposal specified), which in turn showed up lots of places where GHC was using incomplete record selectors. This patch does mostly-simple refactoring to make it clear to the pattern match checker that there is in fact no partiality. There is one externally-visible change: I changed the data type HoleFit to split out the two cases data HoleFit = TcHoleFit TcHoleFit | RawHoleFit SDoc data TcHoleFit = HoleFit { ...lots of fields } There are large swathes of code that just deal with `TcHoleFit`, and having it as a separate data types makes it apparent that `RawHoleFit` can't occur. This makes it much better -- but the change is visible in the HolePlugin interface. I decided that there are so few clients of this API that it's worth the change. I moved several functions from Language.Haskell.Syntax to GHC.Hs. Reason, when instantiated at (GhcPass _), the extension data construtcor is guaranteed unused, and that justifies omitted patterns in these functions. By putting them in GHC.Hs.X I can specialise the type for (GhcPass _) and thereby make the function total. An interesting side-light is that there were a few local function definitions without a type signature, like this one in GHC.Parser.Header convImport (L _ i) = (ideclPkgQual i, reLoc $ ideclName i) This is fully closed, and so is generalised; but that generalises it to any old pass, not (GhcPass _), so GHC rightly complains about the use of the selector `ideclPkgQual`. I added a type signature to `i`, thus convImport (L _ (i::ImportDecl GhcPs)) = (ideclPkgQual i, reLoc $ ideclName i) which specialised the function enough to make the record selector complete. Quite a surprising consequence of local let-generalisation! - - - - - 6a067226 by Simon Peyton Jones at 2024-10-14T22:15:31-04:00 Add -Werror=-Wno-error=incomplete-record-selectors to hadrian-multi In the main MR, -Wall now includes -Wincomplete-record-selectors. However `hadrian-multi` has many, many warnings about incomplete record selectors, so this patch stops those warnings being treated as errors. (See discussion on !13308.) A better fix would be to remove the use of incomplete record selectors, since each of them represents a potential crash. - - - - - edeafc14 by Ben Gamari at 2024-10-14T22:16:08-04:00 users-guide: Document field coalescence - - - - - 55b83587 by ARATA Mizuki at 2024-10-14T22:16:49-04:00 LLVM backend: Use correct rounding for Float literals Fixes #22033 - - - - - e59fe5c6 by Hassan Al-Awwadi at 2024-10-15T08:25:33+00:00 Changed import from Ghc. module to L.H.S module Progresses #21592 For some reason we still imported GHC.Types.Fixity when the definitino of Fixity and LexicalFixity have already been moved to Language.Haskell.Syntax.Basic. This fixes that for - - - - - ab1767d5 by Simon Peyton Jones at 2024-10-15T23:45:04-04:00 Add a release-notes entry for -Wincomplete-record-selectors - - - - - 6f0a62db by ur4t at 2024-10-16T15:33:43+00:00 GHCi: fix improper location of ghci_history file Fixes #24266 - - - - - 5f67db48 by Alan Zimmerman at 2024-10-17T05:18:43-04:00 EPA: Remove [AddEpAnn] commit 3 EPA: Remove [AddEpAnn] from HsDocTy EPA: Remove [AddEpAnn] from HsBangTy EPA: Remove [AddEpAnn] from HsExplicitListTy EPA: Remove [AddEpAnn] from HsExplicitTupleTy EPA: Remove [AddEpAnn] from HsTypedBracket EPA: Remove [AddEpAnn] from HsUntypedBracket EPA: Remove [AddEpAnn] from PatBuilderOpApp EPA: break out 'EpToken "|"' from ClassDecl anns EPA: Remove [AddEpAnn] from ClassDecl EPA: Remove [AddEpAnn] from SynDecl - - - - - fbbbd010 by Daan Rijks at 2024-10-17T05:19:19-04:00 Expand the haddocks for Control.Category - - - - - 076c1a10 by Andrew Lelechenko at 2024-10-17T05:19:19-04:00 documentation: more examples for Control.Category - - - - - 90891962 by Cheng Shao at 2024-10-17T16:41:18+00:00 ghci: mitigate host/target word size mismatch in BCOByteArray serialization This patch mitigates a severe host/target word size mismatch issue in BCOByteArray serialization logic introduced since !12142, see added note for detailed explanation. - - - - - 839ac52e by Cheng Shao at 2024-10-17T16:41:18+00:00 ghci: use plain malloc for mkConInfoTable on non-TNTC platforms This patch avoids using mmap() to allocate executable memory for mkConInfoTable on platforms without tables-next-to-code, see added comment for explanation. - - - - - a998f69d by Cheng Shao at 2024-10-17T16:41:18+00:00 ghc-internal: add missing CPPs for wasm This patch adds some missing CPP guards to ghc-internal, given those functions are non existent on wasm and would cause linking issues. - - - - - 71a471e7 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: rename prelude.js to prelude.mjs This commit renames prelude.js to prelude.mjs for wasm backend rts jsbits, and slightly adjusts the jsbits contents. This is for preparing the implementation of dyld.mjs that contains wasm dynamic linker logic, which needs to import prelude.mjs as a proper ESM module. - - - - - 33d9db17 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: add __wrapped_freeJSVal This commit wraps imported freeJSVal in a __wrapped_freeJSVal C function for wasm backend RTS. In general, wasm imports are only supposed to be directly called by C; they shouldn't be used as function pointers, which confuses wasm-ld at link-time when generating shared libraries. - - - - - 0d0a16a8 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: correct stale link in comment - - - - - 90a35c41 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: drop interpretBCO support from non-dyn ways on wasm This commit drops interpretBCO support from non dynamic rts ways on wasm. The bytecode interpreter is only useful when the RTS linker also works, and on wasm it only works for dynamic ways anyway. An additional benefit of dropping interpretBCO is reduction in code size of linked wasm modules, especially since interpretBCO references ffi_call which is an auto-generated large function in libffi-wasm and unused by most user applications. - - - - - 98a32ec5 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: don't build predefined GloblRegs for wasm PIC mode This commit wraps the predefined GlobalRegs in Wasm.S under a CPP guard to prevent building for PIC mode. When building dynamic ways of RTS, the wasm globals that represent STG GlobalRegs will be created and supplied by dyld.mjs. The current wasm dylink convention doesn't properly support exporting relocatable wasm globals at all, any wasm global exported by a .so is assumed to be a GOT.mem entry. - - - - - bef94bde by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: fix conflicting StgRun definitions on wasm This commit fixes conflicting StgRun definition when building dynamic ways of RTS for wasm in unregisterised mode. - - - - - a6a82cdb by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: use targetSupportsRPaths predicate This commit changes the hostSupportsRPaths predicate to targetSupportsRPaths and use that to decide whether to pass RPATH-related link-time options. It's not applied to stage0, we should just use the default link-time options of stageBoot ghc. - - - - - f232c872 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: disable internal-interpreter of ghc library when cross compiling This commit disable the internal-interpreter flag of ghc library when cross compiling, only external interpreter works in such cases. - - - - - 577c1819 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: enable internal-interpreter for ghc-bin stage0 This commit enables internal-interpreter flag for ghc-bin even when compiling stage0, as long as target supports ghci. It enables ghci functionality for cross targets that support ghci, since cross ghc-bin is really stage0. - - - - - c247f2ee by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: fix CFLAGS for gmp shared objs on wasm This commit adds -fvisibility=default to CFLAGS of gmp when building for wasm. This is required to generate the ghc-bignum shared library without linking errors. Clang defaults to -fvisibility=hidden for wasm targets, which will cause issues when a symbol is expected to be exported in a shared library but without explicit visibility attribute annotation. - - - - - 775410fd by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: re-enable PIC for gmp on wasm This commit re-enables --with-pic=yes configuration option of gmp when building for wasm, given we're about to include support for shared libraries, TH and ghci. - - - - - b45080a3 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: add the host_fully_static flavour transformer This commit adds the host_fully_static flavour transformer to hadrian, which ensures stage0 is fully statically linked while still permitting stage1 libdir to contain shared libraries. This is intended to be used by the wasm backend to build portable linux bindists that contain wasm shared libraries. - - - - - 5043507c by Cheng Shao at 2024-10-17T16:41:18+00:00 ci: update wasm jobs configuration This commit bumps ci-image revision to use updated wasm toolchain, and use host_fully_static instead of fully_static for wasm jobs so to ensure wasm shared libraries can be properly built. - - - - - 2956a3f7 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian/testsuite: implement config.cross logic This commit implements the config.cross field in the testsuite driver. It comes from the "cross compiling" ghc info field for both in-tree/out-of-tree GHC, and is an accurate predicate of whether we're cross-compiling or not (compared to the precense of target emulator), and is useful to implement predicates to assert the precense of internal interpreter (only available on non-cross GHC) for tests that do require it (e.g. plugins). - - - - - 8c74a0ed by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian/compiler: implement targetRTSLinkerOnlySupportsSharedLibs This patch implements the targetRTSLinkerOnlySupportsSharedLibs predicate in hadrian. Its definition in hadrian is the single source of truth, and the information propagates to ghc settings file, ghc driver and testsuite driver. It is used in various places to ensure dynamic dependency is selected when the target RTS linker only supports loading dynamic code. - - - - - b4c3c340 by Cheng Shao at 2024-10-17T16:41:18+00:00 testsuite: don't use host cpu features when testing cross ghc This patch disables CPU feature detection logic when testing cross GHC, since those features don't make sense for the target anyway. - - - - - 3c21b696 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: implement & use req_plugins predicate This commit implements req_plugins predicate to indicate that the test requires plugin functionality. Currently this means cross GHC is disabled since internal-interpreter doesn't work in cross GHC yet. - - - - - 93b8af80 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: make use of config.interp_force_dyn This commit takes config.interp_force_dyn into consideration when setting up TH/ghci way flags. - - - - - 94673d41 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: bump T17572 timeout - - - - - 2b5efc2d by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: bump T22744 pre_cmd timeout - - - - - 45102e2a by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip terminfo_so for cross ghc - - - - - 05e40406 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: fix shared library size tests for cross ghc This commit fixes shared library size tests (e.g. array_so in testsuite/tests/perf/size/all.T) when testing cross ghc. Previously, if shared library file extension of host and target differs, those tests will fail with framework errors due to not finding the right files. - - - - - fa68f833 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip ghc api tests that attempt to spawn processes inside wasm This commit skips a few ghc api tests on wasm, since they would attempt to spawn processes inside wasm, which is not supported at all. - - - - - 1241c04e by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip T22840 due to broken -dtag-inference-checks on wasm - - - - - 78c8b900 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: ensure $(ghciWayFlags) can be overridden This commit revises boilerplate.mk in testsuite as well as a few other places, to ensure the tests that do make use of $(ghciWayFlags) can receive the right $(ghciWayFlags) from testsuite driver config. - - - - - 47989ecc by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: skip rdynamic on wasm - - - - - fefb4ea1 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: skip T2615 on wasm This commit marks T2615 as skip on wasm, given LD_* environment variables aren't supported on wasm anyway. - - - - - 77c79762 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: mark MultiLayerModulesTH_Make/MultiLayerModulesTH_OneShot as fragile on wasm - - - - - 69bb4745 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: fix T16180 on wasm This commit fixes T16180 on wasm once TH support is flipped on. The fix is simply adding right asm code for wasm. - - - - - 621c753d by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: fix -fexternal-interpreter flag for JS backend Previously, -fexternal-interpreter is broken for JS backend, since GHC would attempt to launch a non-existent ghc-iserv* executable. This commit fixes it by adjusting pattern matching order in setTopSessionDynFlags. - - - - - 80aa8983 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: use interpreterDynamic predicate in preloadLib This commit use the interpreterDynamic predicate in preloadLib to decide if we should do dynLoadObjs instead of loadObj. Previously we used hostIsDynamic which was only written with non-cross internal interpreter in mind. The testsuite is also adjusted to remove hard-wired -fPIC flag for cbits (doesn't work in i386 RTS linker in vanilla way, #25260) and properly pass ghc_th_way_flags to ghc. - - - - - 74411461 by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix Cmm dynamic CLabels for wasm This commit fixes the handling of dynamic CLabels for the wasm backend. Just do the simplest handling: preserve the original CLabel, both unreg/NCG backends can handle them properly without issue. - - - - - f6abaf13 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: add necessary compile-time flags for wasm PIC mode This commit adds necessary compile-time flags when compiling for wasm PIC mode, see added comment for detailed explanation. - - - - - 9745fcfb by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: add necessary link-time flags for wasm shared libs This commit adds necessary link-time flags for wasm shared libs, see added comments for detailed explanation. - - - - - 649aae00 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: enforce -fno-use-rpaths for wasm This commit ensures the GHC driver never passes any RPATH-related link-time flags on wasm, which is not supported at all. - - - - - 47baa904 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: ensure static archives are picked when linking static .wasm modules This commit ensures static archives are picked when linking .wasm modules which are supposed to be fully static, even when ghc may be invoked with -dynamic, see added comment for explanation. - - - - - fc3a5591 by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix dynamic_too_enable for targets that require dynamic libraries This commit fixes dynamic_too_enable for targets whose RTS linker can only load dynamic code. - - - - - 94ef949e by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix checkNonStdWay for targets that require dynamic libraries This commit fixes checkNonStdWay to ensure that for targets whose RTS linker can only load dynamic code, the dynamic way of object is selected. - - - - - 88e99248 by Cheng Shao at 2024-10-17T16:41:24+00:00 ghc-bin: enforce dynamic way when the target requires so This commit makes ghc-bin use dynamic way when it is doing interactive stuff on certain targets whose RTS linker can only handle dynamic code. - - - - - 549582ef by Cheng Shao at 2024-10-17T16:41:24+00:00 hadrian/ghci: add wasm dyld This commit adds the wasm dynamic linker implementation, as well as ghci logic to call it and hadrian logic to install it to the correct location. See the top-level note in utils/jsffi/dyld.mjs for more details. - - - - - b562e3a6 by Cheng Shao at 2024-10-17T16:41:29+00:00 driver: fix getGccSearchDirectory for wasm target This commit fixes getGccSearchDirectory logic for wasm target, ensures the correct search directory containing libc.so etc can be found by GHC. getGccSearchDirectory is also exported so it can be used elsewhere to obtain the wasi-sdk libdir and pass to the dyld script. - - - - - 2d6107dc by Cheng Shao at 2024-10-17T16:41:29+00:00 driver: add wasm backend iserv logic This commit adds wasm backend iserv logic to the driver, see added comments for explanation. - - - - - 61f5baa5 by Cheng Shao at 2024-10-17T16:41:29+00:00 compiler: add PIC support to wasm backend NCG This commit adds support for generating PIC to the wasm backend NCG. - - - - - 652e7239 by Cheng Shao at 2024-10-17T16:41:29+00:00 hadrian/compiler: flip on support for shared libs & ghci for wasm This commit flips on the support for shared libs and ghci for the wasm target, given all required support logic has been added in previous commits. - - - - - 74a1f681 by Cheng Shao at 2024-10-17T16:41:29+00:00 testsuite: flip on support for shared libs, TH & ghci for wasm This commit flips on support for shared libs, TH & ghci for wasm in the testsuite, given support has been landed in previous commits. - - - - - 525d451e by Cheng Shao at 2024-10-17T23:03:34-04:00 Revert "compiler: start deprecating cmmToRawCmmHook" This reverts commit 1c064ef1f3e1aa2afc996e962ad53effa99ec5f4. Turns out the GHC-WPC project does use it to observe Cmm in the pipeline, see #25363. - - - - - 5bcfefd5 by Cheng Shao at 2024-10-17T23:04:09-04:00 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. - - - - - eb67875f by Matthew Craven at 2024-10-18T12:18:35+00:00 Bump transformers submodule The svg image files mentioned in transformers.cabal were previously not checked in, which broke sdist generation. - - - - - 366a1109 by Matthew Craven at 2024-10-18T12:18:35+00:00 Remove reference to non-existent file in haddock.cabal - - - - - 826852e9 by Matthew Craven at 2024-10-18T12:18:35+00:00 Move tests T11462 and T11525 into tests/tcplugins - - - - - dbe27152 by Matthew Craven at 2024-10-18T12:18:35+00:00 Repair the 'build-cabal' hadrian target Fixes #23117. Fixes #23281. Fixes #23490. This required: * Updating the bit-rotted compiler/Setup.hs and its setup-depends * Listing a few recently-added libraries and utilities in cabal.project-reinstall * Setting allow-boot-library-installs to 'True' since Cabal now considers the 'ghc' package itself a boot library for the purposes of this flag Additionally, the allow-newer block in cabal.project-reinstall was removed. This block was probably added because when the libraries/Cabal submodule is too new relative to the cabal-install executable, solving the setup-depends for any package with a custom setup requires building an old Cabal (from Hackage) against the in-tree version of base, and this can fail un-necessarily due to tight version bounds on base. However, the blind allow-newer can also cause the solver to go berserk and choose a stupid build plan that has no business succeeding, and the failures when this happens are dreadfully confusing. (See #23281 and #24363.) Why does setup-depends solving insist on an old version of Cabal? See: https://github.com/haskell/cabal/blob/0a0b33983b0f022b9697f7df3a69358ee9061a89/cabal-install/src/Distribution/Client/ProjectPlanning.hs#L1393-L1410 The right solution here is probably to use the in-tree cabal-install from libraries/Cabal/cabal-install with the build-cabal target rather than whatever the environment happens to provide. But this is left for future work. - - - - - b3c00c62 by Matthew Craven at 2024-10-18T12:18:35+00:00 Revert "CI: Disable the test-cabal-reinstall job" This reverts commit 38c3afb64d3ffc42f12163c6f0f0d5c414aa8255. - - - - - a04959b8 by Daneel Yaitskov at 2024-10-19T09:34:15-04:00 base: speed up traceEventIO and friends when eventlogging is turned off #17949 Check the RTS flag before doing any work with the given lazy string. Fix #17949 Co-authored-by: Michael Peyton Jones <me at michaelpj.com> Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - eff16c22 by Matthew Pickering at 2024-10-19T21:55:55-04:00 ci: Add support for ONLY_JOBS variable to trigger any validation pipeline By setting the ONLY_JOBS variable to the name of the job (or multiple jobs), the resulting pipeline will include a validation job for that pipeline. For example - if you set ONLY_JOBS="x86_64-linux-ubuntu22_04-validate" then a ubuntu22_04 job will be included in the validation pipeline. This is useful for testing specific jobs. Fixes #25332 - - - - - 280b6278 by Zubin Duggal at 2024-10-19T21:56:31-04:00 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit d83f5bd730a8aef37d8a38b3560590d9798f8e45) - - - - - 25edf849 by Alan Zimmerman at 2024-10-19T21:57:08-04:00 EPA: Remove [AddEpAnn] Commit 4 EPA: Remove [AddEpAnn] from DataDecl This is quite a big change. The most important part is moving the annotations into HsDataDefn, using a specific annotation data type. It has a knock-on to everything that uses HsDataDefn EPA: Remove [AddEpAnn] for FunDep EPA: Remove [AddEpann] from FamilyDecl EPA: Remove [AddEpAnn] From InjectivityAnn EPA: Remove [AddEpAnn] from DefaultDecl EPA: Remove [AddEpAnn] from RuleDecls EPA: Remove [AddEpAnn] from Warnings - - - - - d5f42045 by Luite Stegeman at 2024-10-20T16:34:47-04:00 Interpreter: Add locking for communication with external interpreter This adds locking to communication with the external interpreter to prevent concurrent tasks interfering with each other. This fixes Template Haskell with the external interpreter in parallel (-j) builds. Fixes #25083 - - - - - d6bfea76 by Matthew James Kraai at 2024-10-20T16:35:29-04:00 Use monospace font for "Either a b" in fmap docs The documentation for fmap shows "`Either a b`" in the default font instead of showing "Either a b" in a monospace font. - - - - - 4bc7f9c8 by Luite Stegeman at 2024-10-20T16:36:15-04:00 Parser: remove non-ASCII characters from Parser.y Non-ASCII characters in the source causes a problem with the default Haskell Language Server setup in VSCode. Two characters seems to have been left in by accident. Workaround for #25396 - - - - - 7f61ed4e by Alan Zimmerman at 2024-10-21T06:39:45-04:00 EPA: Remove [AddEpAnn] Commit 5 EPA: Remove [AddEpAnn] from AnnPragma EPA: Remove [AddEpAnn] From ForeignDecl EPA: Remove [AddEpAnn] from RoleAnnotDecl EPA: Remove [AddEpAnn] from StandaloneKindSig EPA: Remove [AddEpAnn] From HsDeriving EPA: Remove [AddEpAnn] from ConDeclField EPA: Remove [AddEpAnn] from ConDeclGADT EPA: Remove [AddEpAnn] from ConDeclH98 EPA: Remove [AddEpAnn] from ClsInstDecl - - - - - f8694fe7 by Cheng Shao at 2024-10-21T06:40:21-04:00 wasm: bump dyld v8 heap size limit This patch adds `--max-old-space-size=8192` to wasm dyld shebang arguments to bump V8 heap size limit. The default limit (`heap_size_limit` returned by `v8.getHeapStatistics()`) is dynamically determined and a bit too low under certain workloads, and V8 would waste too much CPU time to garbage collect old generation heap more aggressively. Bumping the limit to 8G doesn't imply dyld would really take that much memory at run-time, but it lessens V8 heap stress significantly. - - - - - d328d173 by Luite Stegeman at 2024-10-21T12:39:18+00:00 Add requestTickyCounterSamples to GHC.Internal.Profiling This allows the user to request ticky counters to be written to the eventlog at specific times. See #24645 - - - - - 71765b1d by Simon Peyton Jones at 2024-10-21T20:55:00-04:00 Move defaulting code into a new module GHC.Tc.Solver had reached 4,000 lines -- although quite a lot of them are comments. This MR * Adds the new module GHC.Tc.Solver.Default, which has all the complex, but well modularised, defaulting code * Moves a bit of code from GHC.Tc.Solver into the existing GHC.Tc.Solver.Solve. Notably solveWanteds and simplifyWantedsTcM, which are called from GHC.Tc.Solver.Default It's a pure refactor. No code changes. - - - - - a398227b by Simon Peyton Jones at 2024-10-21T20:55:00-04:00 Improve the generalisation code in Solver.simplifyInfer The code in `decideQuantification` has become quite complicated. This MR straightens it out, adds a new Note, and on the way fixes #25266. See especially Note [decideAndPromoteTyVars] which is is where all the action happens in this MR. - - - - - 148059fe by Andrzej Rybczak at 2024-10-21T20:55:40-04:00 Adjust catches to properly rethrow exceptions https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13302 implemented exception rethrowing proposal, but it didn't adjust `catches`. This fixes it. - - - - - 25121dbc by doyougnu at 2024-10-22T09:38:18-04:00 linker: add --optimistic-linking flag This patch adds: - the --optimistic-linking flag which binds unknown symbols in the runtime linker to 0xDEADBEEF instead of exiting with failure - The test T25240 which tests these flags using dead code in the FFI system. - closes #25240 This patch is part of the upstreaming haskell.nix patches project. - - - - - f19e076d by doyougnu at 2024-10-22T09:38:18-04:00 ghc-internal: hide linkerOptimistic in MiscFlags - - - - - edc02197 by Cheng Shao at 2024-10-22T09:38:54-04:00 hadrian: fix bindist executable wrapper logic for cross targets This commit fixes an oversight of hadrian wrapper generation logic: when doing cross compilation, `wrapper` is called on executable names with cross prefix, therefore we must use `isSuffixOf` when matching to take the cross prefix into account. Also add missing cross prefix to ghci wrapper content and fix hsc2hs wrapper logic. - - - - - edf3bdf5 by Andreas Klebinger at 2024-10-22T16:30:42-04:00 mkTick: Push ticks through unsafeCoerce#. unsafeCoerce# doesn't exist at runtime so we should treat it like a Cast for the purpose of mkTick. This means if we have `{-# SCC foo #-} (unsafeCoerce# trivial_expr))` we now push the scope part of the cost centre up to `trivial_expr` at which point we can discard it completely if the expression is trivial enough. This fixes #25212. - - - - - 1bdb1317 by Cheng Shao at 2024-10-22T16:31:17-04:00 hadrian: enable late-CCS for perf flavour as well This patch enables late-CCS for perf flavour so that the testsuite can pass for perf as well. Fixes #25308. - - - - - fde12aba by Cheng Shao at 2024-10-22T16:31:54-04:00 hadrian: make sure ghc-bin internal-interpreter is disabled for stage0 when not cross compiling This patch disables internal-interpreter flag for stage0 ghc-bin when not cross compiling, see added comment for explanation. Fixes #25406. - - - - - 6ab8d751 by ignatiusm at 2024-10-24T01:23:35-04:00 Improve heap overflow exception message (#25198) Catch heap overflow exceptions and suggest using `+RTS -M<size>`. Fix #25198 - - - - - b3f7fb80 by Rodrigo Mesquita at 2024-10-24T01:24:12-04:00 determinism: Interface re-export list det In 'DocStructureItem' we want to make sure the 'Avails' are sorted, for interface file determinism. This commit introduces 'DetOrdAvails', a newtype that should only be constructed by sorting Avails with 'sortAvails' unless the avails are known to be deterministically ordered. This newtype is used by 'DocStructureItem' where 'Avails' was previously used to ensure the list of avails is deterministically sorted by construction. Note: Even though we order the constructors and avails in the interface file, the order of constructors in the haddock output is still determined from the order of declaration in the source. This was also true before, when the list of constructors in the interface file <docs> section was non-deterministic. Some haddock tests such as "ConstructorArgs" observe this (check the order of constructors in out/ConstructorArgs.html vs src/ConstructorArgs.hs vs its interface file) The updated tests are caused by haddock corners where the order in the source is not preserved (and was non-deterministic before this PR): * Module header in the latex backend * Re-export of pattern synonyms associated to a datatype (#25342) Fixes #25304 - - - - - e39c8c99 by Rodrigo Mesquita at 2024-10-24T01:24:12-04:00 Revert "ci: Allow abi-test to fail." After #25304, the abi-test with interface and object determinism succeeds. This reverts commit 7b37afc9f3e79559055488998ee73187886a0e00. - - - - - 7b1b0c6d by Alan Zimmerman at 2024-10-24T13:07:02-04:00 EPA: reduce [AddEpann] in AnnList Remove it from the `al_rest` field, and make `AnnList` parameterized on a type to be used in `al_rest`, for the various use cases. - - - - - 4a00731e by Rodrigo Mesquita at 2024-10-24T13:07:38-04:00 Fix -fobject-determinism flag definition The flag should be defined as an fflag to make sure the -fno-object-determinism flag is also an available option. Fixes #25397 - - - - - 55e4b9f2 by Sebastian Graf at 2024-10-25T07:01:54-04:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - 9f57c96d by Sebastian Graf at 2024-10-25T07:01:54-04:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * I reworked the whole narrative around "Tag inference". It's now called "EPT enforcement" and I recycyled the different overview Notes into `Note [EPT enforcement]`. * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Compiler perf generally improves, sometimes drastically: Baseline Test Metric value New value Change -------------------------------------------------------------------------------- ManyConstructors(normal) ghc/alloc 3,629,760,116 3,711,852,800 +2.3% BAD MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,502,735,440 2,565,282,888 +2.5% BAD T12707(normal) ghc/alloc 804,399,798 791,807,320 -1.6% GOOD T17516(normal) ghc/alloc 964,987,744 1,008,383,520 +4.5% T18140(normal) ghc/alloc 75,381,152 49,860,560 -33.9% GOOD T18698b(normal) ghc/alloc 232,614,457 184,262,736 -20.8% GOOD T18923(normal) ghc/alloc 62,002,368 58,301,408 -6.0% GOOD T20049(normal) ghc/alloc 75,719,168 70,494,368 -6.9% GOOD T3294(normal) ghc/alloc 1,237,925,833 1,157,638,992 -6.5% GOOD T9233(normal) ghc/alloc 686,490,105 635,166,688 -7.5% GOOD geo. mean -0.7% minimum -33.9% maximum +4.5% I looked at T17516. It seems we do a few more simplifier iterations and end up with a larger program. It seems that some things inline more, while other things inline less. I don't see low-hanging fruit. I also looked at MultiLayerModulesTH_OneShot. It appears we generate a strange join point in the `getUnique` method of `Uniquable GHC.Unit.Types.Module` that should better call-site inline, but does not. Perhaps with !11492. NoFib does not seem affected much either: +-------------------------------++--+------------+-----------+---------------+-----------+ | || | base/ | std. err. | T20749/ (rel) | std. err. | +===============================++==+============+===========+===============+===========+ | spectral/last-piece || | 7.263e8 | 0.0% | +0.62% | 0.0% | +===============================++==+============+===========+===============+===========+ | geom mean || | +0.00% | | | | +-------------------------------++--+------------+-----------+---------------+-----------+ I had a look at last-piece. Nothing changes in stg-final, but there is a bit of ... movement around Data.Map.insert's use of GHC.Exts.lazy that is gone in stg-final. Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> Metric Decrease: T12707 T18140 T18698b T18923 T19695 T20049 T3294 T9233 T21839c Metric Increase: ManyConstructors MultiLayerModulesTH_OneShot - - - - - 0225249a by Simon Peyton Jones at 2024-10-25T07:02:32-04:00 Some renaming This is a pure refactor, tidying up some inconsistent naming: isEqPred --> isEqClassPred isEqPrimPred --> isEqPred isReprEqPrimPred --> isReprEqPred mkPrimEqPred --> mkNomEqPred mkReprPrimEqPred --> mkReprEqPred mkPrimEqPredRold --> mkEqPredRole Plus I moved mkNomEqPred, mkReprEqPred, mkEqPredRolek from GHC.Core.Coercion to GHC.Core.Predicate where they belong. That means that Coercion imports Predicate rather than vice versa -- better. - - - - - 15a3456b by Ryan Hendrickson at 2024-10-25T07:02:32-04:00 compiler: Fix deriving with method constraints See Note [Inferred contexts from method constraints] Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - dbc77ce8 by Alan Zimmerman at 2024-10-25T18:20:13+01:00 EPA: Remove AddEpann commit 7 EPA: Remove [AddEpAnn] from HYPHEN in Parser.y The return value is never used, as it is part of the backpack configuration parsing. EPA: Remove last [AddEpAnn] usages Remove residual usage in GHC. It is still used - In haddock TTG extension point definitions (to be removed) - Some check-exact residual, to be removed - Comments around DisambECP in PostProcess EPA: Clean up [AddEpAnn] from check-exact There is one left, to be cleaned up when we remove AddEpann itself EPA: Remove [AddEpAnn] from haddock The TTG extension points need a value, it is not critical what that value is, in most cases. EPA: Remove AddEpAnn from HsRuleAnn EPA: Remove AddEpAnn from HsCmdArrApp - - - - - 23ddcc01 by Simon Peyton Jones at 2024-10-26T12:44:34-04:00 Fix optimisation of InstCo It turned out (#25387) that the fix to #15725 was not quite right: commit 48efbc04bd45d806c52376641e1a7ed7278d1ec7 Date: Mon Oct 15 10:25:02 2018 +0200 Fix #15725 with an extra Sym Optimising InstCo is quite subtle, and the invariants surrounding the LiftingContext in the coercion optimiser were not stated explicitly. This patch refactors the InstCo optimisation, and documents these invariants. See * Note [Optimising InstCo] * Note [The LiftingContext in optCoercion] I also did some refactoring of course: * Instead of a Bool swap-flag, I am not using GHC.Types.Basic.SwapFlag * I added some invariant-checking the coercion-construction functions in GHC.Core.Coercion.Opt. (Sadly these invariants don't hold during typechecking, becuase the types are un-zonked, so I can't put these checks in GHC.Core.Coercion.) - - - - - 589fea7f by Cheng Shao at 2024-10-27T05:36:38-04:00 ghcid: use multi repl for ghcid - - - - - d52a0475 by Andrew Lelechenko at 2024-10-27T05:37:13-04:00 documentation: add motivating section to Control.Monad.Fix - - - - - 301c3b54 by Cheng Shao at 2024-10-27T05:37:49-04:00 wasm: fix safari console error message related to import("node:timers") This patch fixes the wasm backend JSFFI prelude script to avoid calling `import("node:timers")` on non-deno hosts. Safari doesn't like it and would print an error message to the console. Fixes https://gitlab.haskell.org/ghc/ghc-wasm-meta/-/issues/13. - - - - - 9f02dfb5 by Simon Peyton Jones at 2024-10-27T15:10:08-04:00 Add a missing tidy in UnivCo We were failing to tidy the argument coercions of a UnivCo, which led directly to #25391. The fix is, happily, trivial. I don't have a small repro case (it came up when building horde-ad, which uses typechecker plugins). It should be possible to make a repro case, by using a plugin (which builds a UnivCo) but I decided it was not worth the bother. The bug is egregious and easily fixed. - - - - - 853050c3 by Andrew Lelechenko at 2024-10-27T15:10:44-04:00 Bump text submodule to 2.1.2 - - - - - 90746a59 by Andrew Lelechenko at 2024-10-27T15:10:44-04:00 hadrian: allow -Wunused-imports for text package - - - - - 8a6691c3 by Alan Zimmerman at 2024-10-27T19:44:48+00:00 EPA: Remove AddEpAnn Commit 8/final EPA: Remove AddEpAnn from AnnList EPA: Remove AddEpAnn from GrhsAnn This is the last actual use EPA: Remove NameAdornment from NameAnn Also rework AnnContext to use EpToken, and AnnParen EPA: Remove AddEpAnn. Final removal There are now none left, except for in a large note/comment in PostProcess, describing the historical transition to the disambiguation infrastructure - - - - - d5e7990c by Alan Zimmerman at 2024-10-28T21:41:05+00:00 EPA: Remove AnnKeywordId. This was used as part of AddEpAnn, and is no longer needed. Also remove all the haddock comments about which of are attached to the various parts of the AST. This is now clearly captured in the appropriate TTG extension points, and the `ExactPrint.hs` file. - - - - - e08b8370 by Serge S. Gulin at 2024-10-29T23:17:01-04:00 JS: Re-add optimization for literal strings in genApp (fixes #23479) Based on https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10588/ Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> Co-authored-by: Danil Berestov <goosedb at yandex.ru> ------------------------- Metric Decrease: T25046_perf_size_gzip size_hello_artifact size_hello_artifact_gzip size_hello_unicode size_hello_unicode_gzip ------------------------- - - - - - e3496ef6 by Cheng Shao at 2024-10-29T23:17:37-04:00 compiler: remove unused hscDecls/hscDeclsWithLocation This patch removes unused `hscDecls`/`hscDeclsWithLocation` functions from the compiler, to reduce maintenance burden when doing refactorings related to ghci. - - - - - b1eed26f by Cheng Shao at 2024-10-29T23:18:13-04:00 testsuite: add T25414 test case marked as broken This commit adds T25414 test case to demonstrate #25414. It is marked as broken and will be fixed by the next commit. - - - - - e70009bc by Cheng Shao at 2024-10-29T23:18:13-04:00 driver: fix foreign stub handling logic in hscParsedDecls This patch fixes foreign stub handling logic in `hscParsedDecls`. Previously foreign stubs were simply ignored here, so any feature that involve foreign stubs would not work in ghci (e.g. CApiFFI). The patch reuses `generateByteCode` logic and eliminates a large chunk of duplicate logic that implements Core to bytecode generation pipeline here. Fixes #25414. - - - - - 1d7cd7fe by Andreas Klebinger at 2024-10-30T19:14:28-04:00 Add since tag for -fwrite-if-compression in user guide. Partial fix for #25395 - - - - - b349fd1b by Alan Zimmerman at 2024-10-30T19:15:04-04:00 EPA: Remove some unused functions - - - - - f859d61c by Alan Zimmerman at 2024-10-30T19:15:04-04:00 EPA: use explicit vertical bar token for ExplicitSum / SumPat - - - - - 721ac00d by Ben Gamari at 2024-10-31T08:37:38-04:00 rts/Disassembler: Fix encoding of BRK_FUN instruction The offset of the CC field was not updated after the encoding change in b85b11994e0130ff2401dd4bbdf52330e0bcf776. Fix this. Fixes #25374. - - - - - 0bc94360 by Alan Zimmerman at 2024-10-31T08:38:15-04:00 EPA: Bring in last EpToken usages For import declarations, NameAnnCommas and NPlusKPat. And remove anchor, it is the same as epaLocationRealSrcSpan. - - - - - 0b11cdc0 by sheaf at 2024-10-31T08:38:55-04:00 Assert that ctEvCoercion is called on an equality Calling 'ctEvCoercion' on non-equality constraints is always incorrect. We add an assertion to this function to detect such cases; for example a type-checking plugin might erroneously do this. - - - - - ea458779 by doyougnu at 2024-11-01T18:11:33-04:00 ghc-internal: strict, unboxed src loc ranges - closes: #20449 - See CLC proposal: #55 - - - - - 778ac793 by Kazuki Okamoto at 2024-11-01T18:12:13-04:00 No haddock markup in doctest line - - - - - cf0deeaf by Andreas Klebinger at 2024-11-02T17:54:52-04:00 Reword -fexpose-overloaded-unfoldings docs. This should make them slightly clearer. Fixes #24844 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> - - - - - 1c21e7d4 by Andreas Klebinger at 2024-11-02T17:55:29-04:00 Compile T25062 simd tests even if we can't run them. Helps avoid them being utterly broken. Fixes #25341 - - - - - 573cad4b by Cheng Shao at 2024-11-02T17:56:04-04:00 Remove unused USE_REPORT_PRELUDE code paths from the tree This patch removes unused `USE_REPORT_PRELUDE` code paths from the tree. They have been present since the first git revision 4fb94ae5e5d632748fa2e6c35e259eccc5a1a3f4, and might have been useful for debugging purposes many years ago, but these code paths are never actually built. Removing these ease maintenance of relevant modules in the future, and also allows us to get rid of `CPP` extension in those modules as a nice byproduct. - - - - - 97f600c6 by Hassan Al-Awwadi at 2024-11-04T15:52:12+00:00 Refactored BooleanFormula to be in line with TTG (#21592) There are two parts to this commit. * We moved the definition of BooleanFormula over to L.H.S.BooleanFormula * We parameterized the BooleanFormula over the pass The GHC specific details of BooleanFormula remain in Ghc.Data.BooleanFormula. Because its parameterized over the pass its no longer a functor or traversable, but we defined bfMap and bfTraverse for the cases where we needed fmap and traverse originally. Most other changes are just churn. ------------------------- Metric Decrease: MultiLayerModulesTH_OneShot ------------------------- - - - - - d4fd3580 by Andreas Klebinger at 2024-11-05T07:36:16-05:00 ghc-heap: Fix incomplete selector warnings. Use utility functions instead of selectors to read partial attributes. Part of fixing #25380. - - - - - fdd9f62a by Peter Trommler at 2024-11-05T07:36:51-05:00 PPC NCG: Implement fmin and fmax - - - - - 8e217256 by Mike Pilgrem at 2024-11-07T04:34:20-05:00 Re CLC #293 - Don't specify Data.List.NonEmpty in terms of partial See https://github.com/haskell/core-libraries-committee/issues/293 `List.init` had already been driven out of `tails1` by 21fc180bec93d964a7f4ffdf2429ef6f74b49ab6 but this specification also avoided partial `fromList`, so I preferred it. The `changelog.md` for `base` is updated, with an entry added under `base-4.22.0.0`. - - - - - 346e4cd1 by Zubin Duggal at 2024-11-07T04:34:57-05:00 release: copy zip files into the correct directory Fixes #25446 - - - - - bbdbe225 by Zubin Duggal at 2024-11-07T04:34:57-05:00 release: Sign .gz bindists too Fixes #25447 - - - - - 0c722e14 by Hécate Kleidukos at 2024-11-07T04:35:37-05:00 hadrian: Enforce the usage of GHC >=9.8.1 for ghci-multi GHC 9.6 no good when it comes to multi-repl stuff, despite being well within the range of n-2 releases for bootstrapping, when the script was adapted to load haddock, in !12851 - - - - - d8f8a1c3 by Sylvain Henry at 2024-11-07T19:27:46-05:00 Handle the special ghc-prim:GHC.Prim module in the compiler Before this patch, some custom hacks were necessary in ghc-prim's Setup.hs to register the GHC.Prim (virtual) module and in Hadrian to generate haddocks properly. In this patch we special-case this module in the compiler itself instead (which it already is, see ghcPrimIface in GHC.Iface.Load). From Cabal/Hadrian's perspective GHC.Prim is now just a normal autogenerated module. This simplification is worthwhile on its own. It was found while looking into the work needed for #24453 which aims to merge ghc-prim, ghc-bignum, and ghc-internal. It's also one step closer to remove ghc-prim's custom setup. - - - - - a55adc8e by Cheng Shao at 2024-11-07T19:28:22-05:00 Clean up obsolete CPP guarded code paths from the tree This patch cleans up obsolete CPP guarded code paths from the tree. The minimum supported boot GHC version is 9.6, and all the pre-9.6 era code paths can be removed. - - - - - 9ede97f3 by Cheng Shao at 2024-11-07T19:28:58-05:00 Remove obsolete executable wrappers from the tree The executable wrappers are handled by hadrian and bindist Makefile. The various .wrapper scripts in the tree are unused since removal of Make build system, so this patch removes them all. - - - - - 7d42b2df by tristian at 2024-11-07T19:29:40-05:00 TcRnDuplicateDecls now suggests to use the DuplicateRecordFields extension. Fixes: !24627 - - - - - e56ed179 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: normalise some versions in callstacks (cherry picked from commit f230e29f30d0c1c566d4dd251807fcab76a2710e) - - - - - a28fc903 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: use -fhide-source-paths to normalise some backpack tests (cherry picked from commit b19de476bc5ce5c7792e8af1354b94a4286a1a13) - - - - - ed16d303 by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite/haddock: strip version identifiers and unit hashes from html tests (cherry picked from commit fbf0889eadc410d43dd5c1657e320634b6738fa5) - - - - - e45e5836 by Zubin Duggal at 2024-11-11T15:16:36+05:30 haddock: oneshot tests can drop files if they share modtimes. Stop this by including the filename in the key. Ideally we would use `ghc -M` output to do a proper toposort Partially addresses #25372 (cherry picked from commit e78c7ef96e395f1ef41f04790aebecd0409b92b9) - - - - - 9104e6eb by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: fix normalisation of T9930fail so that it doesn't get tripped up by ghc executable (ARGV[0]) differences (cherry picked from commit a79a587e025d42d34bb30e115fc5c7cab6c1e030) - - - - - 2c31264a by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: normalise windows file seperators (cherry picked from commit f858875e03b9609656b542aaaaff85ad0a83878a) - - - - - 2807f91b by Zubin Duggal at 2024-11-11T15:21:30+05:30 testsuite: Also match <VERSION> placeholders when normalising callsites - - - - - c02add17 by Ben Gamari at 2024-11-12T01:22:11-05:00 configure: Check version number validity Here we verify the previously informal invariant that stable release version numbers must have three components, preventing costly failed releases. Specifically, the check fails in the following scenarios: * `version=9.13` while `RELEASE=YES` since this would imply a release made from an unstable branch * `version=9.13.0` since unstable versions should only have two components * `version=9.12` since this has the wrong number of version components for a stable branch Fixes #25390. - - - - - 747fd322 by Teo Camarasu at 2024-11-12T01:22:49-05:00 docs: link to #14474 in the template-haskell docs - - - - - 6d96bb62 by Zubin Duggal at 2024-11-12T01:23:25-05:00 testsuite: normalise execvp vs exec differences in process tests Fixes #25431 - - - - - 502e6711 by Torsten Schmits at 2024-11-12T01:24:01-05:00 fix test lint that accumulated while the checks were broken I didn't fix the issues flagged by the #ifdef linter because it were so many that it seemed like the rule has become obsolete. - - - - - 223a4cb5 by Torsten Schmits at 2024-11-12T01:24:02-05:00 test driver: fix file collection for regex linters When a testsuite linter is executed with the `tracked` strategy, the driver runs `git ls-tree` to collect eligible files. This appears to have ceased producing any paths – `ls-tree` restricts its results to the current working directory, which is `testsuite/tests/linters` in this case. As a quick fix, this patch changes the working directory to match expectations. - - - - - 9ad9ac63 by Alan Zimmerman at 2024-11-12T01:24:39-05:00 EPA: Capture location of '_' for wild card type binder And keep track of promotion status in HsExplicitTupleTy, so the round-trip ppr test works for it. Updates Haddock output too, using the PromotionFlag in HsExplicitTupleTy. Closes #25454 - - - - - c37b96fa by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix setImmediate() implementation for Cloudflare Workers This patch fixes setImmediate() implementation for Cloudflare Workers in the wasm backend's js prelude script. Cloudflare Workers doesn't support the MessageChannel API, and we use a setTimeout() based fallback implementation in this case. - - - - - bea8ea4c by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix FinalizationRegistry logic for Cloudflare Workers This patch fixes FinalizationRegistry related logic for Cloudflare Workers in wasm backend js post linker. Cloudflare Workers doesn't support FinalizationRegistry, in this case we use a dummy implementation that doesn't do anything. - - - - - 00d551bf by Cheng Shao at 2024-11-13T08:48:21-05:00 Remove obsolete cross-port script This patch removes the obsolete cross-port script in the tree. The script was based on the legacy Make build system which has been pruned from the tree long ago. For hadrian, proper support for two-stage bootstrapping onto a new unsupported platform is a work in progress in !11444. - - - - - 75a2eae4 by Cheng Shao at 2024-11-13T08:48:58-05:00 hadrian: fix bindist makefile for wasm32-wasi target This patch fixes one incoherent place between bindist makefile and hadrian logic: I forgot to include wasi/wasm32 in OsSupportsGHCi/ArchSupportsGHCi as well. And this results in incorrect settings file generated after installing the bindist, and "Use interpreter"/"Have interpreter" fields incorrectly have "NO" values where they should be "YES" like --info output of in-tree version. - - - - - 0614abef by Alan Zimmerman at 2024-11-13T08:49:34-05:00 EPA: Correctly capture leading semis in decl list Closes #25467 - - - - - 00d58ae1 by Sebastian Graf at 2024-11-13T15:21:23-05:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. - - - - - 93233a66 by Ben Gamari at 2024-11-13T15:21:59-05:00 boot: Do not attempt to update config.sub While Apple ARM hardware was new we found that the autoconf scripts included in some boot packages were too old. As a mitigation for this, we introduced logic in the `boot` script to update the `config.sub` with that from the GHC tree. However, this causes submodules which have `config.sub` committted to appear to be dirty. This is a considerable headache. Now since `config.sub` with full platform support is more common we can remove `boot`'s `config.sub` logic. Fixes #19574. - - - - - fa66fa64 by Ryan Scott at 2024-11-14T19:05:00-05:00 Add regression test for #16234 Issue #16234 was likely fixed by !9765. This adds a regression test to ensure that it remains fixed. Fixes #16234. - - - - - bfe64df8 by Matthew Pickering at 2024-11-14T19:05:36-05:00 ghc-internal: Update to Unicode 16 This patch updates the automatically generated code for querying unicode properties to unicode 16. Fixes #25402 - - - - - 1fd83f86 by Ben Gamari at 2024-11-14T19:06:13-05:00 configure: Accept happy-2.1.2 happy-2.1 was released in late Oct 2024. I have confirmed that master bootstraps with it. Here we teach configure to accept this tool. Fixes #25438. - - - - - aa58fc5b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Tighten up invariants of PACK - - - - - 8aa4c10a by Ben Gamari at 2024-11-14T19:06:49-05:00 testsuite: Fix badly escaped literals Use raw string literals to ensure that `\s` is correctly interpreted as a character class. - - - - - 0e084029 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Improve documentation of SLIDE bytecode instruction - - - - - 9bf3663b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Assert that TEST*_P discriminators are valid - - - - - 1f668511 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Improve documentation of TEST*_P instructions - - - - - 59e0a770 by Cheng Shao at 2024-11-14T19:07:25-05:00 misc: improve clangd compile_flags.txt flags This patch improves the compile_flags.txt config used to power clangd for the rts C codebase. The flags in the file are sampled & deduped from a real stage1 build with clang-19 and vastly improves the IDE accuracy when hacking the rts. For maximum code coverage under the default settings, compile_flags.txt defaults to threaded+profiled+dynamic+debug way. This does not mean profdyn needs to be actually built in _build/stage1 for IDE to work. To activate IDE for other RTS ways, simply remove one of the -D flags at the end of compile_flags.txt and restart clangd. - - - - - c2c562e0 by Ben Gamari at 2024-11-14T19:08:01-05:00 testsuite: Don't consider untracked files in dirtiness check Considering trees containing untracked files as dirty is a bridge too far. The chance of an untracked file significantly affecting measured performanced metrics is quite small whereas not collecting measurements is quite inconvenient for some workflows. We now ignore untracked files in the dirtiness check. Fixes #25471. - - - - - ed2ed6c5 by Cheng Shao at 2024-11-14T19:08:37-05:00 testsuite: add regression test T25473 This commit adds regression test T25473 marked as broken due to #25473. It will be fixed in the subsequent commit. - - - - - bd0a8b7e by Cheng Shao at 2024-11-14T19:08:37-05:00 wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. - - - - - f1b0bc32 by Ben Gamari at 2024-11-14T19:09:13-05:00 rts/linker: Make FreeBSD declarations proper prototypes The iconv declarations for FreeBSD were previously not prototypes, leading to warnings. - - - - - 086cbbc1 by Ben Gamari at 2024-11-14T19:09:13-05:00 base: Drop redundant import in FreeBSD ExecutablePath implementation - - - - - 79ecd199 by Ben Gamari at 2024-11-14T19:09:13-05:00 compiler: Fix partial selector warnings in GHC.Runtime.Heap.Inspect - - - - - 1acb73bf by Andrew Lelechenko at 2024-11-15T06:10:47-05:00 gitlab: mention CLC in MR template - - - - - 8f2e0832 by Ben Gamari at 2024-11-15T06:11:24-05:00 rts: Allow use of GNU-stack notes on FreeBSD Previously we gated use of GNU-style non-executable stack notes to only apply on Linux. However, these are also supported by FreeBSD, which also uses ELF. Fix this. Fixes #25475. - - - - - 2c427cb0 by Ben Gamari at 2024-11-16T05:27:40-05:00 rts: Fix EINTR check in timerfd ticker When `poll` failed we previously checked that `errno == -EINTR` to silence the failure warning. However, this is wrong as `errno` values are generally not negated error codes (in contrast to many system call results, which is likely what the original author had in mind). Fixes #25477. - - - - - a0fa4941 by Ben Gamari at 2024-11-16T05:28:16-05:00 rts: Increase gen_workspace alignment to 128 bytes on AArch64 Increase to match the 128-byte cache-line size of Apple's ARMv8 implementation. Closes #25459. - - - - - 142d8afa by Ben Gamari at 2024-11-16T16:20:47-05:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - b7a146e5 by Ben Gamari at 2024-11-16T16:20:47-05:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - ddb7afa6 by Ben Gamari at 2024-11-16T16:21:23-05:00 users guide: Mention language extensions in equality constraints discussion As suggested in #24127, mention the language extensions necessary for usage of equality constriants in their documentation. Closes #24127. - - - - - 36133dac by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/9.14.1-notes: Fix list syntax - - - - - 888de658 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/debug-info: Fix duplicate flag descriptions - - - - - f120e427 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide: Fix reference to 9.14.1 release notes - - - - - 8e975032 by Ben Gamari at 2024-11-16T16:21:59-05:00 Introduce GHC.Tc.Plugin.lookupTHName This makes it significantly more convenient (and less GHC-version-dependent) to resolve a template-haskell name into a GHC Name. As proposed in #24741. - - - - - a0e168ec by ARATA Mizuki at 2024-11-16T16:22:40-05:00 x86 NCG SIMD: Lower packFloatX4#, insertFloatX4# and broadcastFloatX4# to SSE1 instructions Fixes #25441 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 3936bf1b by sheaf at 2024-11-16T16:23:22-05:00 X86 NCG: allow VXOR at scalar floating-point types The NCG can emit VXOR instructions at scalar floating-point types, but the pretty-printer would panic instead of emitting the appropriate VXORPS/VXORPD instructions. This patch rectifies that oversight. Fixes #25455 - - - - - d9dff93a by Ben Gamari at 2024-11-16T16:23:58-05:00 rts: Fix platform-dependent pointer casts Previously we had unnecessary (and incorrect) platform-dependent casts to turn `OSThreadIds`s into a integer. We now just uniformly cast first to a `uintptr_t` (which is always safe, regardless of whether `OSThreadId` is a pointer), and then cast to the desired integral type. This fixes a warning on musl platforms. - - - - - 6d95cdb8 by Ben Gamari at 2024-11-16T16:24:34-05:00 testsuite: Mark encoding004 as broken on FreeBSD Due to #22003, CP936 fails to roundtrip: ```diff == CP936 +Failed to roundtrip given mutant byte at index 891 (251 /= 123 at index 891) +Failed to roundtrip given mutant byte at index 1605 (197 /= 69 at index 1605) +Failed to roundtrip given mutant byte at index 2411 (235 /= 107 at index 2411) +Failed to roundtrip given mutant byte at index 6480 (208 /= 80 at index 6480) +Failed to roundtrip given mutant byte at index 6482 (210 /= 82 at index 6482) +Failed to roundtrip given mutant byte at index 6484 (212 /= 84 at index 6484) +Failed to roundtrip given mutant byte at index 6496 (224 /= 96 at index 6496) +Failed to roundtrip given mutant byte at index 7243 (203 /= 75 at index 7243) +Failed to roundtrip given mutant byte at index 7277 (237 /= 109 at index 7277) +Failed to roundtrip given mutant byte at index 8027 (219 /= 91 at index 8027) +Failed to roundtrip given mutant byte at index 8801 (225 /= 97 at index 8801) ``` - - - - - 26e86984 by Ben Gamari at 2024-11-18T04:05:31-05:00 hadrian: Allow haddock options to be passed via key-value settings - - - - - 6e68b117 by Matthew Pickering at 2024-11-18T04:06:07-05:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - a4e0d235 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 exceptions: Improve the message layout as per #285 This commit fixes the layout of the additional information included when displaying an exception, namely the type of the exception. It also fixes the default handler's heading message to work well together with the improved display message of SomeException. CLC proposal#285 - - - - - 284ffab3 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 Display type and callstack of exception on handler This commit changes the Exception instance of SomeException to *simply* display the underlying exception in `displayException`. The augmented exception message that included the type and backtrace of the exception are now only printed on a call to `displayExceptionWithInfo`. At a surface level, existing programs should behave the same since the `uncaughtExceptionHandler`, which is responsible for printing out uncaught exceptions to the user, will use `displayExceptionWithInfo` by default. However, unlike the instance's `displayException` method, the `uncaughtExceptionHandler` can be overriden with `setUncaughtExceptionHandler`. This makes the extra information opt-in without fixing it the instance, which can be valuable if your program wants to display uncaught exceptions to users in a user-facing way (ie without backtraces). This is what was originally agreed for CLC#231 or CLC#261 with regard to the type of the exception information. The call stack also becoming part of the default handler rather than the Exception instance is an ammendment to CLC#164. Discussion of the ammendment is part of CLC#285. - - - - - 36cddd2c by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Remove redundant CallStack from exceptions Before the exception backtraces proposal was implemented, ErrorCall accumulated its own callstack via HasCallStack constraints, but ExceptionContext is now accumulated automatically. The original ErrorCall mechanism is now redundant and we get a duplicate CallStack Updates Cabal submodule to fix their usage of ErrorCallWithLocation to ErrorCall CLC proposal#285 Fixes #25283 - - - - - 7a74330b by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Freeze call stack in error throwing functions CLC proposal#285 - - - - - 3abf31a4 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 De-duplicate displayContext and displayExceptionContext The former was unused except for one module where it was essentially re-defining displayExceptionContext. Moreover, this commit extends the fix from bfe600f5bb3ecd2c8fa71c536c63d3c46984e3f8 to displayExceptionContext too, which was missing. - - - - - c0d783f8 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Re-export NoBacktrace from Control.Exception This was originally proposed and accepted in section "2.7 Capturing Backtraces on Exceptions" of the CLC proposal for exception backtraces. However, the implementation missed this re-export, which this commit now fixes. - - - - - 802b5c3e by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Fix exception backtraces from GHCi When running the program with `runhaskell`/`runghc` the backtrace should match the backtrace one would get by compiling and running the program. But currently, an exception thrown in a program interpreted with `runhaskell` will: * Not include the original exception backtrace at all * Include the backtrace from the internal GHCi/ghc rethrowing of the original exception This commit fixes this divergence by not annotating the ghc(i) backtrace (with NoBacktrace) and making sure that the backtrace of the original exception is serialized across the boundary and rethrown with the appropriate context. Fixes #25116 The !13301 MR (not this commit in particular) improves performance of MultiLayerModules. Unfortunately, T3294 regresses on aarch64-linux-deb12 by 1% allocations. Since this patch must be merged for 9.12 ASAP, we will not be able to investigate the slight regression on this platform in time. ------------------------- Metric Decrease: MultiLayerModulesRecomp MultiLayerModulesTH_OneShot Metric Increase: T3294 ------------------------- - - - - - 3e89eb65 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 base: Add to changelog.md CLC #285 - - - - - d9326a48 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Bump array and stm submodules for testsuite The testsuites of array and stm had to be updated according to !13301. Updates submodule array and stm. - - - - - 325fcb5d by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Clean up code style of Nativei386 adjustor - - - - - 39bb6e58 by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Fix stack overrun error in Nativei386 adjustor We were reserving the wrong kind of adjustor context (the generic `AdjustorContext` used by other adjustor implementations, rather than the i386-specific `CCallContext`) to return the adjustor context while freeing, resulting in #25485. Fixes #25485. - - - - - 831aab22 by sheaf at 2024-11-18T21:22:36-05:00 Include diagnostic reason in -fdiagnostics-as-json This commit ensures that the -fdiagnostics-as-json output includes the diagnostic reason. This allows the full error message produced by GHC to be re-constructed from the JSON output. Fixes #25403 - - - - - 3e5bfdd3 by Ben Gamari at 2024-11-18T21:23:12-05:00 rts: Introduce printIPE This is a convenience utility for use in GDB. - - - - - 44d909a3 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Don't store boot locations in finder cache Partially reverts commit fff55592a7b Amends add(Home)ModuleToFinder so that locations for boot files are not stored in the finder cache. Removes InstalledModule field from InstalledFound constructor since it's the same as the key that was searched for. - - - - - 64c95292 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Concentrate boot extension logic in Finder With new mkHomeModLocation that takes an extra HscSource to add boot extensions if required. - - - - - 11bad98d by ARATA Mizuki at 2024-11-19T14:39:08-05:00 Better documentation for floating-point min/max and SIMD primitives See #25350 for floating-point min/max Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 791a47b2 by Arnaud Spiwack at 2024-11-20T14:00:05+00:00 Add test for #25185 - - - - - 374e18e5 by Arnaud Spiwack at 2024-11-20T14:09:30+00:00 Quick look: emit the multiplicity of app heads in tcValArgs Otherwise it's not scaled properly by the context, allowing unsound expressions. Fixes #25185. - - - - - 1fc02399 by sheaf at 2024-11-20T18:11:03-05:00 x86 NCG: fix regUsageOfInstr for VMOVU & friends This commit fixes the implementation of 'regUsageOfInstr' for vector operations that take an 'Operand' as the destination, by ensuring that when the destination is an address then the address should be *READ*, and not *WRITTEN*. Getting this wrong is a disaster, as it means the register allocator has incorrect information, which can lead to it discard stores to registers, segfaults ensuing. Fixes #25486 - - - - - 7bd407a6 by Brandon Chinn at 2024-11-21T14:08:15-05:00 Fix CRLF in multiline strings (#25375) - - - - - 7575709b by Rodrigo Mesquita at 2024-11-21T14:08:52-05:00 Improve reachability queries on ModuleGraph Introduces `ReachabilityIndex`, an index constructed from a `GHC.Data.Graph.Directed` `Graph` that supports fast reachability queries (in $O(1)$). This abstract data structure is exposed from `GHC.Data.Graph.Directed.Reachability`. This index is constructed from the module graph nodes and cached in `ModuleGraph`, enabling efficient reachability queries on the module graph. Previously, we'd construct a Map of Set of ModuleGraph nodes which used a lot of memory (`O(n^2)` in the number of nodes) and cache that in the `ModuleGraph`. By using the reachability index we get rid of this space leak in the module graph -- even though the index is still quadratic in the number of modules, it is much, much more space efficient due to its representation using an IntMap of IntSet as opposed to the transitive closure we previously cached. In a memory profile of MultiLayerModules with 100x100 modules, memory usage improved from 6GB residency to 2.8GB, out of which roughly 1.8GB are caused by a second space leak related to ModuleGraph. On the same program, it brings compile time from 7.5s to 5.5s. Note how we simplify `checkHomeUnitsClosed` in terms of `isReachableMany` and by avoiding constructing a second graph with the full transitive closure -- it suffices to answer the reachability query on the full graph without collapsing the transitive closure completely into nodes. Unfortunately, solving this leak means we have to do a little bit more work since we can no longer cache the result of turning vertex indices into nodes. This results in a slight regression in MultiLayerModulesTH_Make, but results in large performance and memory wins when compiling large amounts of modules. ------------------------- Metric Decrease: mhu-perf Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - bcbcdaaf by Cheng Shao at 2024-11-21T14:09:28-05:00 driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code This commit fixes an undefined symbol error in RTS linker when attempting to compile home modules with -fhpc and -fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for detailed description and analysis of the bug. Also adds T25510/T25510c regression tests to test make mode/oneshot mode of the bug. - - - - - 970ada5a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Bump ci-images For introduction of Alpine/i386 image. Thanks to Julian for the base image. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 8115abc2 by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Add release job for i386/Alpine As requested by Mikolaj and started by Julian. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 639f0149 by Ben Gamari at 2024-11-22T23:32:06-05:00 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ - - - - - 490d4d0a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Mark i386 Alpine test breakages Marks the following tests as broken on i386/Alpine: * T22033 due to #25497 * simd009, T25062_V16, T25169, T22187_run due to #25498 - - - - - 536cdf09 by Cheng Shao at 2024-11-22T23:32:42-05:00 compiler: remove unused GHC.Linker.Loader.loadExpr This patch removes the unused `GHC.Linker.Loader.loadExpr` function. It was moved from `GHC.Runtime.Linker.linkExpr` in `ghc-9.0` to `GHC.Linker.Loader.loadExpr` in `ghc-9.2`, and remain completely unused and untested ever since. There's also no third party user of this function to my best knowledge, so let's remove this. Anyone who wants to write their own GHC API function to load bytecode can consult the source code in older release branches. - - - - - 6ee35024 by Drew Fenwick at 2024-11-22T23:33:26-05:00 Fix a non-compiling example in the type abstractions docs This patch adds a missing Show constraint to a code example in the User Guide's type abstractions docs to fix issue #25422. - - - - - d1172e20 by Rodrigo Mesquita at 2024-11-22T23:34:02-05:00 Re-introduce ErrorCallWithLocation with a deprecation pragma With the removal of the duplicate backtrace, part of CLC proposal #285, the constructor `ErrorCallWithLocation` was removed from base. This commit re-introduces it with a deprecation. - - - - - 1187a60a by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Skip tests requiring Hadrian deps in out-of-tree testsuite runs Some testsuite tests require specific tools (e.g. `check-ppr` and `check-exact`) beyond those shipped in the binary distribution. Skip these tests. Fixes #13897. - - - - - c37d7a2e by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Declare exactprint tests' dependency on check-exact - - - - - 454ce957 by Ben Gamari at 2024-11-22T23:35:15-05:00 ghc-internal: Fix a few cases of missing Haddock markup - - - - - a249649b by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/GHCiPrimCall : Add missing Makefile includes - - - - - a021a493 by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/IpeStats: Use Make rather than shell interpolation - - - - - 6e1fbda7 by Ben Gamari at 2024-11-25T03:55:44-05:00 hadrian-ghci-multi: Pass -this-package-name in unit response files As noted in #25509, the `-this-package-name` must be passed for each package to ensure that GHC can response references to the packages' exposed modules via package-qualified imports. Fix this. Closes #25509. - - - - - a05e4a9b by Simon Hengel at 2024-11-25T03:56:33-05:00 Refactoring: Use `OnOff` more consistently for `Extension` - - - - - 7536181d by Matthew Pickering at 2024-11-25T14:00:07-05:00 driver: Always link against "base" package when one shot linking The default value for base-unit-id is stored in the settings file. At install time, this can be set by using the BASE_UNIT_ID environment variable. At runtime, the value can be set by `-base-unit-id` flag. For whether all this is a good idea, see #25382 Fixes #25382 - - - - - 7f90f319 by Andreas Klebinger at 2024-11-25T14:00:44-05:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 - - - - - 291388e1 by Cheng Shao at 2024-11-25T14:01:19-05:00 ci: minor nix-in-docker improvements This patch makes some minor improvements re nix-in-docker logic in the ci configuration: - Update `nixos/nix` to the latest version - Apply $CPUS to `cores`/`max-jobs` to avoid oversubscribing while allowing a reasonable degree of parallelism - Remove redundant `--extra-experimental-features nix-command` in later `nix shell` invocations, it's already configured in `/etc/nix/nix.conf` - - - - - e684c406 by Cheng Shao at 2024-11-25T14:01:57-05:00 ci: avoid depending on stack job for test-bootstrap jobs This patch makes test-bootstrap related ci jobs only depend on hadrian-ghc-in-ghci job to finish, consistent with other jobs in the full-build stage generated by gen_ci.hs. This allows the jobs to be spawned earlier and improve overall pipeline parallelism. - - - - - caaf5388 by Simon Hengel at 2024-11-25T14:02:41-05:00 Refactoring: Remove `pSupportedExts` from `ParserOpts` This is never used for lexing / parsing. It is only used by `GHC.Parser.Header.getOptions`. - - - - - 41f8365c by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Add test for #25515 - - - - - 9279619f by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Desugar record notation with correct multiplicities Simply uses the multiplicity as stored in the field. As I'm writing this commit, the only possible multiplicity is 1, but !13525 is changing this. It's actually easier to take !13525 into account. Fixes #25515. - - - - - fcc3ae6e by Andreas Klebinger at 2024-11-26T08:24:58-05:00 Clarify INLINE unfolding optimization docs. Fixes #24660 - - - - - 88c4fe1d by Cheng Shao at 2024-11-26T08:25:34-05:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. - - - - - 53f978c0 by doyougnu at 2024-11-26T16:07:26-05:00 ghc-experimental: expose GHC.RTS.Flags, GHC.Stats See this CLC proposal: - https://github.com/haskell/core-libraries-committee/issues/289 and this CLC proposal for background: - https://github.com/haskell/core-libraries-committee/issues/288 Metric Decrease: MultiLayerModulesTH_OneShot - - - - - e70d4140 by Wang Xin at 2024-11-26T16:08:10-05:00 Add -mcmodel=medium moduleflag to generated LLVM IR on LoongArch platform With the Medium code model, the jump range of the generated jump instruction is larger than that of the Small code model. It's a temporary fix of the problem descriped in https://gitlab.haskell .org/ghc/ghc/-/issues/25495. This commit requires that the LLVM used contains the code of commit 9dd1d451d9719aa91b3bdd59c0c6679 83e1baf05, i.e., version 8.0 and later. Actually we should not rely on LLVM, so the only way to solve this problem is to implement the LoongArch backend. Add new type for codemodel - - - - - df42ba16 by Andreas Klebinger at 2024-11-27T11:40:49-05:00 Cmm constant folding: Narrow results to operations bitwidth. When constant folding ensure the result is still within bounds for the given type by explicitly narrowing the results. Not doing so results in a lot of spurious assembler warnings especially when testing primops. - - - - - bf3db97e by Ben Gamari at 2024-11-27T11:41:26-05:00 ghc-toolchain: Introduce basic flag validation We verify that required flags (currently `--output` and `--triple`) are provided. The implementation is truly awful, but so is getopt. Begins to address #25500. - - - - - a104508d by Ben Gamari at 2024-11-27T11:42:03-05:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. - - - - - c3fc9b86 by Ben Gamari at 2024-11-27T11:42:39-05:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. - - - - - a362b943 by sheaf at 2024-11-27T23:44:28-05:00 Add checkExact to toolTargets This change means that the Hadrian multi target will include exactprint. In particular, this means that HLS will work on exactprint inside the GHC tree. - - - - - e6c957e4 by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Add test for #25428 - - - - - 52d97f4e by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Don't bypass MonoLocalBind in empty patterns Fixes #25428 - - - - - 7890f2d8 by Ben Gamari at 2024-11-28T10:26:46-05:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. - - - - - 0fd43ea6 by Adam Sandberg Ericsson at 2024-11-28T10:27:22-05:00 mention -Iw in +RTS -? - - - - - 6cf579b9 by Ben Gamari at 2024-11-28T10:27:59-05:00 gitlab-ci: Set GIT_SUBMODULE_FORCE_HTTPS GitLab recommends using `https://` to clone submodules and provides the `GIT_SUBMODULE_FORCE_HTTPS` variable to force this. Fixes #25528. - - - - - 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 795ece74 by Matthew Pickering at 2025-01-22T16:26:35+00:00 Explicit level imports 2024 - - - - - 6 changed files: - .ghcid - .gitattributes - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/hello.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eaf0f1b0c0ad240e011e44941bf2190c47a3b866...795ece744d00ccd33962c4abc2d1057c69d06c9f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eaf0f1b0c0ad240e011e44941bf2190c47a3b866...795ece744d00ccd33962c4abc2d1057c69d06c9f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 16:41:57 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 22 Jan 2025 11:41:57 -0500 Subject: [Git][ghc/ghc][wip/splice-imports-2024] Explicit level imports 2024 Message-ID: <67911fd56ddf8_9accde4e51c2037c@gitlab.mail> Matthew Pickering pushed to branch wip/splice-imports-2024 at Glasgow Haskell Compiler / GHC Commits: 18e4432d by Matthew Pickering at 2025-01-22T16:41:49+00:00 Explicit level imports 2024 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/Data/Graph/Directed.hs - compiler/GHC/Data/Graph/Directed/Reachability.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Header.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Expr.hs-boot - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/Head.hs - compiler/GHC/Tc/Module.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/18e4432d26691cfc99d5d9fc2a3147a814b38184 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/18e4432d26691cfc99d5d9fc2a3147a814b38184 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 16:43:51 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Wed, 22 Jan 2025 11:43:51 -0500 Subject: [Git][ghc/ghc][wip/T25609] Fix lexing comments in multiline strings (#25609) Message-ID: <67912047e553e_9accd106a4f4205b8@gitlab.mail> Brandon Chinn pushed to branch wip/T25609 at Glasgow Haskell Compiler / GHC Commits: 94aa63fa by Brandon Chinn at 2025-01-22T08:43:30-08:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - 9 changed files: - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/String.x - compiler/ghc.cabal.in - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/parser/should_run/NumericUnderscores0.hs - testsuite/tests/parser/should_run/NumericUnderscores0.stdout - + testsuite/tests/parser/should_run/T25609.hs - + testsuite/tests/parser/should_run/T25609.stdout - testsuite/tests/parser/should_run/all.T Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -132,6 +132,7 @@ import GHC.Parser.Errors.Basic import GHC.Parser.Errors.Types import GHC.Parser.Errors.Ppr () import GHC.Parser.Lexer.Interface +import qualified GHC.Parser.Lexer.String as Lexer.String import GHC.Parser.String } @@ -622,13 +623,6 @@ $unigraphic / { isSmartQuote } { smart_quote_error } \" @stringchar* $unigraphic / { isSmartQuote } { smart_quote_error } } - { - -- Parse as much of the multiline string as possible, except for quotes - @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { tok_string_multi_content } - -- Allow bare quotes if it's not a triple quote - (\" | \"\") / ([\n .] # \") { tok_string_multi_content } -} - <0> { \'\' { token ITtyQuote } @@ -2171,11 +2165,23 @@ tok_string span buf len _buf2 = do src = SourceText $ lexemeToFastString buf len endsInHash = currentChar (offsetBytes (len - 1) buf) == '#' --- | Ideally, we would define this completely with Alex syntax, like normal strings. --- Instead, this is defined as a hybrid solution by manually invoking lex states, which --- we're doing for two reasons: --- 1. The multiline string should all be one lexical token, not multiple --- 2. We need to allow bare quotes, which can't be done with one regex +{- Note [Lexing multiline strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ideally, we would lex multiline strings completely with Alex syntax, like +normal strings. However, we can't because: + + 1. The multiline string should all be one lexical token, not multiple + 2. We need to allow bare quotes, which can't be done with one regex + +Instead, we'll lex them with a hybrid solution in tok_string_multi by manually +invoking lex states. This allows us to get the performance of native Alex +syntax as much as possible, and just gluing the pieces together outside of +Alex. + +Implemented in string_multi_content in GHC/Parser/Lexer/String.x +-} + +-- | See Note [Lexing multiline strings] tok_string_multi :: Action tok_string_multi startSpan startBuf _len _buf2 = do -- advance to the end of the multiline string @@ -2201,17 +2207,14 @@ tok_string_multi startSpan startBuf _len _buf2 = do pure $ L span $ ITstringMulti src (mkFastString s) where goContent i0 = - case alexScan i0 string_multi_content of - AlexToken i1 len _ + case Lexer.String.alexScan i0 Lexer.String.string_multi_content of + Lexer.String.AlexToken i1 len _ | Just i2 <- lexDelim i1 -> pure (i1, i2) | isEOF i1 -> checkSmartQuotes >> setInput i1 >> lexError LexError - -- is the next token a tab character? - -- need this explicitly because there's a global rule matching $tab - | Just ('\t', _) <- alexGetChar' i1 -> setInput i1 >> lexError LexError -- Can happen if no patterns match, e.g. an unterminated gap | len == 0 -> setInput i1 >> lexError LexError | otherwise -> goContent i1 - AlexSkip i1 _ -> goContent i1 + Lexer.String.AlexSkip i1 _ -> goContent i1 _ -> setInput i0 >> lexError LexError lexDelim = @@ -2235,11 +2238,6 @@ tok_string_multi startSpan startBuf _len _buf2 = do Just (c, loc) -> throwSmartQuoteError c loc Nothing -> pure () --- | Dummy action that should never be called. Should only be used in lex states --- that are manually lexed in tok_string_multi. -tok_string_multi_content :: Action -tok_string_multi_content = panic "tok_string_multi_content unexpectedly invoked" - lex_chars :: (String, String) -> PsSpan -> StringBuffer -> Int -> P String lex_chars (startDelim, endDelim) span buf len = either (throwStringLexError i0) pure $ @@ -3371,6 +3369,7 @@ topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. +-- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} lexToken :: P (PsLocated Token) ===================================== compiler/GHC/Parser/Lexer/String.x ===================================== @@ -0,0 +1,96 @@ +{ +{- | +This module defines lex states for strings. + +This needs to be separate from the normal lexer because the normal lexer +automatically includes rules like skipping whitespace or lexing comments, +which we don't want in these contexts. +-} +module GHC.Parser.Lexer.String ( + AlexReturn (..), + alexScan, + string_multi_content, +) where + +import GHC.Prelude + +import GHC.Parser.Lexer.Interface +import GHC.Utils.Panic (panic) +} + +-- ----------------------------------------------------------------------------- +-- Alex "Character set macros" +-- Copied from GHC/Parser/Lexer.x + +$unispace = \x05 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$nl = [\n\r\f] +$space = [\ $unispace] +$whitechar = [$nl \v $space] +$tab = \t + +$ascdigit = 0-9 +$unidigit = \x03 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$decdigit = $ascdigit -- exactly $ascdigit, no more no less. +$digit = [$ascdigit $unidigit] + +$special = [\(\)\,\;\[\]\`\{\}] +$ascsymbol = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~\:] +$unisymbol = \x04 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$symbol = [$ascsymbol $unisymbol] # [$special \_\"\'] + +$unilarge = \x01 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$asclarge = [A-Z] +$large = [$asclarge $unilarge] + +$unismall = \x02 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$ascsmall = [a-z] +$small = [$ascsmall $unismall \_] + +$uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$idchar = [$small $large $digit $uniidchar \'] + +$unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] +$charesc = [a b f n r t v \\ \" \' \&] + +$octit = 0-7 +$hexit = [$decdigit A-F a-f] + +-- ----------------------------------------------------------------------------- +-- Alex "Regular expression macros" +-- Copied from GHC/Parser/Lexer.x + + at numspc = _* -- numeric spacer (#14473) + at decimal = $decdigit(@numspc $decdigit)* + at octal = $octit(@numspc $octit)* + at hexadecimal = $hexit(@numspc $hexit)* + at gap = \\ $whitechar+ \\ + at cntrl = $asclarge | \@ | \[ | \\ | \] | \^ | \_ + at ascii = \^ @cntrl | "NUL" | "SOH" | "STX" | "ETX" | "EOT" | "ENQ" | "ACK" + | "BEL" | "BS" | "HT" | "LF" | "VT" | "FF" | "CR" | "SO" | "SI" | "DLE" + | "DC1" | "DC2" | "DC3" | "DC4" | "NAK" | "SYN" | "ETB" | "CAN" + | "EM" | "SUB" | "ESC" | "FS" | "GS" | "RS" | "US" | "SP" | "DEL" + at escape = \\ ( $charesc | @ascii | @decimal | o @octal | x @hexadecimal ) + at stringchar = ($graphic # [\\ \"]) | $space | @escape | @gap + +:- + +-- Define an empty rule so it compiles; callers should always explicitly specify a startcode +<0> () ; + +-- See Note [Lexing multiline strings] + { + -- Parse as much of the multiline string as possible, except for quotes + @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { string_multi_content_action } + -- Allow bare quotes if it's not a triple quote + (\" | \"\") / ([\n .] # \") { string_multi_content_action } +} + +-- ----------------------------------------------------------------------------- +-- Haskell actions +{ +-- | Dummy action that should never be called. Should only be used in lex states +-- that are manually lexed in tok_string_multi. +string_multi_content_action :: a +string_multi_content_action = panic "string_multi_content_action unexpectedly invoked" +} ===================================== compiler/ghc.cabal.in ===================================== @@ -647,6 +647,7 @@ Library GHC.Parser.Header GHC.Parser.Lexer GHC.Parser.Lexer.Interface + GHC.Parser.Lexer.String GHC.Parser.HaddockLex GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -128,6 +128,7 @@ GHC.Parser.Errors.Types GHC.Parser.HaddockLex GHC.Parser.Lexer GHC.Parser.Lexer.Interface +GHC.Parser.Lexer.String GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock GHC.Parser.String ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.hs ===================================== @@ -99,3 +99,6 @@ main = do 0x_ff == 0xff, 0x__ff == 0xff ] + + -- ensure that strings are unaffected + print ["\o16_000", "\16_000", "\x16_000"] ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.stdout ===================================== @@ -11,3 +11,4 @@ [True,True,True] [True,True,True] [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] +["\SO_000","\DLE_000","\SYN_000"] ===================================== testsuite/tests/parser/should_run/T25609.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE MultilineStrings #-} + +main :: IO () +main = do + -- strings with comment tokens + print """{- asdf -}""" + print """a {- asdf -} b""" + print """-- asdf""" + print """{-""" + + -- strings with haddock comments + print """{- | test -}""" + print """{- * test -}""" + print """{- ^ test -}""" + print """{- $ test -}""" + print """-- | test""" + print """-- * test""" + print """-- ^ test""" + print """-- $ test""" + + -- strings with only whitespace + print """ """ + print """ + + + """ + + -- strings with unicode + print """ + ★ + ★ + ★ + ★ + """ ===================================== testsuite/tests/parser/should_run/T25609.stdout ===================================== @@ -0,0 +1,15 @@ +"{- asdf -}" +"a {- asdf -} b" +"-- asdf" +"{-" +"{- | test -}" +"{- * test -}" +"{- ^ test -}" +"{- $ test -}" +"-- | test" +"-- * test" +"-- ^ test" +"-- $ test" +" " +"\n" +" \9733\n\9733\n \9733\n\9733" ===================================== testsuite/tests/parser/should_run/all.T ===================================== @@ -21,6 +21,9 @@ test('RecordDotSyntax3', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compil test('RecordDotSyntax4', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compile_and_run, ['RecordDotSyntax4', '']) test('RecordDotSyntax5', normal, compile_and_run, ['']) test('ListTuplePunsConstraints', extra_files(['ListTuplePunsConstraints.hs']), ghci_script, ['ListTuplePunsConstraints.script']) + +# Multiline strings test('MultilineStrings', normal, compile_and_run, ['']) test('MultilineStringsOverloaded', normal, compile_and_run, ['']) test('T25375', normal, compile_and_run, ['']) +test('T25609', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/94aa63fafd027ef32a31045f02f608a06083893d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/94aa63fafd027ef32a31045f02f608a06083893d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 17:35:59 2025 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Wed, 22 Jan 2025 12:35:59 -0500 Subject: [Git][ghc/ghc][wip/int-index/list-tuple-cleanup] Rework built-in and punned names (#25174, #25179, #25180, #25182) Message-ID: <67912c7f13a22_d501730960c67398@gitlab.mail> Vladislav Zavialov pushed to branch wip/int-index/list-tuple-cleanup at Glasgow Haskell Compiler / GHC Commits: 29b18378 by Vladislav Zavialov at 2025-01-22T20:34:08+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Name/Cache.hs - compiler/GHC/Types/Name/Ppr.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/ghc-api/T18522-dbg-ppr.hs - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - + testsuite/tests/rename/should_compile/ReExportTuples.hs - + testsuite/tests/rename/should_compile/T25182.hs - testsuite/tests/rename/should_compile/all.T - testsuite/tests/simplStg/should_compile/T15226b.stderr - + testsuite/tests/th/FunNameTH.hs - testsuite/tests/th/T13776.hs - testsuite/tests/th/T13776.stderr - testsuite/tests/th/T17380.stderr - + testsuite/tests/th/T25174.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29b183786e4fb7be3b97686b5cfc4109bcca5f86 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29b183786e4fb7be3b97686b5cfc4109bcca5f86 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 17:41:40 2025 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Wed, 22 Jan 2025 12:41:40 -0500 Subject: [Git][ghc/ghc][wip/int-index/list-tuple-cleanup] 5 commits: compiler: Fix CPP guards around ghc_unique_counter64 Message-ID: <67912dd44099d_d501749df687073d@gitlab.mail> Vladislav Zavialov pushed to branch wip/int-index/list-tuple-cleanup at Glasgow Haskell Compiler / GHC Commits: 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 51e3ec83 by Vladislav Zavialov at 2025-01-22T20:41:32+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29b183786e4fb7be3b97686b5cfc4109bcca5f86...51e3ec839c378f0da7052278a56482f0349e9bc7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29b183786e4fb7be3b97686b5cfc4109bcca5f86...51e3ec839c378f0da7052278a56482f0349e9bc7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 18:24:45 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 22 Jan 2025 13:24:45 -0500 Subject: [Git][ghc/ghc][ghc-9.10] 32 commits: Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Message-ID: <679137ed1f434_f6b74c0af854397@gitlab.mail> Andreas Klebinger pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: ba97aa2d by Alex Mason at 2025-01-13T15:01:42+01:00 Implements MO_S_Mul2 and MO_U_Mul2 using the UMULH, UMULL and SMULH instructions for AArch64 Also adds a test for MO_S_Mul2 (cherry picked from commit dbdf1995956a7457c34b6895c67ef48f6c8384f2) - - - - - 52812e1c by Matthew Pickering at 2025-01-13T15:04:41+01:00 Bump os-string submodule to 2.0.2.2 Closes #24786 (cherry picked from commit 0528509028ef6c4d80d47aad9fd80de6c662c8a2) - - - - - a085f505 by Alex Mason at 2025-01-13T15:05:55+01:00 Add AArch64 CLZ, CTZ, RBIT primop implementations. Adds support for emitting the clz and rbit instructions, which are used by GHC.Prim.clz*#, GHC.Prim.ctz*# and GHC.Prim.bitReverse*#. (cherry picked from commit 71010381f4270966de334193ab2bfc67f8524212) - - - - - 6faa8336 by Andreas Klebinger at 2025-01-13T15:06:40+01:00 GHCi interpreter: Tag constructor closures when possible. When evaluating PUSH_G try to tag the reference we are pushing if it's a constructor. This is potentially helpful for performance and required to fix #24870. (cherry picked from commit 1bfa91115b8320ed99a5e946147528e21ca4f3e1) - - - - - 8a963d2c by Peter Trommler at 2025-01-14T12:44:32+01:00 X86 NCG: Fix argument promotion in foreign C calls Promote 8 bit and 16 bit signed arguments by sign extension. Fixes #25018 (cherry picked from commit a82121b3b6fdc2ac47211f71871b3ab21e5f6276) - - - - - d09da820 by Matthew Pickering at 2025-01-14T12:44:38+01:00 configure: Set LD_STAGE0 appropiately when 9.10.1 is used as a boot compiler In 9.10.1 the "ld command" has been removed, so we fall back to using the more precise "merge objects command" when it's available as LD_STAGE0 is only used to set the object merging command in hadrian. Fixes #24949 (cherry picked from commit 564981bda9a6a309ff0f524610af0f908432442f) - - - - - fffba270 by Matthew Pickering at 2025-01-14T12:44:39+01:00 hadrian: Don't build ghci object files for ./hadrian/ghci target There is some convoluted logic which determines whether we build ghci object files are not. In any case, if you set `ghcDynPrograms = pure False` then it forces them to be built. Given we aren't ever building executables with this flavour it's fine to leave `ghcDynPrograms` as the default and it should be a bit faster to build less. Also fixes #24949 (cherry picked from commit a949c792388b5662dd199497541f9ad51c78d1a8) - - - - - 20632a9f by Matthew Pickering at 2025-01-14T12:44:39+01:00 ci: Unset ALEX/HAPPY variables when testing bootstrap jobs Ticket #24826 reports a regression in 9.10.1 when building from a source distribution. This patch is an attempt to reproduce the issue on CI by more aggressively removing `alex` and `happy` from the environment. (cherry picked from commit 3f9548fe97c728ed60ba26811e4fe248fc28d2a7) - - - - - 4ecf7782 by Andrea Bedini at 2025-01-14T12:44:39+01:00 hadrian: Ignore build-tool-depends fields in cabal files hadrian does not utilise the build-tool-depends fields in cabal files and their presence can cause issues when building source distribution (see #24826) Ideally Cabal would support building "full" source distributions which would remove the need for workarounds in hadrian but for now we can patch the build-tool-depends out of the cabal files. Fixes #24826 (cherry picked from commit aba2c9d4728262cd9a2d711eded9050ac131c6c1) - - - - - 89a3ef84 by Zubin Duggal at 2025-01-14T12:44:39+01:00 compiler: Fingerprint -fwrite-if-simplified-core We need to recompile if this flag is changed because later modules might depend on the simplified core for this module if -fprefer-bytecode is enabled. Fixes #24656 (cherry picked from commit dddc9dff0547733a10e7f505612ab9df3a7c21b6) - - - - - 0d81d70a by Alex Mason at 2025-01-14T12:48:36+01:00 ncg(aarch64): Add fsqrt instruction, byteSwap primitives [#24956] Implements the FSQRT machop using native assembly rather than a C call. Implements MO_BSwap by producing assembly to do the byte swapping instead of producing a foreign call a C function. In `tar`, the hot loop for `deserialise` got almost 4x faster by avoiding the foreign call which caused spilling live variables to the stack -- this means the loop did 4x more memory read/writing than necessary in that particular case! (cherry picked from commit dee035bf618d75a18fe72dd3977434c0749a2156) - - - - - 27696fe0 by Sylvain Henry at 2025-01-14T12:48:38+01:00 Linker: use m32 allocator for sections when NEED_PLT (#24432) Use M32 allocator to avoid fragmentation when allocating ELF sections. We already did this when NEED_PLT was undefined. Failing to do this led to relocations impossible to fulfil (#24432). (cherry picked from commit 5104ee615503617a1c124fe1d92f6aa2d263b7d0) - - - - - d8dd7752 by Sylvain Henry at 2025-01-14T12:48:38+01:00 RTS: allow M32 allocation outside of 4GB range when assuming -fPIC (cherry picked from commit 52d6698479f951e07def237b0474ee22d27e621a) - - - - - 31e744b8 by Sylvain Henry at 2025-01-14T12:48:38+01:00 Linker: fix stub offset Remove unjustified +8 offset that leads to memory corruption (cf discussion in #24432). (cherry picked from commit c34fef56367142fa55e9861092f64cc7b9946fa1) - - - - - 61a648b3 by Simon Peyton Jones at 2025-01-14T12:48:38+01:00 Address #25055, by disabling case-of-runRW# in Gentle phase See Note [Case-of-case and full laziness] in GHC.Driver.Config.Core.Opt.Simplify (cherry picked from commit de5d9852dbdd367611bf9e45e69c723d26351992) - - - - - cb346572 by Andreas Klebinger at 2025-01-14T12:48:38+01:00 Fix -freg-graphs for FP and AARch64 NCG (#24941). It seems we reserve 8 registers instead of four for global regs based on the layout in Note [AArch64 Register assignments]. I'm not sure it's neccesary, but for now we just accept this state of affairs and simple update -fregs-graph to account for this. (cherry picked from commit 3f89ab92da74c4ed45da68fe92ff81e7b9caa53d) - - - - - 07393a24 by Simon Peyton Jones at 2025-01-22T14:45:04+01:00 Fix nasty bug in occurrence analyser As #25096 showed, the occurrence analyser was getting one-shot info flat out wrong. This commit does two things: * It fixes the bug and actually makes the code a bit tidier too. The work is done in the new function GHC.Core.Opt.OccurAnal.mkRhsOccEnv, especially the bit that prepares the `occ_one_shots` for the RHS. See Note [The OccEnv for a right hand side] * When floating out a binding we must be conservative about one-shot info. But we were zapping the entire demand info, whereas we only really need zap the /top level/ cardinality. See Note [Floatifying demand info when floating] in GHC.Core.Opt.SetLevels For some reason there is a 2.2% improvement in compile-time allocation for CoOpt_Read. Otherwise nickels and dimes. Metric Decrease: CoOpt_Read (cherry picked from commit f6b4c1c9be71fc6fe4688337752ffa4ad84180d9) - - - - - 1ecd6116 by Arnaud Spiwack at 2025-01-22T14:45:11+01:00 Add tests for 25081 (cherry picked from commit e2f2a56e42d25bae178ae1692390bbbd6275176c) - - - - - 850414e1 by Arnaud Spiwack at 2025-01-22T14:45:11+01:00 Scale multiplicity in list comprehension Fixes #25081 (cherry picked from commit 23f50640e705c132f1a0689d4850866d0f0d76a6) - - - - - 4c37bafd by doyougnu at 2025-01-22T14:45:11+01:00 Rts linker: add case for pc-rel 64 relocation part of the upstream haskell.nix patches (cherry picked from commit bfe4b3d3bbb98b39169fad063c6c32f06d167756) - - - - - 6d3d44bb by Sylvain Henry at 2025-01-22T14:45:11+01:00 Only lookup ghcversion.h file in the RTS include-dirs by default. The code was introduced in 3549c952b535803270872adaf87262f2df0295a4. It used `getPackageIncludePath` which name doesn't convey that it looks into all include paths of the preload units too. So this behavior is probably unintentional and it should be ok to change it. Fix #25106 (cherry picked from commit f954f42823f6ca3588425a0d543d93ace86d89e4) - - - - - 2486f9d0 by Andreas Klebinger at 2025-01-22T14:45:11+01:00 Add since annotation for -fkeep-auto-rules. This partially addresses #25082. - - - - - 77fadb7e by Andreas Klebinger at 2025-01-22T14:45:11+01:00 Mention `-fkeep-auto-rules` in release notes. It was added earlier but hadn't appeared in any release notes yet. Partially addresses #25082. - - - - - 0889c9e7 by Sylvain Henry at 2025-01-22T14:45:11+01:00 Cmm: don't perform unsound optimizations on 32-bit compiler hosts - beef61351b240967b49169d27a9a19565cf3c4af enabled the use of MO_Add/MO_Sub for 64-bit operations in the C and LLVM backends - 6755d833af8c21bbad6585144b10e20ac4a0a1ab did the same for the x86 NCG backend However we store some literal values as `Int` in the compiler. As a result, some Cmm optimizations transformed target 64-bit literals into compiler `Int`. If the compiler is 32-bit, this leads to computing with wrong literals (see #24893 and #24700). This patch disables these Cmm optimizations for 32-bit compilers. This is unsatisfying (optimizations shouldn't be compiler-word-size dependent) but it fixes the bug and it makes the patch easy to backport. A proper fix would be much more invasive but it shall be implemented in the future. Co-authored-by: amesgen <amesgen at amesgen.de> (cherry picked from commit 7446a09a2d5b04b95cd43c03659b5647853124ce) - - - - - cec2db29 by Sylvain Henry at 2025-01-22T14:45:11+01:00 AARCH64 linker: skip NONE relocations This patch is part of the patches upstreamed from haskell.nix. See https://github.com/input-output-hk/haskell.nix/pull/1960 for the original report/patch. (cherry picked from commit c749bdfd3e21d712dc2b966482eb010165bdeebe) - - - - - 2ecb9d68 by sheaf at 2025-01-22T14:45:11+01:00 GHCi debugger: drop record name spaces for Ids When binding new local variables at a breakpoint, we should create Ids with variable namespace, and not record field namespace. Otherwise the rest of the compiler falls over because the IdDetails are wrong. Fixes #25109 (cherry picked from commit c29b2b5a77611b2bd6c3089765079bc43aec3e22) - - - - - 0028decc by Sylvain Henry at 2025-01-22T14:45:11+01:00 JS: support rubbish static literals (#25177) Support for rubbish dynamic literals was added in #24664. This patch does the same for static literals. Fix #25177 (cherry picked from commit 5092dbff750ee5b6fd082b7eed8574922a2b0bf4) - - - - - 14c6b834 by Arsen Arsenović at 2025-01-22T14:45:11+01:00 ghc-toolchain: Don't leave stranded a.outs when testing for -g0 This happened because, when ghc-toolchain tests for -g0, it does so by compiling an empty program. This compilation creates an a.out. Since we create a temporary directory, lets place the test program compilation in it also, so that it gets cleaned up. Fixes: 25b0b40467d0a12601497117c0ad14e1fcab0b74 Closes: https://gitlab.haskell.org/ghc/ghc/-/issues/25203 (cherry picked from commit b16605e7c135f8cfd357a60c7f358132faec6a84) - - - - - 91e1572a by Cheng Shao at 2025-01-22T14:45:11+01:00 rts: fix checkClosure error message This patch fixes an error message in checkClosure() when the closure has already been evacuated. The previous logic was meant to print the evacuated closure's type in the error message, but it was completely wrong, given info was not really an info table, but a tagged pointer that points to the closure's new address. (cherry picked from commit 0d3bc2fa3a9a8c342ec34bb9d32e493655a4ec69) - - - - - 90b3ad99 by Simon Peyton Jones at 2025-01-22T14:45:11+01:00 Add ZonkAny and document it This MR fixed #24817 by adding ZonkAny, which takes a Nat argument. See Note [Any types] in GHC.Builtin.Types, especially wrinkle (Any4). (cherry picked from commit cfbff65a8bde902b4510cdaead847bf7a52b4018) - - - - - 9f5046b3 by Cheng Shao at 2025-01-22T14:45:11+01:00 compiler: avoid saving foreign call target to local when there are no caller-save GlobalRegs This patch makes the STG->Cmm backend avoid saving foreign call target to local when there are no caller-save GlobalRegs. Since 321941a8ebe25192cdeece723e1058f2f47809ea, when we lower a foreign call, we unconditionally save the foreign call target to a temporary local first, then rely on cmmSink to clean it up later, which only happens with -fcmm-sink (implied by -O) and not in unoptimized code. And this is troublesome for the wasm backend NCG, which needs to infer a foreign call target symbol's type signature from the Cmm call site. Previously, the NCG has been emitting incorrect type signatures for unoptimized code, which happens to work with `wasm-ld` most of the time, but this is never future-proof against upstream toolchain updates, and it causes horrible breakages when LTO objects are included in linker input. Hence this patch. (cherry picked from commit 8dd8a076058baca45ac52ace25b9c2797d61ef84) - - - - - c6e5b188 by Cheng Shao at 2025-01-22T14:45:11+01:00 testsuite: add callee-no-local regression test (cherry picked from commit 986df1abe23aaad4142721fbdb7dd3791cf153ad) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/AArch64/Regs.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Driver/Config/Core/Opt/Simplify.hs - compiler/GHC/Driver/Config/StgToCmm.hs - compiler/GHC/Iface/Recomp/Flags.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToCmm/Config.hs - compiler/GHC/StgToCmm/Foreign.hs - compiler/GHC/StgToCmm/Prim.hs - compiler/GHC/StgToJS/Literal.hs - compiler/GHC/SysTools/Cpp.hs - compiler/GHC/Tc/Gen/Match.hs - compiler/GHC/Tc/Types.hs - compiler/GHC/Tc/Utils/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a92613c21bc0d728d87fb48eb0a3f9bff20e04f5...c6e5b18825363b4a89d262de6d41a7844fab188d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a92613c21bc0d728d87fb48eb0a3f9bff20e04f5...c6e5b18825363b4a89d262de6d41a7844fab188d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 19:52:44 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 22 Jan 2025 14:52:44 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: driver: Store the HomePackageTable in a mutable reference Message-ID: <67914c8c9f386_f6b7413940585818e@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 1f9d2f33 by Brandon Chinn at 2025-01-22T14:52:38-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 9e2ad830 by Brandon Chinn at 2025-01-22T14:52:38-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - 65820de9 by Brandon Chinn at 2025-01-22T14:52:39-05:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Errors.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Linker/Deps.hs - compiler/GHC/Linker/ExtraObj.hs - compiler/GHC/Linker/Loader.hs - compiler/GHC/Linker/Static.hs - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/Runtime/Loader.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/69ffd30dccf6387626faf7c9924706d614265faf...65820de995bb712e6bace917115c8ed9448caa0c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/69ffd30dccf6387626faf7c9924706d614265faf...65820de995bb712e6bace917115c8ed9448caa0c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 20:00:33 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 22 Jan 2025 15:00:33 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/mul2 Message-ID: <67914e61240e4_f6b741528874625eb@gitlab.mail> Ben Gamari pushed new branch wip/mul2 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mul2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 20:04:20 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 22 Jan 2025 15:04:20 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/backports-9.12 Message-ID: <67914f4446f70_f6b741533abc64029@gitlab.mail> Ben Gamari pushed new branch wip/backports-9.12 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/backports-9.12 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 20:34:39 2025 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Wed, 22 Jan 2025 15:34:39 -0500 Subject: [Git][ghc/ghc][wip/T18631] doc: Add documentation for -XDoAndIfThenElse Message-ID: <6791565f7d00c_147b904411dc15250@gitlab.mail> Teo Camarasu pushed to branch wip/T18631 at Glasgow Haskell Compiler / GHC Commits: 311fc853 by Teo Camarasu at 2025-01-22T20:34:30+00:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4 changed files: - docs/users_guide/conf.py - docs/users_guide/expected-undocumented-flags.txt - + docs/users_guide/exts/doandifthenelse.rst - docs/users_guide/exts/syntax.rst Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -36,7 +36,6 @@ nitpick_ignore = [ ("c:type", "bool"), - ("extension", "DoAndIfThenElse"), ("extension", "RelaxedPolyRec"), ] ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -7,7 +7,6 @@ -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional -XAutoDeriveTypeable --XDoAndIfThenElse -XDoRec -XJavaScriptFFI -XParallelArrays ===================================== docs/users_guide/exts/doandifthenelse.rst ===================================== @@ -0,0 +1,30 @@ +.. _doandifthenelse: + +Do And If Then Else +============ + +.. extension:: DoAndIfThenElse + :shortdesc: Allow semicolons in ``if`` expressions. + + :since: 7.0.1 + + :status: Included in :extension:`Haskell2010` + + Allow semicolons in ``if`` expressions. + +Normally, a conditional is written like this: ``if cond then expr1 else expr2``. With the extension +:extension:`DoAndIfThenElse`, semicolons are allowed before the ``then`` and also before the ``else``, allowing +``if cond; then expr1; else expr2``. (You can also include either semicolon on its own.) + +Allowing semicolons in the middle of a conditional is useful in connection with layout-controlled +blocks, like ``do``\ -blocks. This is because GHC invisibly inserts a semicolon between each line of a +layout-controlled block. Accordingly, with :extension:`DoAndIfThenElse`, we can write code like this :: + + f mb x y = do + b <- mb + if b + then x + else y + +Without :extension:`DoAndIfThenElse`, the ``then`` and ``else`` lines would have to be indented with respect +to the rest of the lines in the ``do``\ -block. ===================================== docs/users_guide/exts/syntax.rst ===================================== @@ -20,6 +20,7 @@ Syntax lambda_case empty_case multiway_if + doandifthenelse local_fixity_decls block_arguments typed_holes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/311fc8533c70d0f8a730f9ea4d55daeeec59cae5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/311fc8533c70d0f8a730f9ea4d55daeeec59cae5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 22:50:00 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Wed, 22 Jan 2025 17:50:00 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] hadrian: change || to && Message-ID: <679176188c985_16f759adb89442119@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: bb99b85e by Luite Stegeman at 2025-01-22T15:16:00+01:00 hadrian: change || to && - - - - - 1 changed file: - hadrian/src/Settings/Builders/Ghc.hs Changes: ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -247,9 +247,9 @@ packageGhcArgs = do , packageDatabaseArgs -- We want to pass -this-unit-id for executables as well for multi-repl to -- work with executable packages but this is buggy on GHC-9.0.2 - , (isLibrary package || (ghc_ver >= makeVersion [9,2,1])) ? + , (isLibrary package && (ghc_ver >= makeVersion [9,2,1])) ? arg ("-this-unit-id " ++ pkgId) - , (isLibrary package || (ghc_ver >= makeVersion [9,4,1])) ? + , (isLibrary package && (ghc_ver >= makeVersion [9,4,1])) ? arg ("-this-package-name " ++ pkgName) , map ("-package-id " ++) <$> getContextData depIds ] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb99b85e7d7b56c6d322cba7eca8a5316d478121 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb99b85e7d7b56c6d322cba7eca8a5316d478121 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 22 23:07:18 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Wed, 22 Jan 2025 18:07:18 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] hadrian: fix condition for -this-package-name Message-ID: <67917a26c5743_16f75910f7ebc428d0@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 4ccbf2ce by Luite Stegeman at 2025-01-23T00:06:09+01:00 hadrian: fix condition for -this-package-name - - - - - 1 changed file: - hadrian/src/Settings/Builders/Ghc.hs Changes: ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -247,9 +247,9 @@ packageGhcArgs = do , packageDatabaseArgs -- We want to pass -this-unit-id for executables as well for multi-repl to -- work with executable packages but this is buggy on GHC-9.0.2 - , (isLibrary package && (ghc_ver >= makeVersion [9,2,1])) ? + , (isLibrary package || (ghc_ver >= makeVersion [9,2,1])) ? arg ("-this-unit-id " ++ pkgId) - , (isLibrary package && (ghc_ver >= makeVersion [9,4,1])) ? + , (ghc_ver >= makeVersion [9,4,1]) ? arg ("-this-package-name " ++ pkgName) , map ("-package-id " ++) <$> getContextData depIds ] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ccbf2ce5c1a6a9c44873f5e3067571261f40278 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ccbf2ce5c1a6a9c44873f5e3067571261f40278 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 02:19:37 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 22 Jan 2025 21:19:37 -0500 Subject: [Git][ghc/ghc][wip/backports-9.12] 224 commits: haddock: Allow building with GHC 9.12 Message-ID: <6791a73964801_1fcf55717dac44274@gitlab.mail> Ben Gamari pushed to branch wip/backports-9.12 at Glasgow Haskell Compiler / GHC Commits: 362afd63 by Zubin Duggal at 2024-10-02T18:12:52+05:30 haddock: Allow building with GHC 9.12 Also bump `binaryInterfaceVersion` to 45 to detect binary version changes. - - - - - 18860aa6 by Andreas Klebinger at 2024-10-13T21:07:34+05:30 SpecConstr: Introduce a separate argument limit for forced specs. We used to put no limit at all on specializations forced via the SPEC argument. This isn't always reasonable so we introduce a very high limit that applies to forced specializations, a flag to control it, and we now emit a warning if we fail a specialization because we exceed the warning. Fixes #25197 (cherry picked from commit da20cac16d0982c982f9d6779dc8174e5184fe15) - - - - - 0904d0c1 by Andreas Klebinger at 2024-10-13T21:08:23+05:30 ghc-experimental: Expose primops and ghc extensions via GHC.PrimOps This will be the new place for functions that would have gone into GHC.Exts in the past but are not stable enough to do so now. Addresses #25242 (cherry picked from commit 39497eeda74fc7f1e7ea89292de395b16f69cee2) - - - - - 187b2d5d by Sylvain Henry at 2024-10-13T21:08:36+05:30 RTS: cleanup timerfd file descriptors after a fork (#25280) When we init a timerfd-based ticker, we should be careful to cleanup the old file descriptors (e.g. after a fork). (cherry picked from commit e9dc26907e13eeb73514ff3f70323b40b40ef8ac) - - - - - b9b6807e by Matthew Pickering at 2024-10-13T21:08:51+05:30 Bump LLVM upper bound to allow LLVM 19 Also bumps the ci-images commit so that the deb12 images uses LLVM 19 for testing. ------------------------- Metric Decrease: size_hello_artifact_gzip size_hello_unicode_gzip ------------------------- Fixes #25295 (cherry picked from commit 36bbb167f354a2fbc6c4842755f2b1e374e3580e) - - - - - d6b8a4fb by ARATA Mizuki at 2024-10-13T21:09:19+05:30 Use bundled llc/opt on Windows (#22438) (cherry picked from commit 92976985625ffba551f1e1422f5e3a0cbf7beb89) - - - - - f9a0dc6d by Andreas Klebinger at 2024-10-13T21:09:36+05:30 Change versionig of ghc-experimental to follow ghc versions. Just like ghc-internal it will now use the @ProjectVersionForLib@ macro for versioning. This means for ghc=9.10.1, ghc-experimental's version will be 9.1001.0 and so on. This fixes #25289 (cherry picked from commit 2293c0b7d709df7be04f596e72c97fd2435c4134) - - - - - a85c33c4 by Rodrigo Mesquita at 2024-10-13T21:09:47+05:30 determinism: Deterministic MonadGetUnique LlvmM Update LlvmM to thread a unique deterministic supply (using UniqDSMT), and use it in the MonadGetUnique instance. This makes uniques sampled from LlvmM deterministic, which guarantees object determinism with -fllvm. Fixes #25274 (cherry picked from commit 64e876bc0a5dd5d59b47ee3969b52a3bcecb37e6) - - - - - 623a2534 by Cheng Shao at 2024-10-13T21:09:56+05:30 testsuite: remove accidentally checked in debug print logic (cherry picked from commit bcb293f216e56c8dfd199f990e8eaa48071ef845) - - - - - 6bbb7588 by Daniel Díaz at 2024-10-13T21:10:06+05:30 Clarify the meaning of "exactly once" in LinearTypes Solves documentaion issue #25084. (cherry picked from commit 535a2117239f0d0e4588c6616fcd8deed725cfc0) - - - - - b78e8c5b by Krzysztof Gogolewski at 2024-10-13T21:10:14+05:30 Only allow (a => b) :: Constraint rather than CONSTRAINT rep Fixes #25243 (cherry picked from commit 92f8939a5fa689dc0143501cfeac0b3b2cd7abd6) - - - - - a4328a4c by Teo Camarasu at 2024-10-13T21:11:42+05:30 Add changelog entries for !12479 (cherry picked from commit c9590ba0703d65ecb9d71ac8390c1ae1144bd9d0) - - - - - 616dfef0 by Matthew Pickering at 2024-10-13T21:12:05+05:30 Fix registerArch for riscv64 The register allocator doesn't support vector registers on riscv64, therefore advertise as NoVectors. Fixes #25314 (cherry picked from commit af59749abb723283fa42b51f62a8ac8b345a7f8f) - - - - - 76549660 by Matthew Pickering at 2024-10-13T21:12:20+05:30 riscv: Avoid using csrr instruction to test for vector registers The csrr instruction isn't allowed in qemu user-mode, and raises an illegal instruction error when it is encountered. Therefore for now, we just hard-code that there is no support for vector registers since the rest of the compiler doesn't support vector registers for riscv. Fixes #25312 (cherry picked from commit a49e66fcf26632b31991384193e9fc0f7d051adc) - - - - - 30e85658 by Andreas Klebinger at 2024-10-13T21:12:35+05:30 Add support for fp min/max to riscv Fixes #25313 (cherry picked from commit 115a30e9142b4481de3ba735396e9d0417d46445) - - - - - a4b9b1a2 by Sven Tennie at 2024-10-13T21:12:45+05:30 CCallConv test: Align argument types The C calling convention / standard requires that arguments and their values are of the same type. (cherry picked from commit 5fd320da57bb52458bb1e8c14c5311129d88a3a7) - - - - - 328dedef by sheaf at 2024-10-13T21:12:56+05:30 user's guide: update docs for X86 CPU flags This commit updates the section of the user's guide pertaining to X86 feature flags with the following changes: - the NCG backend now supports SIMD, so remove all text that says the contrary, - the LLVM backend does not "automatically detect" features, so remove any text that makes that claim. (cherry picked from commit 9c9c790dbca89722080f47158001ac3920f11606) - - - - - 7b07c101 by Matthew Pickering at 2024-10-13T21:13:04+05:30 ci: Add nightly & release ubuntu-22.04 jobs This adds build of bindists on ubuntu-22.04 on nightly and release pipelines. We also update ghcup-metadata to provide ubuntu-22.04 bindists on ubuntu-22.04. Fixes #25317 (cherry picked from commit 504900755e3297c000a3bcf4f20eaae1f10298f4) - - - - - 86f3005b by Cheng Shao at 2024-10-13T21:13:52+05:30 driver: bail out when -fllvm is passed to GHC not configured with LLVM This patch makes GHC bail out with an proper error message when it's not configured with LLVM but users attempt to pass -fllvm, see #25011 and added comment for details. Fixes #25011 Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> (cherry picked from commit 2338a971ce45ce7bc6ba2711e40966ec5ff12359) - - - - - abd0d124 by Simon Peyton Jones at 2024-10-13T21:16:19+05:30 Consider Wanteds with rewriters as insoluble This MR fixes #25325 See GHC.Tc.Types.Constraint, Note [Insoluble Wanteds], especially (IW2) There is a small change in the error message for T14172, but it looks entirely acceptable to me. (cherry picked from commit 083703a12cd34369e7ed2f0efc4a5baee47aedab) - - - - - fbbba0f1 by Simon Peyton Jones at 2024-10-13T21:16:27+05:30 Wibbles (cherry picked from commit 0dfaeb66fb8457e7339abbd44d5c53a81ad8ae3a) - - - - - 7164dbca by Simon Peyton Jones at 2024-10-13T21:16:33+05:30 Spelling errors (cherry picked from commit 09d24d828e48c2588a317e6dad711f8673983703) - - - - - aa5026c7 by sheaf at 2024-10-13T21:16:57+05:30 LLVM: use sse4.2 instead of sse42 LLVM expects the former instead of the latter since version 3.4. Fixes #25019 (cherry picked from commit 694489edf35c35b29fbdf09a8e3fdc404469858f) - - - - - 0b323326 by sheaf at 2024-10-13T21:17:15+05:30 LLVM: make SSE4.2 imply +popcnt For consistency with the NCG as well as with Clang and GCC, we make the SSE4.2 feature flag imply +popcnt when using the LLVM backend. Fixes #25353 (cherry picked from commit 06ae85071b95376bd1eb354f7cc7901aed45b625) - - - - - b1f40130 by Ben Gamari at 2024-10-13T21:17:26+05:30 base: Improve documentation of Control.Exception.Backtrace (cherry picked from commit 0060ece762d7a936daf28195676b6162c30dc845) - - - - - 95880157 by Ben Gamari at 2024-10-13T21:17:55+05:30 testsuite: Normalise trailing digits from hole fits output The type variables in the holes fit output from `abstract_refinement_hole_fits` is quite sensitive to compiler configuration. Specifically, a slight change in the inlining behavior of `throw` changes type variable naming in `(>>=)` and a few others. Ideally we would make hole fits output more deterministic but in the meantime we simply normalise this difference away as it not relevant to the test's goal. (cherry picked from commit d029f1700effa626ff622700b198ed49ee8b6c19) - - - - - f92a8a84 by Ben Gamari at 2024-10-13T21:18:09+05:30 base: Add test for #25066 (cherry picked from commit da5d7d0d8bde06a1c29612fd17b6a579fc523036) - - - - - 3d0fe159 by Ben Gamari at 2024-10-13T21:22:40+05:30 base: Fix #25066 As noted in #25066, the exception backtrace proposal introduced a rather subtle performance regression due to simplification producing Core which the demand analyser concludes may diverge with a precise exception. The nature of the problem is more completely described in the new Note [Hiding precise exception signature in throw]. The (rather hacky) solution we use here hides the problematic optimisation through judicious use of `noinline`. Ultimately however we will want a more principled solution (e.g. #23847). Fixes #255066 CLC proposal: https://github.com/haskell/core-libraries-committee/issues/290 Metric Decrease: T9872d (cherry picked from commit eb7ddae1a2b3fb1be1cd635849516a6398327b29) - - - - - 772b4f59 by Artem Pelenitsyn at 2024-10-13T21:22:40+05:30 Docs: Linear types: link Strict Patterns subsection Also, fix a bug in RST with missing newline before a listing. Co-authored-by: Arnaud Spiwack <arnaud at spiwack.net> (cherry picked from commit 4dd30cba51c7936dc53f0c1d331f88a590f93013) - - - - - 1418869f by Ben Gamari at 2024-10-13T21:22:40+05:30 base: Add `HasCallStack` constraint to `ioError` As proposed in core-libraries-committee#275. (cherry picked from commit 876d6e0e807c074d5c71370aa3c3451bbcb28342) - - - - - b5ad81c7 by Matthew Pickering at 2024-10-13T21:22:40+05:30 Fix toException method for ExceptionWithContext Fixes #25235 (cherry picked from commit 9bfd9fd0730359b4e88e97b08d3654d966a9a11d) - - - - - 35f20223 by Matthew Pickering at 2024-10-13T21:22:40+05:30 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> (cherry picked from commit ac0040286a8962b728a7cdb3c1be4691db635366) - - - - - a2ec22e7 by Rodrigo Mesquita at 2024-10-13T21:26:21+05:30 Add test for #25300 (cherry picked from commit 0e5cff6676426d614739c74bf6a953ef6e9659e6) - - - - - d92aa23a by Rodrigo Mesquita at 2024-10-13T21:26:30+05:30 Backport !13302 docs to users guide (cherry picked from commit e44e448ea8745a04724420edfa6ab4d24252a53f) - - - - - d2f2a3b2 by Alan Zimmerman at 2024-10-13T21:26:50+05:30 EPA: Remove unused hsCaseAnnsRest We never populate it, so remove it. (cherry picked from commit 4a2f0f1302f5919dfc9c8cbc410fceb19e7309ba) - - - - - b2c53e75 by Alan Zimmerman at 2024-10-13T21:29:24+05:30 EPA: Remove [AddEpAnn] from (most of) HsExpr EPA: introduce EpAnnLam for lambda annotationsi, and remove `glAA` from `Parser.y`, it is the same as `glR` EPA: Remove unused annotation from XOpApp EPA: Use EpToken for XNPat and XNegApp EPA: specific anns for XExplicitTuple / XTuplePat / sumPatParens. EPA: Use specific annotation for MultiIf EPA: Move annotations into FunRhs EPA: Remove [AddEpAnn] from SigPat and ExprWithTySig EPA: Remove [AddEpAnn] from ArithSeq EPA: Remove [AddEpAnn] from HsProc EPA: Remove [AddEpAnn] from HsStatic EPA: Remove [AddEpAnn] from BindStmt EPA: Remove [AddEpAnn] from TransStmt EPA: Remove [AddEpAnn] from HsTypedSplice EPA: Remove [AddEpAnn] from HsUntypedSpliceExpr (cherry picked from commit ef481813719c5f6d9d97b60ffef4617307d24c80) - - - - - 7564b6a7 by Zubin Duggal at 2024-10-13T21:30:30+05:30 hadrian: Handle broken symlinks properly when creating source dist directories If we have a broken symlink in the repository, don't try to `need` the symlink or the target of the symlink. Attempting to do so has `shake` attempt to read the target to compute its hash, which fails because the target doesn't exist. (cherry picked from commit 8b402da2738ef6bbc17409f1daac7448e064503a) - - - - - 39e19e26 by Zubin Duggal at 2024-10-13T21:30:37+05:30 hadrian: exclude cabal.project.symlink.broken from source archives Cabal 3.14 introduced a broken symlink in its testsuite. Unfortunately, this broke our source distribution as we use use `tar --dereference` to avoid issues with symlink compatibility on windows, and `tar --dereference` chokes when it encounters any broken symlinks. We can't get rid of `--dereference` because symlinks are generally broken on windows, so the only option is to exclude this file from source archives. see also https://github.com/haskell/cabal/issues/10442 (cherry picked from commit 16f97667a859337e8c82636aca7dd7102aa94b55) - - - - - c6dd5542 by Zubin Duggal at 2024-10-13T21:30:44+05:30 Bump Cabal submodule to 3.14 Metric Decrease: MultiLayerModulesTH_OneShot Metric Increase: haddock.Cabal (cherry picked from commit f1a2c9fc140baa0aaeda00c02648aa75deb59723) - - - - - e78c7ef9 by Zubin Duggal at 2024-10-14T14:20:59+05:30 haddock: oneshot tests can drop files if they share modtimes. Stop this by including the filename in the key. Ideally we would use `ghc -M` output to do a proper toposort Partially addresses #25372 - - - - - f230e29f by Zubin Duggal at 2024-10-15T04:26:11+05:30 testsuite: normalise some versions in callstacks - - - - - b19de476 by Zubin Duggal at 2024-10-15T04:26:11+05:30 testsuite: use -fhide-source-paths to normalise some backpack tests - - - - - fbf0889e by Zubin Duggal at 2024-10-15T04:26:11+05:30 testsuite/haddock: strip version identifiers and unit hashes from html tests - - - - - 473a201c by Zubin Duggal at 2024-10-15T04:26:11+05:30 Bump base bound to 4.21 for GHC 9.12 - - - - - a79a587e by Zubin Duggal at 2024-10-15T04:26:11+05:30 testsuite: fix normalisation of T9930fail so that it doesn't get tripped up by ghc executable (ARGV[0]) differences - - - - - f858875e by Zubin Duggal at 2024-10-15T04:41:35+05:30 testsuite: normalise windows file seperators - - - - - 24e5761e by Zubin Duggal at 2024-10-15T04:55:36+05:30 testsuite: Mark 25300A as broken on windows - - - - - ca2b21c3 by Zubin Duggal at 2024-10-15T04:55:41+05:30 Prepare 9.12.1 alpha - - - - - 128d1b18 by Alan Zimmerman at 2024-10-30T16:52:57+05:30 EPA: Remove [AddEpAnn] from IE, Pat and some Tys EPA: Remove [AddEpAnn] from LazyPat EPA: Remove [AddEpAnn] from RecordCon/RecordUpd/ConPat EPA: Remove [AddEpAnn] from HsFieldBind EPA: Remove [AddEpAnn] from PatSynBind EPA: Remove [AddEpAnn] from IPBind EPA: Remove [AddEpAnn] from FixSig EPA: Remove [AddEpAnn] from activation rules EPA: Remove [AddEpann] from SpecInstSig EPA: Remove [AddEpAnn] from MinimalSig EPA: Remove [AddEpAnn] from SCCFunSig EPA: Remove [AddEpAnn] from CompleteMatchSig EPA: Remove [AddEpAnn] from AnnSig, as used in PatSynSig, ClassOpSig, TypeSig EPA: Remove [AddEpAnn] from IEThingAbs EPA: Remove [AddEpAnn] from IEThingAll / IEThingWith EPA: Remove [AddEpAnn] from IEModuleContents EPA: Remove [AddEpAnn] from HsOpTy EPA: Remove [AddEpAnn] for various binders EPA: Remove [AddEpAnn] for HsIParamTy (cherry picked from commit e9cc469954eb19c5c131f9cfc1f0ede6ea9e9848) - - - - - bc19b10c by Alan Zimmerman at 2024-10-30T16:53:14+05:30 EPA: Remove [AddEpAnn] commit 3 EPA: Remove [AddEpAnn] from HsDocTy EPA: Remove [AddEpAnn] from HsBangTy EPA: Remove [AddEpAnn] from HsExplicitListTy EPA: Remove [AddEpAnn] from HsExplicitTupleTy EPA: Remove [AddEpAnn] from HsTypedBracket EPA: Remove [AddEpAnn] from HsUntypedBracket EPA: Remove [AddEpAnn] from PatBuilderOpApp EPA: break out 'EpToken "|"' from ClassDecl anns EPA: Remove [AddEpAnn] from ClassDecl EPA: Remove [AddEpAnn] from SynDecl (cherry picked from commit 5f67db48bdef51905132d990cfaaa0df6532ea99) - - - - - 96090209 by Cheng Shao at 2024-10-30T16:53:30+05:30 Revert "compiler: start deprecating cmmToRawCmmHook" This reverts commit 1c064ef1f3e1aa2afc996e962ad53effa99ec5f4. Turns out the GHC-WPC project does use it to observe Cmm in the pipeline, see #25363. (cherry picked from commit 525d451e175c7d6acfa968ce99d8d3fc7a8af0c7) - - - - - ba012ad5 by Cheng Shao at 2024-10-30T16:53:44+05:30 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. (cherry picked from commit 5bcfefd5bb73c18a9bad63d1813968832b696f9a) - - - - - cb003daf by Alan Zimmerman at 2024-10-30T16:54:21+05:30 EPA: Remove [AddEpAnn] Commit 4 EPA: Remove [AddEpAnn] from DataDecl This is quite a big change. The most important part is moving the annotations into HsDataDefn, using a specific annotation data type. It has a knock-on to everything that uses HsDataDefn EPA: Remove [AddEpAnn] for FunDep EPA: Remove [AddEpann] from FamilyDecl EPA: Remove [AddEpAnn] From InjectivityAnn EPA: Remove [AddEpAnn] from DefaultDecl EPA: Remove [AddEpAnn] from RuleDecls EPA: Remove [AddEpAnn] from Warnings (cherry picked from commit 25edf84977fa15b9911ecbdf614789893ad0e108) - - - - - ef8096d9 by Daan Rijks at 2024-10-30T16:55:36+05:30 Expand the haddocks for Control.Category (cherry picked from commit fbbbd010c5537480deaedc812a235311e13ef767) - - - - - 57c0c460 by Andrew Lelechenko at 2024-10-30T16:55:46+05:30 documentation: more examples for Control.Category (cherry picked from commit 076c1a104f55750a49de03694786180bd78eb9b6) - - - - - 30d12c46 by Cheng Shao at 2024-10-30T16:58:18+05:30 ghci: mitigate host/target word size mismatch in BCOByteArray serialization This patch mitigates a severe host/target word size mismatch issue in BCOByteArray serialization logic introduced since !12142, see added note for detailed explanation. (cherry picked from commit 90891962ad4d2c781e68062de01e25eea999ae1b) (cherry picked from commit 860596329a85295277aa21854f4aeae2b755c36f) - - - - - d256f923 by Cheng Shao at 2024-10-30T16:58:18+05:30 ghci: use plain malloc for mkConInfoTable on non-TNTC platforms This patch avoids using mmap() to allocate executable memory for mkConInfoTable on platforms without tables-next-to-code, see added comment for explanation. (cherry picked from commit 839ac52e94f8ecf878e522dba0575466af248267) (cherry picked from commit 9723a703e3fb53383d4afb49d012f9de43c4235b) - - - - - 50d5feec by Cheng Shao at 2024-10-30T16:58:18+05:30 ghc-internal: add missing CPPs for wasm This patch adds some missing CPP guards to ghc-internal, given those functions are non existent on wasm and would cause linking issues. (cherry picked from commit a998f69d2de062b7290e78221d55e8c49bf95bbc) (cherry picked from commit f95de54149e66627079d42cfa0b5b70286a3aae7) - - - - - 647752c8 by Cheng Shao at 2024-10-30T16:58:18+05:30 rts: rename prelude.js to prelude.mjs This commit renames prelude.js to prelude.mjs for wasm backend rts jsbits, and slightly adjusts the jsbits contents. This is for preparing the implementation of dyld.mjs that contains wasm dynamic linker logic, which needs to import prelude.mjs as a proper ESM module. (cherry picked from commit 71a471e7495f1fbf6b44cfbe4e930c99131c583e) (cherry picked from commit 1d5a2ff899d9c6905a216b24d5c4fc5d54654166) - - - - - 3218f014 by Cheng Shao at 2024-10-30T16:58:18+05:30 rts: add __wrapped_freeJSVal This commit wraps imported freeJSVal in a __wrapped_freeJSVal C function for wasm backend RTS. In general, wasm imports are only supposed to be directly called by C; they shouldn't be used as function pointers, which confuses wasm-ld at link-time when generating shared libraries. (cherry picked from commit 33d9db17f31f59ef72d6d8dac033a84c45d3c216) (cherry picked from commit 151017ca9483b77a83f0bde4eb20af490816e62a) - - - - - 68e780b5 by Cheng Shao at 2024-10-30T16:58:18+05:30 rts: correct stale link in comment (cherry picked from commit 0d0a16a81b3875c0e21c0bbe9659edc6312c4846) (cherry picked from commit dfb3988f3b6a96282cbf4e7edf95f15191dc8c36) - - - - - 6c08d83c by Cheng Shao at 2024-10-30T16:58:18+05:30 rts: drop interpretBCO support from non-dyn ways on wasm This commit drops interpretBCO support from non dynamic rts ways on wasm. The bytecode interpreter is only useful when the RTS linker also works, and on wasm it only works for dynamic ways anyway. An additional benefit of dropping interpretBCO is reduction in code size of linked wasm modules, especially since interpretBCO references ffi_call which is an auto-generated large function in libffi-wasm and unused by most user applications. (cherry picked from commit 90a35c41bb676b5e68212f63b187d2c50439714c) (cherry picked from commit 21dff5baafd20d2a796896c47c243b2c877e2ad4) - - - - - 319d4a46 by Cheng Shao at 2024-10-30T16:58:18+05:30 rts: don't build predefined GloblRegs for wasm PIC mode This commit wraps the predefined GlobalRegs in Wasm.S under a CPP guard to prevent building for PIC mode. When building dynamic ways of RTS, the wasm globals that represent STG GlobalRegs will be created and supplied by dyld.mjs. The current wasm dylink convention doesn't properly support exporting relocatable wasm globals at all, any wasm global exported by a .so is assumed to be a GOT.mem entry. (cherry picked from commit 98a32ec551dd95534c1a8eaccb0f67dbe5f19648) (cherry picked from commit 70f75b0defd8c1c7941581cd333ca198046c3d15) - - - - - 1fa9b36b by Cheng Shao at 2024-10-30T16:58:18+05:30 rts: fix conflicting StgRun definitions on wasm This commit fixes conflicting StgRun definition when building dynamic ways of RTS for wasm in unregisterised mode. (cherry picked from commit bef94bde53f07a1b0d7eb16d3d0eb1bd62f5f992) (cherry picked from commit b9b1a3a95588218b8b823f3315adad0fb7c2ed0c) - - - - - 92eed1ed by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian: use targetSupportsRPaths predicate This commit changes the hostSupportsRPaths predicate to targetSupportsRPaths and use that to decide whether to pass RPATH-related link-time options. It's not applied to stage0, we should just use the default link-time options of stageBoot ghc. (cherry picked from commit a6a82cdb7162f32a1b73a2a6224d6d9cd208962c) (cherry picked from commit 7e1f1b0778f581d2b72cfb533c65918b199e6247) - - - - - 355ac972 by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian: disable internal-interpreter of ghc library when cross compiling This commit disable the internal-interpreter flag of ghc library when cross compiling, only external interpreter works in such cases. (cherry picked from commit f232c872c6adf4472b5a1c88812c57aa2aa76cbe) (cherry picked from commit ce1387a065033fc1b85faa314be52f61a9057778) - - - - - af73ef6d by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian: enable internal-interpreter for ghc-bin stage0 This commit enables internal-interpreter flag for ghc-bin even when compiling stage0, as long as target supports ghci. It enables ghci functionality for cross targets that support ghci, since cross ghc-bin is really stage0. (cherry picked from commit 577c1819ab4eb3369cafdaf24114b74da21ce4b4) (cherry picked from commit 37b3d585e3f0f5c97a2ab375b8ac4ec9c3c17661) - - - - - dcd550ab by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian: fix CFLAGS for gmp shared objs on wasm This commit adds -fvisibility=default to CFLAGS of gmp when building for wasm. This is required to generate the ghc-bignum shared library without linking errors. Clang defaults to -fvisibility=hidden for wasm targets, which will cause issues when a symbol is expected to be exported in a shared library but without explicit visibility attribute annotation. (cherry picked from commit c247f2eef9e8450837cbaad1668c6178d094a8fb) (cherry picked from commit 18e5383329ca4a4bfe3a63f828a4f74f94031550) - - - - - 3d6f16cb by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian: re-enable PIC for gmp on wasm This commit re-enables --with-pic=yes configuration option of gmp when building for wasm, given we're about to include support for shared libraries, TH and ghci. (cherry picked from commit 775410fdfc5d6faf287eecdaae170af9f8a59bb9) (cherry picked from commit b537609f4f399538ee9e65df4f3442922693d487) - - - - - 4f4f378a by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian: add the host_fully_static flavour transformer This commit adds the host_fully_static flavour transformer to hadrian, which ensures stage0 is fully statically linked while still permitting stage1 libdir to contain shared libraries. This is intended to be used by the wasm backend to build portable linux bindists that contain wasm shared libraries. (cherry picked from commit b45080a3e34200767b76faca495f5aea95bb94f5) (cherry picked from commit c12980bf63c23bb1cbf3e3b3c27a4278a38f97d8) - - - - - f69cf2a5 by Cheng Shao at 2024-10-30T16:58:18+05:30 ci: update wasm jobs configuration This commit bumps ci-image revision to use updated wasm toolchain, and use host_fully_static instead of fully_static for wasm jobs so to ensure wasm shared libraries can be properly built. (cherry picked from commit 5043507ca32e31d14869a0a11dd317529f616fc2) (cherry picked from commit cbf0b2757b60313f356d701d0857cce44afe8b69) - - - - - 66c473f2 by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian/testsuite: implement config.cross logic This commit implements the config.cross field in the testsuite driver. It comes from the "cross compiling" ghc info field for both in-tree/out-of-tree GHC, and is an accurate predicate of whether we're cross-compiling or not (compared to the precense of target emulator), and is useful to implement predicates to assert the precense of internal interpreter (only available on non-cross GHC) for tests that do require it (e.g. plugins). (cherry picked from commit 2956a3f7ecd58a6fda81447100404941c0ed837d) (cherry picked from commit 00fef7bcd722c86b5b65d5189d47b9197b0c05a5) - - - - - cd124d94 by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian/compiler: implement targetRTSLinkerOnlySupportsSharedLibs This patch implements the targetRTSLinkerOnlySupportsSharedLibs predicate in hadrian. Its definition in hadrian is the single source of truth, and the information propagates to ghc settings file, ghc driver and testsuite driver. It is used in various places to ensure dynamic dependency is selected when the target RTS linker only supports loading dynamic code. (cherry picked from commit 8c74a0eda41255ead134f05598f5da70992a7054) (cherry picked from commit 9d2e02f911f42ffc6934f189b1d30e95ec47cc49) - - - - - 2daf1ddd by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: don't use host cpu features when testing cross ghc This patch disables CPU feature detection logic when testing cross GHC, since those features don't make sense for the target anyway. (cherry picked from commit b4c3c34090088378870a6705d30665aac6d5c455) (cherry picked from commit 17386f368a72bba5ed5b3a831e9e9cb744c2f989) - - - - - 0ab21132 by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: implement & use req_plugins predicate This commit implements req_plugins predicate to indicate that the test requires plugin functionality. Currently this means cross GHC is disabled since internal-interpreter doesn't work in cross GHC yet. (cherry picked from commit 3c21b696abc9acf375307eb91ccc678965487843) (cherry picked from commit 78600342635c931131ebcabb0fc6584fa44b6bbe) - - - - - 53187cb7 by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: make use of config.interp_force_dyn This commit takes config.interp_force_dyn into consideration when setting up TH/ghci way flags. (cherry picked from commit 93b8af8009a6e174b8d75f766dba2dc4d9aa9119) (cherry picked from commit 2741e5cf30ae2450b84a53b3b1ac6583ece7de2b) - - - - - b4431854 by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: bump T17572 timeout (cherry picked from commit 94673d419a8cdf71d722c93da9860ad8807657e7) (cherry picked from commit c5d97b796f6167d44501cb2ac69ef01432d38c3e) - - - - - 980adc2e by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: bump T22744 pre_cmd timeout (cherry picked from commit 2b5efc2d6b0b051ab0458ea0e2a2747b23190827) (cherry picked from commit e3f42443852f73504b3854737c94a32534b4b3db) - - - - - 2be13ac4 by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: skip terminfo_so for cross ghc (cherry picked from commit 45102e2ad39d95c06887be036722f793df236a04) (cherry picked from commit c93876ff7cd01344dc356d66eaf9f80f661660a9) - - - - - 908d6621 by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: fix shared library size tests for cross ghc This commit fixes shared library size tests (e.g. array_so in testsuite/tests/perf/size/all.T) when testing cross ghc. Previously, if shared library file extension of host and target differs, those tests will fail with framework errors due to not finding the right files. (cherry picked from commit 05e40406709fd325476a0fec89488a500094ecec) (cherry picked from commit d00c26a51a23e4fb7bc7d5c44033b9ee3e4f9149) - - - - - bd769e85 by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: skip ghc api tests that attempt to spawn processes inside wasm This commit skips a few ghc api tests on wasm, since they would attempt to spawn processes inside wasm, which is not supported at all. (cherry picked from commit fa68f83355ecca1f72f4593a1ed0422fa8fcb6a6) (cherry picked from commit aa49631399728d6e25625205eedf66d27dc152cb) - - - - - 1e80537e by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: skip T22840 due to broken -dtag-inference-checks on wasm (cherry picked from commit 1241c04e72107e1648f9aba5e857b48ec3bac96f) (cherry picked from commit 689c9267e758f3381a098ae5de120d84741fb2eb) - - - - - d5e9623d by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: ensure $(ghciWayFlags) can be overridden This commit revises boilerplate.mk in testsuite as well as a few other places, to ensure the tests that do make use of $(ghciWayFlags) can receive the right $(ghciWayFlags) from testsuite driver config. (cherry picked from commit 78c8b90006ac4d0a4de4e72295f8a57de4b9beca) (cherry picked from commit 6d0cdeedc42d6571e1cd17b862f09e8027baeb75) - - - - - b83ceaf4 by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: skip rdynamic on wasm (cherry picked from commit 47989ecc6ddfbe68ba2213c6c2b0d29ed958c330) (cherry picked from commit e220adb3dd370bae29e1f741bf5b4088d79f2599) - - - - - 838e9839 by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: skip T2615 on wasm This commit marks T2615 as skip on wasm, given LD_* environment variables aren't supported on wasm anyway. (cherry picked from commit fefb4ea1dee945ace173b63c808c593fc167803f) (cherry picked from commit 39d746e16e235889e39a6a8faefaef34522af89e) - - - - - cb100a9c by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: mark MultiLayerModulesTH_Make/MultiLayerModulesTH_OneShot as fragile on wasm (cherry picked from commit 77c797625483be968bb51c1518020895ca5ecb11) (cherry picked from commit 990addfc8ec7a4f13ed52f435e4f203fe60ff39b) - - - - - 59a3f31a by Cheng Shao at 2024-10-30T16:58:18+05:30 testsuite: fix T16180 on wasm This commit fixes T16180 on wasm once TH support is flipped on. The fix is simply adding right asm code for wasm. (cherry picked from commit 69bb4745218d2d54c82e33fa529ccf9ba3819fac) (cherry picked from commit ddff197541d5974bd8067362a6828c2361c69c33) - - - - - 66a0442d by Cheng Shao at 2024-10-30T16:58:18+05:30 driver: fix -fexternal-interpreter flag for JS backend Previously, -fexternal-interpreter is broken for JS backend, since GHC would attempt to launch a non-existent ghc-iserv* executable. This commit fixes it by adjusting pattern matching order in setTopSessionDynFlags. (cherry picked from commit 621c753dee540be65208d1fdcd1728ba9f2b4320) (cherry picked from commit 4d38dc40506057c5a3449b1841414ea8378a9f42) - - - - - cb8d1184 by Cheng Shao at 2024-10-30T16:58:18+05:30 driver: use interpreterDynamic predicate in preloadLib This commit use the interpreterDynamic predicate in preloadLib to decide if we should do dynLoadObjs instead of loadObj. Previously we used hostIsDynamic which was only written with non-cross internal interpreter in mind. The testsuite is also adjusted to remove hard-wired -fPIC flag for cbits (doesn't work in i386 RTS linker in vanilla way, #25260) and properly pass ghc_th_way_flags to ghc. (cherry picked from commit 80aa89831c18162ce5591400c41b4cd8f77db0e4) (cherry picked from commit 1b30373da385f2931f77443e56156089d6218dcc) - - - - - 752677dc by Cheng Shao at 2024-10-30T16:58:18+05:30 compiler: fix Cmm dynamic CLabels for wasm This commit fixes the handling of dynamic CLabels for the wasm backend. Just do the simplest handling: preserve the original CLabel, both unreg/NCG backends can handle them properly without issue. (cherry picked from commit 744114618678ed1eac7a699c738ffa3223d1b41a) (cherry picked from commit 762933824140e5af24ea27c998fdca699b7b8c53) - - - - - 49fe20a4 by Cheng Shao at 2024-10-30T16:58:18+05:30 driver: add necessary compile-time flags for wasm PIC mode This commit adds necessary compile-time flags when compiling for wasm PIC mode, see added comment for detailed explanation. (cherry picked from commit f6abaf13c527e372edea2d70f9c012da8624e27c) (cherry picked from commit 9834ac3b086c7489084edef8a81ce1155d739f30) - - - - - ccff9bc6 by Cheng Shao at 2024-10-30T16:58:18+05:30 driver: add necessary link-time flags for wasm shared libs This commit adds necessary link-time flags for wasm shared libs, see added comments for detailed explanation. (cherry picked from commit 9745fcfbffb6434bacdec69082739c9e0229c6f2) (cherry picked from commit 5c94cee60e631e4f5b2458377a1179cc5ad680db) - - - - - 724a9240 by Cheng Shao at 2024-10-30T16:58:18+05:30 driver: enforce -fno-use-rpaths for wasm This commit ensures the GHC driver never passes any RPATH-related link-time flags on wasm, which is not supported at all. (cherry picked from commit 649aae00c34014fcb64244de59961635563bf06a) (cherry picked from commit 55d8b48d125fc92c5e7679c0be6202d002f8e3c1) - - - - - cec1a8a3 by Cheng Shao at 2024-10-30T16:58:18+05:30 driver: ensure static archives are picked when linking static .wasm modules This commit ensures static archives are picked when linking .wasm modules which are supposed to be fully static, even when ghc may be invoked with -dynamic, see added comment for explanation. (cherry picked from commit 47baa9044a786ab04b6b68cf008f1254471c3cc1) (cherry picked from commit 1638d829e8c4c34d1a430799ea6c1a762bad9b38) - - - - - 46f944be by Cheng Shao at 2024-10-30T16:58:18+05:30 compiler: fix dynamic_too_enable for targets that require dynamic libraries This commit fixes dynamic_too_enable for targets whose RTS linker can only load dynamic code. (cherry picked from commit fc3a55917e9c6c64765f11e0703853b9eed230fe) (cherry picked from commit ba24a6bd70c06c8e02a29cc4ca5a39488c9edfe5) - - - - - 01684c08 by Cheng Shao at 2024-10-30T16:58:18+05:30 compiler: fix checkNonStdWay for targets that require dynamic libraries This commit fixes checkNonStdWay to ensure that for targets whose RTS linker can only load dynamic code, the dynamic way of object is selected. (cherry picked from commit 94ef949ef8b52cebaf8d4a81d7a169e100da2a73) (cherry picked from commit 38474be061ff58bc725a90b0994669d1477fe24e) - - - - - 205b8af3 by Cheng Shao at 2024-10-30T16:58:18+05:30 ghc-bin: enforce dynamic way when the target requires so This commit makes ghc-bin use dynamic way when it is doing interactive stuff on certain targets whose RTS linker can only handle dynamic code. (cherry picked from commit 88e992489e1574b471a55ff9ddace2c81a09ba63) (cherry picked from commit 50dc1ac1f9ad3ba62558346ef44759794508c863) - - - - - fdf17574 by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian/ghci: add wasm dyld This commit adds the wasm dynamic linker implementation, as well as ghci logic to call it and hadrian logic to install it to the correct location. See the top-level note in utils/jsffi/dyld.mjs for more details. (cherry picked from commit 549582eff80da6a8c5b7449755eaa726c208c324) (cherry picked from commit 5b545e3c9a2ca3bdf82cc24de92c1d977c8fff57) - - - - - 8e1d564d by Cheng Shao at 2024-10-30T16:58:18+05:30 driver: fix getGccSearchDirectory for wasm target This commit fixes getGccSearchDirectory logic for wasm target, ensures the correct search directory containing libc.so etc can be found by GHC. getGccSearchDirectory is also exported so it can be used elsewhere to obtain the wasi-sdk libdir and pass to the dyld script. (cherry picked from commit b562e3a6fab87422f40997f84b11a05505df2fcb) (cherry picked from commit d3510168869357f78527df9cc0fa0197c8c2016c) - - - - - e7d3bf92 by Cheng Shao at 2024-10-30T16:58:18+05:30 driver: add wasm backend iserv logic This commit adds wasm backend iserv logic to the driver, see added comments for explanation. (cherry picked from commit 2d6107dc0e461f6d339ea14712b6f0cb9a619680) (cherry picked from commit c07205fc70e17ffb228ca17f0eb239f2c858fe94) - - - - - c20a5175 by Cheng Shao at 2024-10-30T16:58:18+05:30 compiler: add PIC support to wasm backend NCG This commit adds support for generating PIC to the wasm backend NCG. (cherry picked from commit 61f5baa5bd6e8d0daa20af4dc7c3213a48f99019) (cherry picked from commit 9f8b78240c438fd8c32727f8cbce3ee644d517be) - - - - - 7608bc46 by Cheng Shao at 2024-10-30T16:58:18+05:30 hadrian/compiler: flip on support for shared libs & ghci for wasm This commit flips on the support for shared libs and ghci for the wasm target, given all required support logic has been added in previous commits. (cherry picked from commit 652e72394b715abc931b1104a4b683bb16909695) (cherry picked from commit e11dc80550084af2ea8aeba96e8a2a8a67468c03) - - - - - 07832d18 by Cheng Shao at 2024-10-30T16:58:19+05:30 testsuite: flip on support for shared libs, TH & ghci for wasm This commit flips on support for shared libs, TH & ghci for wasm in the testsuite, given support has been landed in previous commits. (cherry picked from commit 74a1f6818d1592ebceab8e0fbb6be1973f38fe78) (cherry picked from commit 2e63876a44236bc67af1aa0ed71db0acf6ac04a3) - - - - - 89adaa88 by Luite Stegeman at 2024-10-30T16:58:53+05:30 Interpreter: Add locking for communication with external interpreter This adds locking to communication with the external interpreter to prevent concurrent tasks interfering with each other. This fixes Template Haskell with the external interpreter in parallel (-j) builds. Fixes #25083 (cherry picked from commit d5f420450e86cedca819ca401b184917c6478c1a) - - - - - 35922587 by Alan Zimmerman at 2024-10-30T16:59:07+05:30 EPA: Remove [AddEpAnn] Commit 5 EPA: Remove [AddEpAnn] from AnnPragma EPA: Remove [AddEpAnn] From ForeignDecl EPA: Remove [AddEpAnn] from RoleAnnotDecl EPA: Remove [AddEpAnn] from StandaloneKindSig EPA: Remove [AddEpAnn] From HsDeriving EPA: Remove [AddEpAnn] from ConDeclField EPA: Remove [AddEpAnn] from ConDeclGADT EPA: Remove [AddEpAnn] from ConDeclH98 EPA: Remove [AddEpAnn] from ClsInstDecl (cherry picked from commit 7f61ed4e6f3b4d5933fa699ec2fc9dbab8052f7e) - - - - - 744fda1b by Daneel Yaitskov at 2024-10-30T16:59:45+05:30 base: speed up traceEventIO and friends when eventlogging is turned off #17949 Check the RTS flag before doing any work with the given lazy string. Fix #17949 Co-authored-by: Michael Peyton Jones <me at michaelpj.com> Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> (cherry picked from commit a04959b8964c8d09897cfae1fd7b06ac53ebee95) - - - - - 6509bb40 by Andrzej Rybczak at 2024-10-30T17:00:07+05:30 Adjust catches to properly rethrow exceptions https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13302 implemented exception rethrowing proposal, but it didn't adjust `catches`. This fixes it. (cherry picked from commit 148059fea534aced44649c739cd0fad4c25a99f0) - - - - - db954955 by Cheng Shao at 2024-10-30T17:00:18+05:30 hadrian: fix bindist executable wrapper logic for cross targets This commit fixes an oversight of hadrian wrapper generation logic: when doing cross compilation, `wrapper` is called on executable names with cross prefix, therefore we must use `isSuffixOf` when matching to take the cross prefix into account. Also add missing cross prefix to ghci wrapper content and fix hsc2hs wrapper logic. (cherry picked from commit edc02197b95488e8752c988e0e92ed6253c04b8c) - - - - - 508eb2db by Rodrigo Mesquita at 2024-10-30T17:00:58+05:30 determinism: Interface re-export list det In 'DocStructureItem' we want to make sure the 'Avails' are sorted, for interface file determinism. This commit introduces 'DetOrdAvails', a newtype that should only be constructed by sorting Avails with 'sortAvails' unless the avails are known to be deterministically ordered. This newtype is used by 'DocStructureItem' where 'Avails' was previously used to ensure the list of avails is deterministically sorted by construction. Note: Even though we order the constructors and avails in the interface file, the order of constructors in the haddock output is still determined from the order of declaration in the source. This was also true before, when the list of constructors in the interface file <docs> section was non-deterministic. Some haddock tests such as "ConstructorArgs" observe this (check the order of constructors in out/ConstructorArgs.html vs src/ConstructorArgs.hs vs its interface file) The updated tests are caused by haddock corners where the order in the source is not preserved (and was non-deterministic before this PR): * Module header in the latex backend * Re-export of pattern synonyms associated to a datatype (#25342) Fixes #25304 (cherry picked from commit b3f7fb80781bac756efdd7fdde836bf4742a75fc) - - - - - 16cb5517 by Rodrigo Mesquita at 2024-10-30T17:00:58+05:30 Revert "ci: Allow abi-test to fail." After #25304, the abi-test with interface and object determinism succeeds. This reverts commit 7b37afc9f3e79559055488998ee73187886a0e00. (cherry picked from commit e39c8c993c1da534c5893ca418d1fa4cbb9e0a0a) - - - - - 678794cd by Alan Zimmerman at 2024-10-30T17:01:12+05:30 EPA: reduce [AddEpann] in AnnList Remove it from the `al_rest` field, and make `AnnList` parameterized on a type to be used in `al_rest`, for the various use cases. (cherry picked from commit 7b1b0c6deab87bfc4d2b4ddfda40ed735c28cd53) - - - - - e66de62b by Rodrigo Mesquita at 2024-10-30T17:01:25+05:30 Fix -fobject-determinism flag definition The flag should be defined as an fflag to make sure the -fno-object-determinism flag is also an available option. Fixes #25397 (cherry picked from commit 4a00731eda964ec551f920b0319b24db2073687c) - - - - - f082e86e by Simon Peyton Jones at 2024-10-30T17:01:36+05:30 Fix optimisation of InstCo It turned out (#25387) that the fix to #15725 was not quite right: commit 48efbc04bd45d806c52376641e1a7ed7278d1ec7 Date: Mon Oct 15 10:25:02 2018 +0200 Fix #15725 with an extra Sym Optimising InstCo is quite subtle, and the invariants surrounding the LiftingContext in the coercion optimiser were not stated explicitly. This patch refactors the InstCo optimisation, and documents these invariants. See * Note [Optimising InstCo] * Note [The LiftingContext in optCoercion] I also did some refactoring of course: * Instead of a Bool swap-flag, I am not using GHC.Types.Basic.SwapFlag * I added some invariant-checking the coercion-construction functions in GHC.Core.Coercion.Opt. (Sadly these invariants don't hold during typechecking, becuase the types are un-zonked, so I can't put these checks in GHC.Core.Coercion.) (cherry picked from commit 23ddcc0102b3b0c31829a8f67003f4f00fb52f9a) - - - - - da4402b0 by Cheng Shao at 2024-10-30T17:02:27+05:30 testsuite: add T25414 test case marked as broken This commit adds T25414 test case to demonstrate #25414. It is marked as broken and will be fixed by the next commit. (cherry picked from commit b1eed26f10645e8d918402b7fc29b07e0b294757) - - - - - d5390862 by Hassan Al-Awwadi at 2024-10-31T17:13:29+05:30 Put RdrName in the foExt field of FieldOcc The main purpose of this commit is to rip RdrName out of FieldOcc, in accordance with #21592, and as a side note it has simplified the method we use to deal with ambiguity somewhat. To do the first, we make FieldOccs store (LIdP p) instead of always storing Located RdrName, and moved the readername to the extension points where necessary. For the second, well, we just turn an ambiguous RdrName into a unbound Name through mkUnboundName. Later during disambiguateRecordBinds of the type checking phase, we will try and do type-directed disambiguation based on the rdrName field (for now), so this hack works out fine. See Note [Ambiguous FieldOcc in record updates] for more details. There are two additional minor changes in this commit: * The HsRecSel constructor of HsExpr has been moved to the extension constuctors, since its really GHC specific. * HsProjection no longer has a Located DotFieldOcc as a field, but just a regular DotFieldOcc, since DotFieldOcc already wraps a located FieldLabelString co-authored by: @Jade <Jade512 at proton.me> @alt-romes <rodrigo.m.mesquita at gmail.com> (cherry picked from commit 1587cccfe7c3c1db3ccc48437b47ccb6ae215701) - - - - - c580b505 by Cheng Shao at 2024-10-31T17:13:29+05:30 driver: fix foreign stub handling logic in hscParsedDecls This patch fixes foreign stub handling logic in `hscParsedDecls`. Previously foreign stubs were simply ignored here, so any feature that involve foreign stubs would not work in ghci (e.g. CApiFFI). The patch reuses `generateByteCode` logic and eliminates a large chunk of duplicate logic that implements Core to bytecode generation pipeline here. Fixes #25414. (cherry picked from commit e70009bc5b388ed02db12ee7a99bca0e4c283c87) - - - - - 7202e2ac by Andrew Lelechenko at 2024-10-31T17:13:29+05:30 hadrian: allow -Wunused-imports for text package (cherry picked from commit 90746a591919fc51a0ec9dec58d8f1c8397040e3) - - - - - 4595620a by Andrew Lelechenko at 2024-10-31T17:13:29+05:30 Bump text submodule to 2.1.2 (cherry picked from commit 853050c386ff8634b950204edf4c7f8d973f9a89) - - - - - ccd4f869 by Zubin Duggal at 2024-10-31T17:13:29+05:30 configure: Set release version to 9.12.0 instead of 9.12. This means our alphas will be properly named. - - - - - ec2f40b4 by Zubin Duggal at 2024-10-31T17:13:29+05:30 Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) - - - - - d2a10e25 by Ben Gamari at 2024-10-31T17:13:29+05:30 Bump process submodule to v1.6.25.0 (cherry picked from commit 18f532f3ed021fff9529f50da2006b8a8d8b1df7) - - - - - c0eb35df by Zubin Duggal at 2024-10-31T17:13:29+05:30 testsuite: normalise execvp vs exec differences in process tests Fixes #25431 (cherry picked from commit a23d8e73166725b699af88a36e97c63b2a0ede25) - - - - - 8de7406f by Zubin Duggal at 2024-11-12T13:42:19+05:30 testsuite: allow metric increase for TcPlugin_RewritePerf this is an empty commit to allow this backports batch to be merged. Metric Increase: TcPlugin_RewritePerf - - - - - b1994328 by Alan Zimmerman at 2024-11-14T16:17:28+05:30 EPA: Remove AddEpann commit 7 EPA: Remove [AddEpAnn] from HYPHEN in Parser.y The return value is never used, as it is part of the backpack configuration parsing. EPA: Remove last [AddEpAnn] usages Remove residual usage in GHC. It is still used - In haddock TTG extension point definitions (to be removed) - Some check-exact residual, to be removed - Comments around DisambECP in PostProcess EPA: Clean up [AddEpAnn] from check-exact There is one left, to be cleaned up when we remove AddEpann itself EPA: Remove [AddEpAnn] from haddock The TTG extension points need a value, it is not critical what that value is, in most cases. EPA: Remove AddEpAnn from HsRuleAnn EPA: Remove AddEpAnn from HsCmdArrApp (cherry picked from commit dbc77ce804c0f410f3f2894a158d0ee899ce64f5) - - - - - 210b59c4 by Alan Zimmerman at 2024-11-14T16:17:37+05:30 EPA: Remove AddEpAnn Commit 8/final EPA: Remove AddEpAnn from AnnList EPA: Remove AddEpAnn from GrhsAnn This is the last actual use EPA: Remove NameAdornment from NameAnn Also rework AnnContext to use EpToken, and AnnParen EPA: Remove AddEpAnn. Final removal There are now none left, except for in a large note/comment in PostProcess, describing the historical transition to the disambiguation infrastructure (cherry picked from commit 8a6691c3a947a21c7dcc9772d6cc396894c4756f) - - - - - c43414d2 by Alan Zimmerman at 2024-11-14T16:17:49+05:30 EPA: Remove AnnKeywordId. This was used as part of AddEpAnn, and is no longer needed. Also remove all the haddock comments about which of are attached to the various parts of the AST. This is now clearly captured in the appropriate TTG extension points, and the `ExactPrint.hs` file. (cherry picked from commit d5e7990ca9637ebee2293b22815fa0c393231baf) - - - - - 43dd7718 by Alan Zimmerman at 2024-11-14T16:18:00+05:30 EPA: use explicit vertical bar token for ExplicitSum / SumPat (cherry picked from commit f859d61c4832b16ae3b4dd14aad5cb41b0051de3) - - - - - aa59a1ef by Alan Zimmerman at 2024-11-14T16:21:51+05:30 EPA: Bring in last EpToken usages For import declarations, NameAnnCommas and NPlusKPat. And remove anchor, it is the same as epaLocationRealSrcSpan. (cherry picked from commit 0bc94360908011167284ee4c283c343350cbba78) - - - - - 788ae992 by Alan Zimmerman at 2024-11-14T19:03:38+05:30 EPA: Capture location of '_' for wild card type binder And keep track of promotion status in HsExplicitTupleTy, so the round-trip ppr test works for it. Updates Haddock output too, using the PromotionFlag in HsExplicitTupleTy. Closes #25454 (cherry picked from commit 9ad9ac63abed33aa48d4df40142d2809bdfd1ff0) - - - - - 344bb0f3 by Alan Zimmerman at 2024-11-14T19:04:35+05:30 EPA: Correctly capture leading semis in decl list Closes #25467 (cherry picked from commit 0614abef967c2ee9fb83955f18460715160a557a) - - - - - 8662d966 by ur4t at 2024-11-14T19:05:02+05:30 GHCi: fix improper location of ghci_history file Fixes #24266 (cherry picked from commit 6f0a62db5dc79640433c61e83ea1427665304869) - - - - - 014126ba by Rodrigo Mesquita at 2024-11-14T19:05:43+05:30 Deprecation for WarnCompatUnqualifiedImports Fixes #25330 (cherry picked from commit 68e2da5a9ed2f0221b0b17a19032d909a1ea1037) - - - - - 3b7dc559 by Andreas Klebinger at 2024-11-14T19:06:05+05:30 Compile T25062 simd tests even if we can't run them. Helps avoid them being utterly broken. Fixes #25341 (cherry picked from commit 1c21e7d4358162342b707f20ae2765ad02affdf3) - - - - - 31a75a91 by Ben Gamari at 2024-11-14T19:06:21+05:30 rts/Disassembler: Fix encoding of BRK_FUN instruction The offset of the CC field was not updated after the encoding change in b85b11994e0130ff2401dd4bbdf52330e0bcf776. Fix this. Fixes #25374. (cherry picked from commit 721ac00d63216e5e6512baba09b6ebb3cc456ebf) - - - - - eccd1ef0 by Ben Gamari at 2024-11-14T19:06:44+05:30 configure: Check version number validity Here we verify the previously informal invariant that stable release version numbers must have three components, preventing costly failed releases. Specifically, the check fails in the following scenarios: * `version=9.13` while `RELEASE=YES` since this would imply a release made from an unstable branch * `version=9.13.0` since unstable versions should only have two components * `version=9.12` since this has the wrong number of version components for a stable branch Fixes #25390. (cherry picked from commit c02add17f04c0521f0cb97b4c8511b47f4b639d7) - - - - - 9d431ca7 by Teo Camarasu at 2024-11-14T19:07:03+05:30 docs: link to #14474 in the template-haskell docs (cherry picked from commit 747fd3224f9832a97367aaf7e6085a9b0a26fba9) - - - - - 29923e5f by Peter Trommler at 2024-11-14T19:07:33+05:30 PPC NCG: Implement fmin and fmax (cherry picked from commit fdd9f62ad3deb64dabef438032a1e8c89c98cd99) - - - - - c3fb73d2 by Sebastian Graf at 2024-11-14T19:07:47+05:30 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. (cherry picked from commit 00d58ae18a7ce8db6b2d57261a08ba8c1c2549b5) - - - - - 53d2a948 by Zubin Duggal at 2024-11-14T19:08:09+05:30 release: copy zip files into the correct directory Fixes #25446 (cherry picked from commit 346e4cd1903b2cbcc9bb7c39652666c513eb2a59) - - - - - c29445eb by Zubin Duggal at 2024-11-14T19:08:16+05:30 release: Sign .gz bindists too Fixes #25447 (cherry picked from commit bbdbe2254df1bfc9157cfb409afc93f8157712cd) - - - - - f5b5d1dc by Zubin Duggal at 2024-11-14T19:11:16+05:30 Bump exceptions submodule to 0.10.9 - - - - - ba786681 by Zubin Duggal at 2024-11-14T19:56:41+05:30 Bump file-io submodule to 0.1.4 - - - - - 3a7ffdbb by Zubin Duggal at 2024-11-14T19:56:41+05:30 bump os-string submodule to 2.0.6 - - - - - 53b46fd4 by Zubin Duggal at 2024-11-14T19:56:41+05:30 bump transformers submodule to 0.6.1.2 - - - - - 27dc2664 by Zubin Duggal at 2024-11-14T19:56:41+05:30 Bump directory submodule to v1.3.9.0 - - - - - 80df8808 by Zubin Duggal at 2024-11-14T19:56:41+05:30 Bump Win32 submodule to v2.14.1.0 - - - - - 29bfae2c by Zubin Duggal at 2024-11-14T19:56:41+05:30 Bump filepath submodule to 1.5.3.0 - - - - - 97b0dff2 by Zubin Duggal at 2024-11-14T23:00:10+05:30 Bump file-io submodule to avoid usage of QuasiQuotes - - - - - a1f56d6d by Zubin Duggal at 2024-11-26T16:36:33+05:30 Bump unix submodule to 2.8.6.0 - - - - - 348179be by Matthew Pickering at 2024-11-26T16:36:56+05:30 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> (cherry picked from commit 6e68b1177ea6fde381060268c377f67f6097877a) - - - - - 9d5f116c by Rodrigo Mesquita at 2024-11-26T16:38:55+05:30 exceptions: Improve the message layout as per #285 This commit fixes the layout of the additional information included when displaying an exception, namely the type of the exception. It also fixes the default handler's heading message to work well together with the improved display message of SomeException. CLC proposal#285 (cherry picked from commit a4e0d23596b45f27f5faad2363c77698abe900b1) - - - - - 39c9228c by Rodrigo Mesquita at 2024-11-26T16:39:07+05:30 Display type and callstack of exception on handler This commit changes the Exception instance of SomeException to *simply* display the underlying exception in `displayException`. The augmented exception message that included the type and backtrace of the exception are now only printed on a call to `displayExceptionWithInfo`. At a surface level, existing programs should behave the same since the `uncaughtExceptionHandler`, which is responsible for printing out uncaught exceptions to the user, will use `displayExceptionWithInfo` by default. However, unlike the instance's `displayException` method, the `uncaughtExceptionHandler` can be overriden with `setUncaughtExceptionHandler`. This makes the extra information opt-in without fixing it the instance, which can be valuable if your program wants to display uncaught exceptions to users in a user-facing way (ie without backtraces). This is what was originally agreed for CLC#231 or CLC#261 with regard to the type of the exception information. The call stack also becoming part of the default handler rather than the Exception instance is an ammendment to CLC#164. Discussion of the ammendment is part of CLC#285. (cherry picked from commit 284ffab334bcda838865ff4804bc04f9082d81b3) - - - - - 39ecdcb9 by Rodrigo Mesquita at 2024-11-26T16:39:37+05:30 Remove redundant CallStack from exceptions Before the exception backtraces proposal was implemented, ErrorCall accumulated its own callstack via HasCallStack constraints, but ExceptionContext is now accumulated automatically. The original ErrorCall mechanism is now redundant and we get a duplicate CallStack Updates Cabal submodule to fix their usage of ErrorCallWithLocation to ErrorCall CLC proposal#285 Fixes #25283 (cherry picked from commit 36cddd2ce1a3bc62ea8a1307d8bc6006d54109cf) - - - - - 5f7a6678 by Rodrigo Mesquita at 2024-11-26T16:39:48+05:30 Freeze call stack in error throwing functions CLC proposal#285 (cherry picked from commit 7a74330bf55a85573ed02298b92b7b3fc06f2fed) - - - - - 1848cfb0 by Rodrigo Mesquita at 2024-11-26T16:39:56+05:30 De-duplicate displayContext and displayExceptionContext The former was unused except for one module where it was essentially re-defining displayExceptionContext. Moreover, this commit extends the fix from bfe600f5bb3ecd2c8fa71c536c63d3c46984e3f8 to displayExceptionContext too, which was missing. (cherry picked from commit 3abf31a45ddbc80901baefdc6325fc3351c5deec) - - - - - 900aa787 by Rodrigo Mesquita at 2024-11-26T16:40:05+05:30 Re-export NoBacktrace from Control.Exception This was originally proposed and accepted in section "2.7 Capturing Backtraces on Exceptions" of the CLC proposal for exception backtraces. However, the implementation missed this re-export, which this commit now fixes. (cherry picked from commit c0d783f8a94ee6b72ff3c20e0a974cd09edd96ff) - - - - - b7337c54 by Rodrigo Mesquita at 2024-11-26T16:40:12+05:30 Fix exception backtraces from GHCi When running the program with `runhaskell`/`runghc` the backtrace should match the backtrace one would get by compiling and running the program. But currently, an exception thrown in a program interpreted with `runhaskell` will: * Not include the original exception backtrace at all * Include the backtrace from the internal GHCi/ghc rethrowing of the original exception This commit fixes this divergence by not annotating the ghc(i) backtrace (with NoBacktrace) and making sure that the backtrace of the original exception is serialized across the boundary and rethrown with the appropriate context. Fixes #25116 The !13301 MR (not this commit in particular) improves performance of MultiLayerModules. Unfortunately, T3294 regresses on aarch64-linux-deb12 by 1% allocations. Since this patch must be merged for 9.12 ASAP, we will not be able to investigate the slight regression on this platform in time. ------------------------- Metric Decrease: MultiLayerModulesRecomp MultiLayerModulesTH_OneShot Metric Increase: T3294 ------------------------- (cherry picked from commit 802b5c3e118dad9fcfbe61a3fa4d7bf4592356a8) - - - - - e92bfcb9 by Rodrigo Mesquita at 2024-11-26T16:40:25+05:30 base: Add to changelog.md CLC #285 (cherry picked from commit 3e89eb65895b4ea390d0fd2cd4f8bc688a602e34) - - - - - ab5867a9 by Zubin Duggal at 2024-11-26T16:42:52+05:30 Bump array and stm submodules for exception output changes - - - - - 7688daae by Rodrigo Mesquita at 2024-11-26T16:43:13+05:30 Re-introduce ErrorCallWithLocation with a deprecation pragma With the removal of the duplicate backtrace, part of CLC proposal #285, the constructor `ErrorCallWithLocation` was removed from base. This commit re-introduces it with a deprecation. (cherry picked from commit d1172e20f29e6fbf53fa95726492bdb998c52582) - - - - - df632282 by Brandon Chinn at 2024-11-26T16:43:29+05:30 Fix CRLF in multiline strings (#25375) (cherry picked from commit 7bd407a67cd7810d3ff1e6d18885555175383a35) - - - - - 5654b8ba by Matthew Pickering at 2024-11-26T16:43:57+05:30 ghc-internal: Update to Unicode 16 This patch updates the automatically generated code for querying unicode properties to unicode 16. Fixes #25402 (cherry picked from commit bfe64df85683d63ccfa438fed0999193b703d48c) - - - - - 0117fed6 by ARATA Mizuki at 2024-11-26T16:44:12+05:30 x86 NCG SIMD: Lower packFloatX4#, insertFloatX4# and broadcastFloatX4# to SSE1 instructions Fixes #25441 Co-authored-by: sheaf <sam.derbyshire at gmail.com> (cherry picked from commit a0e168ec0b6f18ffeddaf8a5dfc68e84563630b8) - - - - - 467f71c6 by Arnaud Spiwack at 2024-11-26T16:45:13+05:30 Add test for #25185 (cherry picked from commit 791a47b205f1d7cc04f27fc780905f8d4fa042fa) - - - - - eda04ebd by Arnaud Spiwack at 2024-11-26T16:46:10+05:30 Quick look: emit the multiplicity of app heads in tcValArgs Otherwise it's not scaled properly by the context, allowing unsound expressions. Fixes #25185. (cherry picked from commit 374e18e5e79125375a49432da939abbb36268c8a) - - - - - dbac8232 by sheaf at 2024-11-26T16:46:45+05:30 X86 NCG: allow VXOR at scalar floating-point types The NCG can emit VXOR instructions at scalar floating-point types, but the pretty-printer would panic instead of emitting the appropriate VXORPS/VXORPD instructions. This patch rectifies that oversight. Fixes #25455 (cherry picked from commit 3936bf1bc37c9f8ea662ed4b57a3a28b5a670c54) - - - - - df943652 by sheaf at 2024-11-26T16:46:58+05:30 Include diagnostic reason in -fdiagnostics-as-json This commit ensures that the -fdiagnostics-as-json output includes the diagnostic reason. This allows the full error message produced by GHC to be re-constructed from the JSON output. Fixes #25403 (cherry picked from commit 831aab2238e682e2977b4959afa100df928cec09) - - - - - ff7a27be by sheaf at 2024-11-26T16:47:12+05:30 x86 NCG: fix regUsageOfInstr for VMOVU & friends This commit fixes the implementation of 'regUsageOfInstr' for vector operations that take an 'Operand' as the destination, by ensuring that when the destination is an address then the address should be *READ*, and not *WRITTEN*. Getting this wrong is a disaster, as it means the register allocator has incorrect information, which can lead to it discard stores to registers, segfaults ensuing. Fixes #25486 (cherry picked from commit 1fc02399fcc82a222033919c8d3c5db4b382cb97) - - - - - 345ea654 by Cheng Shao at 2024-11-26T16:47:26+05:30 driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code This commit fixes an undefined symbol error in RTS linker when attempting to compile home modules with -fhpc and -fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for detailed description and analysis of the bug. Also adds T25510/T25510c regression tests to test make mode/oneshot mode of the bug. (cherry picked from commit bcbcdaaf2df58e3b7a2756d044c4169a724e03d9) - - - - - 2645523b by Andreas Klebinger at 2024-11-26T16:47:55+05:30 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 (cherry picked from commit 7f90f319531c312a074d21688b05f664f0d173fc) - - - - - 0121b76f by Zubin Duggal at 2024-11-26T18:00:38+05:30 Bump os-string submodule to 2.0.8 - - - - - 962ceb50 by Zubin Duggal at 2024-11-26T18:00:38+05:30 Bump file-io submodule to avoid usage of QuasiQuotes - - - - - 7bc6877f by Zubin Duggal at 2024-11-26T18:00:38+05:30 Bump filepath submodule to 1.5.4.0 - - - - - 90b49376 by Zubin Duggal at 2024-11-27T18:55:49+05:30 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. - - - - - 77f340a2 by Zubin Duggal at 2024-11-27T18:58:23+05:30 Fix ghc-e005 after HasCallstack changes - - - - - 9478b5ae by Zubin Duggal at 2024-11-27T19:02:38+05:30 Bump file-io submodule to 0.1.5 - - - - - 6fc1fa3b by Zubin Duggal at 2024-11-28T14:31:01+05:30 Bump ghc-prim and template-haskell versions - - - - - 5d938345 by Zubin Duggal at 2024-11-28T18:23:25+05:30 testsuite: Also match <VERSION> placeholders when normalising callsites (cherry picked from commit 2807f91bfb0b1e60ea8668622eae344e9ff5d840) - - - - - 83377584 by Ben Gamari at 2024-12-13T09:52:25+05:30 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. (cherry picked from commit 292ed74ea908b64490e91346b890cbebdcde37d0) - - - - - 194ad792 by Ben Gamari at 2024-12-13T09:53:38+05:30 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ (cherry picked from commit 952a1243a77ac73222659a49a642b20e80d77cdb) - - - - - f5ed23d9 by Ben Gamari at 2024-12-13T09:53:50+05:30 rts/linker: Clarify debug output (cherry picked from commit 20912f5bac6fe4146172accc1849d9b762eb45e3) - - - - - 051d8a37 by Ben Gamari at 2024-12-13T09:54:37+05:30 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. (cherry picked from commit a104508d2ea5bbc61c4a756dca42fc043b329709) - - - - - fa0348b8 by Cheng Shao at 2024-12-13T09:54:47+05:30 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. (cherry picked from commit 88c4fe1d8a3bdbedf3972fde12f663a974cc2191) - - - - - 563a3124 by Ben Gamari at 2024-12-13T09:54:56+05:30 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. (cherry picked from commit c3fc9b861fd00a85a4fcbd9960b8242d9fabe04b) - - - - - a9e0cfe7 by Ben Gamari at 2024-12-13T09:55:33+05:30 testsuite: Handle division-by-zero more gracefully Previously we would fail with an ZeroDivisionError. Fixes #25321 (cherry picked from commit 513775082b89deae3f83896031caf0e89a7ed333) - - - - - a2c033cf by Ben Gamari at 2024-12-13T09:55:33+05:30 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. (cherry picked from commit 7890f2d8526dd90584eaa181ab10bd30d90e6743) - - - - - 14d80de1 by Brandon Chinn at 2024-12-13T09:56:20+05:30 Fix panic in multiline string with unterminated gap (#25530) (cherry picked from commit a8ceccf397216f63d609c4f7471506773c98572f) - - - - - 4ae5ef94 by Brandon Chinn at 2024-12-13T09:56:29+05:30 Add test case for unterminated multiline string (cherry picked from commit 9e464ad01f5f60f774504fcaf8d0c30bdd291159) - - - - - 2feb717e by Matthew Pickering at 2024-12-13T09:56:47+05:30 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 (cherry picked from commit 13fe48d40004d9cdf3c73300a18f144bdc5191d9) - - - - - c0b36c68 by Ben Gamari at 2024-12-13T09:56:55+05:30 testsuite: Add test for #25560 (cherry picked from commit 683115a40fd989a287fa51efe140af9448526098) - - - - - 74e42943 by Ben Gamari at 2024-12-13T09:57:04+05:30 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. (cherry picked from commit e745e3a30670440c9cf65450835d4eddada784eb) - - - - - f8b36d9b by Ben Gamari at 2024-12-13T09:57:17+05:30 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. (cherry picked from commit 41dae5b86955094aa4c5647f63f1f52f1a8a5519) - - - - - ada12a20 by Ben Gamari at 2024-12-13T09:57:41+05:30 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. (cherry picked from commit 9efbc51f99118e8f9c3abf2bcb6dc3295893ded6) - - - - - f43b1d65 by Ben Gamari at 2024-12-13T09:57:53+05:30 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. (cherry picked from commit 34d3e8e69b62b92cc438514f7fb8e37ce639efea) - - - - - 5c9c3e3f by Zubin Duggal at 2024-12-13T10:00:58+05:30 Bump Cabal submodule to 3.14.1.0 - - - - - 89790626 by Zubin Duggal at 2024-12-13T10:16:14+05:30 Bump directory submodule to 0.12.2.0 - - - - - 9321f8b7 by Andreas Klebinger at 2024-12-13T10:24:04+05:30 Document -fmax-forced-spec-args=⟨n⟩ in the 9.12 changelog. Fixes #25544 (cherry picked from commit e2d2645c01d45149420bb07987b1634e577adc04) - - - - - 66d66a25 by Andreas Klebinger at 2024-12-13T10:25:30+05:30 Document -fwrite-if-compression in release notes. (cherry picked from commit 93335a250347ed0591d240701a56ff171a9a5561) - - - - - f29620c8 by Adam Gundry at 2024-12-13T10:27:57+05:30 Fix formatting issues and make corrections to 9.12.1 release notes (cherry picked from commit 6ce3e546083304c4f2da060184b3b73f48dd8fc0) - - - - - 15c719f3 by Zubin Duggal at 2024-12-13T16:59:48+05:30 Changelog fixes - - - - - dc86785e by Zubin Duggal at 2024-12-13T16:59:48+05:30 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore - - - - - fc647a65 by Ben Gamari at 2024-12-13T16:59:48+05:30 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. (cherry picked from commit 1e84b41108d96cb721dd11281105fdf621105a12) - - - - - cbfd0829 by Zubin Duggal at 2024-12-13T16:59:48+05:30 release: copy index.html from correct directory - - - - - 0ba478fe by Matthew Pickering at 2024-12-13T16:59:48+05:30 configure: Allow happy-2.0.2 happy-2.0.2 can be used to compile GHC. happy-2.0 and 2.0.1 have bugs which make it unsuitable to use. The version bound is now == 1.20.* || >= 2.0.2 && < 2.1 Fixes #25276 (cherry picked from commit 0029ca91c845dd4530eb2c4606ad5bd59775cec2) - - - - - 24b4914a by Cristiano Moraes at 2024-12-13T16:59:48+05:30 configure: Find C++ probing when GCC version is the latest but G++ is old #23118 (cherry picked from commit 78ad81ecef846f73fee0f6c1a86cd6f19aa29b21) - - - - - 95d35d6c by Ben Gamari at 2024-12-13T16:59:48+05:30 configure: Accept happy-2.1.2 happy-2.1 was released in late Oct 2024. I have confirmed that master bootstraps with it. Here we teach configure to accept this tool. Fixes #25438. (cherry picked from commit 1fd83f865ffb620f4f7c4c59787710206dcadb90) - - - - - 86f29950 by Ben Gamari at 2024-12-13T16:59:48+05:30 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. (cherry picked from commit 992259962191b0b774dfeeabb46729376c7fe7cf) - - - - - dde3796b by Zubin Duggal at 2024-12-13T23:41:56+05:30 hadrian-multi: warn on unused imports os-string has redundant imports - - - - - 52b58a66 by Zubin Duggal at 2024-12-13T23:41:56+05:30 ghcup metadata: output metadata fragment in CI - - - - - 39e4fed1 by Zubin Duggal at 2024-12-13T23:41:56+05:30 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit d83f5bd730a8aef37d8a38b3560590d9798f8e45) (cherry picked from commit 280b627869da55a22b4b9a3458e6115b06b5fff4) - - - - - e226fcf0 by Ben Gamari at 2024-12-14T14:47:47+05:30 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. (cherry picked from commit 55d8304e02000b3ec33d254794e84d159dc93926) - - - - - 227c86d4 by Ben Gamari at 2024-12-14T14:47:47+05:30 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 (cherry picked from commit 56b9f484fd89b5c2c69045dcd5690f68699ba0b1) - - - - - ce8458e9 by Ben Gamari at 2024-12-14T14:47:47+05:30 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 (cherry picked from commit 336d392e417203c492fec15ecf91dd444cb70936) - - - - - 65c1928d by Ben Gamari at 2024-12-14T14:47:47+05:30 base: Mention incorrect Data.Enum addition in changelog (cherry picked from commit dd7ca93903eba8c63261656ca3d245f9e8baa662) - - - - - 032b058c by Ben Gamari at 2024-12-15T21:21:51+05:30 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. (cherry picked from commit dfd1db48aaa1ee6c109e9a05ce34672418f17f59) - - - - - dc7c0f85 by Zubin Duggal at 2024-12-15T21:21:51+05:30 RELEASE=YES - - - - - daf659b6 by Zubin Duggal at 2024-12-15T21:28:10+05:30 ci: allow test-primops to fail as a workaround to #25582 - - - - - eb2859af by Ben Gamari at 2025-01-16T17:20:25-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - e7097cf5 by Ben Gamari at 2025-01-16T17:20:25-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - e6850133 by Ben Gamari at 2025-01-16T17:20:25-05:00 testsuite: Test shift correctness in mul2 test - - - - - 2a48b7b5 by Ben Gamari at 2025-01-16T17:20:25-05:00 testsuite: Add regression test for #25653 - - - - - f6aa9f65 by Ben Gamari at 2025-01-22T13:17:55-05:00 Cmm/Parser: Add surface syntax for Mul2 MachOps These are otherwise very hard to test in isolation. - - - - - 33a74ef5 by Ben Gamari at 2025-01-22T15:02:48-05:00 Add release notes for 9.12.2 - - - - - a6f47532 by Ben Gamari at 2025-01-22T15:02:59-05:00 configure: Set RELEASE=NO - - - - - 30 changed files: - .gitattributes - .gitlab-ci.yml - .gitlab/ci.sh - .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 - .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - CODEOWNERS - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/Format.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/RV64/CodeGen.hs - compiler/GHC/CmmToAsm/RV64/Instr.hs - compiler/GHC/CmmToAsm/RV64/Ppr.hs - compiler/GHC/CmmToAsm/Wasm.hs - compiler/GHC/CmmToAsm/Wasm/Asm.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7366808fcab007963d1b225912356fc27ab86208...a6f47532aa7c5e08f9d7549e72839b400d932cb8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7366808fcab007963d1b225912356fc27ab86208...a6f47532aa7c5e08f9d7549e72839b400d932cb8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 08:34:19 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 23 Jan 2025 03:34:19 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Break out GHC.Parser.Lexer.Interface Message-ID: <6791ff0b706bf_2545c224f7430875a1@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 64f8f046 by Brandon Chinn at 2025-01-23T03:34:01-05:00 Break out GHC.Parser.Lexer.Interface - - - - - aa8b9cb1 by Brandon Chinn at 2025-01-23T03:34:01-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - f1f702e5 by Brandon Chinn at 2025-01-23T03:34:02-05:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - b21c689b by Teo Camarasu at 2025-01-23T03:34:03-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 15 changed files: - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/ghc.cabal.in - docs/users_guide/conf.py - docs/users_guide/expected-undocumented-flags.txt - + docs/users_guide/exts/doandifthenelse.rst - docs/users_guide/exts/syntax.rst - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/parser/should_run/NumericUnderscores0.hs - testsuite/tests/parser/should_run/NumericUnderscores0.stdout - + testsuite/tests/parser/should_run/T25609.hs - + testsuite/tests/parser/should_run/T25609.stdout - testsuite/tests/parser/should_run/all.T Changes: ===================================== compiler/GHC/Parser/HaddockLex.x ===================================== @@ -8,6 +8,7 @@ import GHC.Prelude import GHC.Data.FastString import GHC.Hs.Doc import GHC.Parser.Lexer +import GHC.Parser.Lexer.Interface (adjustChar) import GHC.Parser.Annotation import GHC.Types.SrcLoc import GHC.Types.SourceText ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -78,7 +79,6 @@ module GHC.Parser.Lexer ( commentToAnnotation, HdkComment(..), warnopt, - adjustChar, addPsMessage ) where @@ -132,6 +132,8 @@ import GHC.Driver.Flags import GHC.Parser.Errors.Basic import GHC.Parser.Errors.Types import GHC.Parser.Errors.Ppr () +import GHC.Parser.Lexer.Interface +import qualified GHC.Parser.Lexer.String as Lexer.String import GHC.Parser.String } @@ -622,13 +624,6 @@ $unigraphic / { isSmartQuote } { smart_quote_error } \" @stringchar* $unigraphic / { isSmartQuote } { smart_quote_error } } - { - -- Parse as much of the multiline string as possible, except for quotes - @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { tok_string_multi_content } - -- Allow bare quotes if it's not a triple quote - (\" | \"\") / ([\n .] # \") { tok_string_multi_content } -} - <0> { \'\' { token ITtyQuote } @@ -2171,11 +2166,23 @@ tok_string span buf len _buf2 = do src = SourceText $ lexemeToFastString buf len endsInHash = currentChar (offsetBytes (len - 1) buf) == '#' --- | Ideally, we would define this completely with Alex syntax, like normal strings. --- Instead, this is defined as a hybrid solution by manually invoking lex states, which --- we're doing for two reasons: --- 1. The multiline string should all be one lexical token, not multiple --- 2. We need to allow bare quotes, which can't be done with one regex +{- Note [Lexing multiline strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ideally, we would lex multiline strings completely with Alex syntax, like +normal strings. However, we can't because: + + 1. The multiline string should all be one lexical token, not multiple + 2. We need to allow bare quotes, which can't be done with one regex + +Instead, we'll lex them with a hybrid solution in tok_string_multi by manually +invoking lex states. This allows us to get the performance of native Alex +syntax as much as possible, and just gluing the pieces together outside of +Alex. + +Implemented in string_multi_content in GHC/Parser/Lexer/String.x +-} + +-- | See Note [Lexing multiline strings] tok_string_multi :: Action tok_string_multi startSpan startBuf _len _buf2 = do -- advance to the end of the multiline string @@ -2201,17 +2208,14 @@ tok_string_multi startSpan startBuf _len _buf2 = do pure $ L span $ ITstringMulti src (mkFastString s) where goContent i0 = - case alexScan i0 string_multi_content of - AlexToken i1 len _ + case Lexer.String.alexScan i0 Lexer.String.string_multi_content of + Lexer.String.AlexToken i1 len _ | Just i2 <- lexDelim i1 -> pure (i1, i2) | isEOF i1 -> checkSmartQuotes >> setInput i1 >> lexError LexError - -- is the next token a tab character? - -- need this explicitly because there's a global rule matching $tab - | Just ('\t', _) <- alexGetChar' i1 -> setInput i1 >> lexError LexError -- Can happen if no patterns match, e.g. an unterminated gap | len == 0 -> setInput i1 >> lexError LexError | otherwise -> goContent i1 - AlexSkip i1 _ -> goContent i1 + Lexer.String.AlexSkip i1 _ -> goContent i1 _ -> setInput i0 >> lexError LexError lexDelim = @@ -2235,11 +2239,6 @@ tok_string_multi startSpan startBuf _len _buf2 = do Just (c, loc) -> throwSmartQuoteError c loc Nothing -> pure () --- | Dummy action that should never be called. Should only be used in lex states --- that are manually lexed in tok_string_multi. -tok_string_multi_content :: Action -tok_string_multi_content = panic "tok_string_multi_content unexpectedly invoked" - lex_chars :: (String, String) -> PsSpan -> StringBuffer -> Int -> P String lex_chars (startDelim, endDelim) span buf len = either (throwStringLexError i0) pure $ @@ -2591,105 +2590,6 @@ getLastLocIncludingComments = P $ \s@(PState { prev_loc = prev_loc }) -> POk s p getLastLoc :: P PsSpan getLastLoc = P $ \s@(PState { last_loc = last_loc }) -> POk s last_loc -data AlexInput = AI !PsLoc !StringBuffer deriving (Show) - -{- -Note [Unicode in Alex] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Although newer versions of Alex support unicode, this grammar is processed with -the old style '--latin1' behaviour. This means that when implementing the -functions - - alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) - alexInputPrevChar :: AlexInput -> Char - -which Alex uses to take apart our 'AlexInput', we must - - * return a latin1 character in the 'Word8' that 'alexGetByte' expects - * return a latin1 character in 'alexInputPrevChar'. - -We handle this in 'adjustChar' by squishing entire classes of unicode -characters into single bytes. --} - -{-# INLINE adjustChar #-} -adjustChar :: Char -> Word8 -adjustChar c = adj_c - where non_graphic = 0x00 - upper = 0x01 - lower = 0x02 - digit = 0x03 - symbol = 0x04 - space = 0x05 - other_graphic = 0x06 - uniidchar = 0x07 - - adj_c - | c <= '\x07' = non_graphic - | c <= '\x7f' = fromIntegral (ord c) - -- Alex doesn't handle Unicode, so when Unicode - -- character is encountered we output these values - -- with the actual character value hidden in the state. - | otherwise = - -- NB: The logic behind these definitions is also reflected - -- in "GHC.Utils.Lexeme" - -- Any changes here should likely be reflected there. - - case generalCategory c of - UppercaseLetter -> upper - LowercaseLetter -> lower - TitlecaseLetter -> upper - ModifierLetter -> uniidchar -- see #10196 - OtherLetter -> lower -- see #1103 - NonSpacingMark -> uniidchar -- see #7650 - SpacingCombiningMark -> other_graphic - EnclosingMark -> other_graphic - DecimalNumber -> digit - LetterNumber -> digit - OtherNumber -> digit -- see #4373 - ConnectorPunctuation -> symbol - DashPunctuation -> symbol - OpenPunctuation -> other_graphic - ClosePunctuation -> other_graphic - InitialQuote -> other_graphic - FinalQuote -> other_graphic - OtherPunctuation -> symbol - MathSymbol -> symbol - CurrencySymbol -> symbol - ModifierSymbol -> symbol - OtherSymbol -> symbol - Space -> space - _other -> non_graphic - --- Getting the previous 'Char' isn't enough here - we need to convert it into --- the same format that 'alexGetByte' would have produced. --- --- See Note [Unicode in Alex] and #13986. -alexInputPrevChar :: AlexInput -> Char -alexInputPrevChar (AI _ buf) = unsafeChr (fromIntegral (adjustChar pc)) - where pc = prevChar buf '\n' - -unsafeChr :: Int -> Char -unsafeChr (I# c) = GHC.Exts.C# (GHC.Exts.chr# c) - --- backwards compatibility for Alex 2.x -alexGetChar :: AlexInput -> Maybe (Char,AlexInput) -alexGetChar inp = case alexGetByte inp of - Nothing -> Nothing - Just (b,i) -> c `seq` Just (c,i) - where c = unsafeChr $ fromIntegral b - --- See Note [Unicode in Alex] -alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) -alexGetByte (AI loc s) - | atEnd s = Nothing - | otherwise = byte `seq` loc' `seq` s' `seq` - --trace (show (ord c)) $ - Just (byte, (AI loc' s')) - where (c,s') = nextChar s - loc' = advancePsLoc loc c - byte = adjustChar c - {-# INLINE alexGetChar' #-} -- This version does not squash unicode characters, it is used when -- lexing strings. @@ -3467,10 +3367,13 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. +-- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} +#endif lexToken :: P (PsLocated Token) lexToken = do ===================================== compiler/GHC/Parser/Lexer/Interface.hs ===================================== @@ -0,0 +1,124 @@ +{-# LANGUAGE MagicHash #-} + +{- | +This module defines the types and functions necessary for an Alex-generated +lexer. + +https://haskell-alex.readthedocs.io/en/latest/api.html# +-} +module GHC.Parser.Lexer.Interface ( + AlexInput (..), + alexGetByte, + alexInputPrevChar, + + -- * Helpers + alexGetChar, + adjustChar, +) where + +import GHC.Prelude + +import Data.Char (GeneralCategory (..), generalCategory, ord) +import Data.Word (Word8) +import GHC.Data.StringBuffer (StringBuffer, atEnd, nextChar, prevChar) +import GHC.Exts +import GHC.Types.SrcLoc (PsLoc, advancePsLoc) + +data AlexInput = AI !PsLoc !StringBuffer deriving (Show) + +-- See Note [Unicode in Alex] +alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) +alexGetByte (AI loc s) + | atEnd s = Nothing + | otherwise = byte `seq` loc' `seq` s' `seq` + --trace (show (ord c)) $ + Just (byte, (AI loc' s')) + where (c,s') = nextChar s + loc' = advancePsLoc loc c + byte = adjustChar c + +-- Getting the previous 'Char' isn't enough here - we need to convert it into +-- the same format that 'alexGetByte' would have produced. +-- +-- See Note [Unicode in Alex] and #13986. +alexInputPrevChar :: AlexInput -> Char +alexInputPrevChar (AI _ buf) = unsafeChr (fromIntegral (adjustChar pc)) + where pc = prevChar buf '\n' + +-- backwards compatibility for Alex 2.x +alexGetChar :: AlexInput -> Maybe (Char,AlexInput) +alexGetChar inp = case alexGetByte inp of + Nothing -> Nothing + Just (b,i) -> c `seq` Just (c,i) + where c = unsafeChr $ fromIntegral b + +unsafeChr :: Int -> Char +unsafeChr (I# c) = GHC.Exts.C# (GHC.Exts.chr# c) + +{- +Note [Unicode in Alex] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Although newer versions of Alex support unicode, this grammar is processed with +the old style '--latin1' behaviour. This means that when implementing the +functions + + alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) + alexInputPrevChar :: AlexInput -> Char + +which Alex uses to take apart our 'AlexInput', we must + + * return a latin1 character in the 'Word8' that 'alexGetByte' expects + * return a latin1 character in 'alexInputPrevChar'. + +We handle this in 'adjustChar' by squishing entire classes of unicode +characters into single bytes. +-} + +{-# INLINE adjustChar #-} +adjustChar :: Char -> Word8 +adjustChar c = adj_c + where non_graphic = 0x00 + upper = 0x01 + lower = 0x02 + digit = 0x03 + symbol = 0x04 + space = 0x05 + other_graphic = 0x06 + uniidchar = 0x07 + + adj_c + | c <= '\x07' = non_graphic + | c <= '\x7f' = fromIntegral (ord c) + -- Alex doesn't handle Unicode, so when Unicode + -- character is encountered we output these values + -- with the actual character value hidden in the state. + | otherwise = + -- NB: The logic behind these definitions is also reflected + -- in "GHC.Utils.Lexeme" + -- Any changes here should likely be reflected there. + + case generalCategory c of + UppercaseLetter -> upper + LowercaseLetter -> lower + TitlecaseLetter -> upper + ModifierLetter -> uniidchar -- see #10196 + OtherLetter -> lower -- see #1103 + NonSpacingMark -> uniidchar -- see #7650 + SpacingCombiningMark -> other_graphic + EnclosingMark -> other_graphic + DecimalNumber -> digit + LetterNumber -> digit + OtherNumber -> digit -- see #4373 + ConnectorPunctuation -> symbol + DashPunctuation -> symbol + OpenPunctuation -> other_graphic + ClosePunctuation -> other_graphic + InitialQuote -> other_graphic + FinalQuote -> other_graphic + OtherPunctuation -> symbol + MathSymbol -> symbol + CurrencySymbol -> symbol + ModifierSymbol -> symbol + OtherSymbol -> symbol + Space -> space + _other -> non_graphic ===================================== compiler/GHC/Parser/Lexer/String.x ===================================== @@ -0,0 +1,96 @@ +{ +{- | +This module defines lex states for strings. + +This needs to be separate from the normal lexer because the normal lexer +automatically includes rules like skipping whitespace or lexing comments, +which we don't want in these contexts. +-} +module GHC.Parser.Lexer.String ( + AlexReturn (..), + alexScan, + string_multi_content, +) where + +import GHC.Prelude + +import GHC.Parser.Lexer.Interface +import GHC.Utils.Panic (panic) +} + +-- ----------------------------------------------------------------------------- +-- Alex "Character set macros" +-- Copied from GHC/Parser/Lexer.x + +$unispace = \x05 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$nl = [\n\r\f] +$space = [\ $unispace] +$whitechar = [$nl \v $space] +$tab = \t + +$ascdigit = 0-9 +$unidigit = \x03 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$decdigit = $ascdigit -- exactly $ascdigit, no more no less. +$digit = [$ascdigit $unidigit] + +$special = [\(\)\,\;\[\]\`\{\}] +$ascsymbol = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~\:] +$unisymbol = \x04 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$symbol = [$ascsymbol $unisymbol] # [$special \_\"\'] + +$unilarge = \x01 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$asclarge = [A-Z] +$large = [$asclarge $unilarge] + +$unismall = \x02 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$ascsmall = [a-z] +$small = [$ascsmall $unismall \_] + +$uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$idchar = [$small $large $digit $uniidchar \'] + +$unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] +$charesc = [a b f n r t v \\ \" \' \&] + +$octit = 0-7 +$hexit = [$decdigit A-F a-f] + +-- ----------------------------------------------------------------------------- +-- Alex "Regular expression macros" +-- Copied from GHC/Parser/Lexer.x + + at numspc = _* -- numeric spacer (#14473) + at decimal = $decdigit(@numspc $decdigit)* + at octal = $octit(@numspc $octit)* + at hexadecimal = $hexit(@numspc $hexit)* + at gap = \\ $whitechar+ \\ + at cntrl = $asclarge | \@ | \[ | \\ | \] | \^ | \_ + at ascii = \^ @cntrl | "NUL" | "SOH" | "STX" | "ETX" | "EOT" | "ENQ" | "ACK" + | "BEL" | "BS" | "HT" | "LF" | "VT" | "FF" | "CR" | "SO" | "SI" | "DLE" + | "DC1" | "DC2" | "DC3" | "DC4" | "NAK" | "SYN" | "ETB" | "CAN" + | "EM" | "SUB" | "ESC" | "FS" | "GS" | "RS" | "US" | "SP" | "DEL" + at escape = \\ ( $charesc | @ascii | @decimal | o @octal | x @hexadecimal ) + at stringchar = ($graphic # [\\ \"]) | $space | @escape | @gap + +:- + +-- Define an empty rule so it compiles; callers should always explicitly specify a startcode +<0> () ; + +-- See Note [Lexing multiline strings] + { + -- Parse as much of the multiline string as possible, except for quotes + @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { string_multi_content_action } + -- Allow bare quotes if it's not a triple quote + (\" | \"\") / ([\n .] # \") { string_multi_content_action } +} + +-- ----------------------------------------------------------------------------- +-- Haskell actions +{ +-- | Dummy action that should never be called. Should only be used in lex states +-- that are manually lexed in tok_string_multi. +string_multi_content_action :: a +string_multi_content_action = panic "string_multi_content_action unexpectedly invoked" +} ===================================== compiler/ghc.cabal.in ===================================== @@ -646,6 +646,8 @@ Library GHC.Parser.Errors.Types GHC.Parser.Header GHC.Parser.Lexer + GHC.Parser.Lexer.Interface + GHC.Parser.Lexer.String GHC.Parser.HaddockLex GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock ===================================== docs/users_guide/conf.py ===================================== @@ -36,7 +36,6 @@ nitpick_ignore = [ ("c:type", "bool"), - ("extension", "DoAndIfThenElse"), ("extension", "RelaxedPolyRec"), ] ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -7,7 +7,6 @@ -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional -XAutoDeriveTypeable --XDoAndIfThenElse -XDoRec -XJavaScriptFFI -XParallelArrays ===================================== docs/users_guide/exts/doandifthenelse.rst ===================================== @@ -0,0 +1,30 @@ +.. _doandifthenelse: + +Do And If Then Else +============ + +.. extension:: DoAndIfThenElse + :shortdesc: Allow semicolons in ``if`` expressions. + + :since: 7.0.1 + + :status: Included in :extension:`Haskell2010` + + Allow semicolons in ``if`` expressions. + +Normally, a conditional is written like this: ``if cond then expr1 else expr2``. With the extension +:extension:`DoAndIfThenElse`, semicolons are allowed before the ``then`` and also before the ``else``, allowing +``if cond; then expr1; else expr2``. (You can also include either semicolon on its own.) + +Allowing semicolons in the middle of a conditional is useful in connection with layout-controlled +blocks, like ``do``\ -blocks. This is because GHC invisibly inserts a semicolon between each line of a +layout-controlled block. Accordingly, with :extension:`DoAndIfThenElse`, we can write code like this :: + + f mb x y = do + b <- mb + if b + then x + else y + +Without :extension:`DoAndIfThenElse`, the ``then`` and ``else`` lines would have to be indented with respect +to the rest of the lines in the ``do``\ -block. ===================================== docs/users_guide/exts/syntax.rst ===================================== @@ -20,6 +20,7 @@ Syntax lambda_case empty_case multiway_if + doandifthenelse local_fixity_decls block_arguments typed_holes ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -127,6 +127,8 @@ GHC.Parser.Errors.Ppr GHC.Parser.Errors.Types GHC.Parser.HaddockLex GHC.Parser.Lexer +GHC.Parser.Lexer.Interface +GHC.Parser.Lexer.String GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock GHC.Parser.String ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.hs ===================================== @@ -99,3 +99,6 @@ main = do 0x_ff == 0xff, 0x__ff == 0xff ] + + -- ensure that strings are unaffected + print ["\o16_000", "\16_000", "\x16_000"] ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.stdout ===================================== @@ -11,3 +11,4 @@ [True,True,True] [True,True,True] [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] +["\SO_000","\DLE_000","\SYN_000"] ===================================== testsuite/tests/parser/should_run/T25609.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE MultilineStrings #-} + +main :: IO () +main = do + -- strings with comment tokens + print """{- asdf -}""" + print """a {- asdf -} b""" + print """-- asdf""" + print """{-""" + + -- strings with haddock comments + print """{- | test -}""" + print """{- * test -}""" + print """{- ^ test -}""" + print """{- $ test -}""" + print """-- | test""" + print """-- * test""" + print """-- ^ test""" + print """-- $ test""" + + -- strings with only whitespace + print """ """ + print """ + + + """ + + -- strings with unicode + print """ + ★ + ★ + ★ + ★ + """ ===================================== testsuite/tests/parser/should_run/T25609.stdout ===================================== @@ -0,0 +1,15 @@ +"{- asdf -}" +"a {- asdf -} b" +"-- asdf" +"{-" +"{- | test -}" +"{- * test -}" +"{- ^ test -}" +"{- $ test -}" +"-- | test" +"-- * test" +"-- ^ test" +"-- $ test" +" " +"\n" +" \9733\n\9733\n \9733\n\9733" ===================================== testsuite/tests/parser/should_run/all.T ===================================== @@ -21,6 +21,9 @@ test('RecordDotSyntax3', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compil test('RecordDotSyntax4', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compile_and_run, ['RecordDotSyntax4', '']) test('RecordDotSyntax5', normal, compile_and_run, ['']) test('ListTuplePunsConstraints', extra_files(['ListTuplePunsConstraints.hs']), ghci_script, ['ListTuplePunsConstraints.script']) + +# Multiline strings test('MultilineStrings', normal, compile_and_run, ['']) test('MultilineStringsOverloaded', normal, compile_and_run, ['']) test('T25375', normal, compile_and_run, ['']) +test('T25609', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65820de995bb712e6bace917115c8ed9448caa0c...b21c689b4a257db011c6ddbe5c2c72db8fa375c1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65820de995bb712e6bace917115c8ed9448caa0c...b21c689b4a257db011c6ddbe5c2c72db8fa375c1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 11:29:56 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 06:29:56 -0500 Subject: [Git][ghc/ghc][wip/T18462] Add documentation Message-ID: <67922834ea752_30c37b13786b476966@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: be8b6857 by Sjoerd Visscher at 2025-01-23T12:29:47+01:00 Add documentation - - - - - 5 changed files: - compiler/GHC/Core/Rules.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/Language/Haskell/Syntax/Type.hs - libraries/ghc-internal/src/GHC/Internal/TypeError.hs Changes: ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -1282,7 +1282,7 @@ Two wrinkles: f (\(MkT @b (d::Num b) (x::b)) -> h @b d x) = ... where the HOP is (h @b d x). In principle this might be possible, but it seems fragile; e.g. we would still need to insist that the (invisible) - @b was a type variable. And since `h` gets a polymoprhic type, that + @b was a type variable. And since `h` gets a polymorphic type, that type would have to be declared by the programmer. Maybe one day. But for now, we insist (in `arg_as_lcl_var`)that a HOP ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -488,6 +488,11 @@ type instance XXType GhcPs = HsTypeGhcPsExt GhcPs type instance XXType GhcRn = HsCoreTy type instance XXType GhcTc = DataConCantHappen +type instance XNumTy (GhcPass _) = SourceText +type instance XStrTy (GhcPass _) = SourceText +type instance XCharTy (GhcPass _) = SourceText +type instance XXTyLit (GhcPass _) = DataConCantHappen + -- An escape hatch for tunnelling a Core 'Type' through 'HsType'. -- For more details on how this works, see: -- @@ -496,19 +501,27 @@ type instance XXType GhcTc = DataConCantHappen -- * @Note [Typechecking HsCoreTys]@ in "GHC.Tc.Gen.HsType" type HsCoreTy = Type -type instance XNumTy (GhcPass _) = SourceText -type instance XStrTy (GhcPass _) = SourceText -type instance XCharTy (GhcPass _) = SourceText -type instance XXTyLit (GhcPass _) = DataConCantHappen - data HsTypeGhcPsExt pass = HsCoreTy HsCoreTy | HsBangTy (XBangTy pass) -- Contains the SourceText in GHC passes. - HsBang (LHsType pass) -- Bang-style type annotations + HsBang (LHsType pass) -- See Note [Parsing data type declarations] | HsRecTy (XRecTy pass) - [LConDeclField pass] -- Only in data type declarations + [LConDeclField pass] -- See Note [Parsing data type declarations] + +{- Note [Parsing data type declarations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When parsing it is not always clear if we're parsing a constructor field type +or not. So during parsing we extend the type syntax to support bang annotations +and record braces. Once parsing is done these extensions are removed and +the data is stored in the HsConFieldSpec. It is an error if it turns out +the extensions were used outside of a constructor field type. + +Conversely it is convenient to have these extensions when generating +documentation with Haddock. So in Haddock the type syntax is extended again +from the data in HsConFieldSpec. +-} data EpLinearArrow = EpPct1 !(EpToken "%1") !(TokRarrow) @@ -548,6 +561,7 @@ multAnnToHsType = expandHsMultAnnOn (HsTyVar noAnn NotPromoted) -- | Convert an multiplicity annotation into its corresponding multiplicity. -- In essence this erases the information of whether the programmer wrote an explicit -- multiplicity or a shorthand. +-- In this polymorphic function, `t` can be `HsType` or `HsExpr` expandHsMultAnnOn :: (LocatedN Name -> t GhcRn) -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn -> LocatedA (t GhcRn) expandHsMultAnnOn mk_var (HsUnannotated HsUnannOne _) = noLocA (mk_var (noLocA oneDataConName)) expandHsMultAnnOn mk_var (HsUnannotated HsUnannMany _) = noLocA (mk_var (noLocA manyDataConName)) ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -851,7 +851,7 @@ everything to be in terms of b, while k does none of that. This is ridiculous, but I (Richard E) don't see a good fix. Shortcoming 2. Removing a redundant constraint can cause clients to fail to -compile, by making the function more polymoprhic. Consider (#16154) +compile, by making the function more polymorphic. Consider (#16154) f :: (a ~ Bool) => a -> Int f x = 3 ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -1084,6 +1084,24 @@ data ConDeclField pass cd_fld_spec :: HsConFieldSpec OnRecField pass } | XConDeclField !(XXConDeclField pass) +{- Note [ConDeclField pass] +~~~~~~~~~~~~~~~~~~~~~~~~~ +A ConDeclField contains a list of field occurrences: these always +include the field label as the user wrote it. After the renamer, it +will additionally contain the identity of the selector function in the +second component. + +Due to DuplicateRecordFields, the OccName of the selector function +may have been mangled, which is why we keep the original field label +separately. For example, when DuplicateRecordFields is enabled + + data T = MkT { x :: Int } + +gives + + ConDeclField { cd_fld_names = [L _ (FieldOcc "x" $sel:x:MkT)], ... }. +-} + -- | Describes the arguments to a data constructor. This is a common -- representation for several constructor-related concepts, including: -- @@ -1111,35 +1129,51 @@ data HsConDetails tyarg arg rec noTypeArgs :: [Void] noTypeArgs = [] +-- | Constructor field specification, see Note [HsConFieldSpec on pass] data HsConFieldSpec on pass = CFS { cfs_ext :: XConFieldSpec pass + -- ^ Extension point + , cfs_unpack :: SrcUnpackedness + -- ^ UNPACK pragma if any + -- E.g. data T = MkT {-# UNPACK #-} Int + , cfs_bang :: SrcStrictness + -- ^ User-specified strictness, if any + -- E.g. data T a = MkT !a + , cfs_multiplicity :: HsMultAnnOn on (LHsType pass) pass + -- ^ User-specified multiplicity, if any + -- E.g. data T a = MkT { t %Many :: a } + -- or data T a where MtT :: a %1 -> T a + , cfs_type :: LHsType pass - , cfs_doc :: Maybe (LHsDoc pass) } + -- ^ The type of the field + + , cfs_doc :: Maybe (LHsDoc pass) + -- ^ Documentation for the field + -- F.e. this very piece of documentation + } hsConFieldSpecGeneralize :: HsConFieldSpec on pass -> HsConFieldSpec on1 pass hsConFieldSpecGeneralize = unsafeCoerce -{- -Note [ConDeclField pass] -~~~~~~~~~~~~~~~~~~~~~~~~~ - -A ConDeclField contains a list of field occurrences: these always -include the field label as the user wrote it. After the renamer, it -will additionally contain the identity of the selector function in the -second component. - -Due to DuplicateRecordFields, the OccName of the selector function -may have been mangled, which is why we keep the original field label -separately. For example, when DuplicateRecordFields is enabled - - data T = MkT { x :: Int } - -gives - - ConDeclField { cd_fld_names = [L _ (FieldOcc "x" $sel:x:MkT)], ... }. +{- Note [HsConFieldSpec on pass] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +`HsConFieldSpec` is used to specify the type of a data single constructor argument for all of: +* Haskell-98 style declarations (with prefix, infix or record syntax) + e.g. data T1 a = MkT (Maybe a) !Int +* GADT-style declarations with arrow syntax + e.g. data T2 a where MkT :: Maybe a -> !Int -> T2 a +* GADT-style declarations with record syntax + e.g. data T3 a where MkT :: { x :: Maybe a, y :: !Int } -> T3 a + +These argument types are decorated with any user-defined + a) UNPACK pragma `cfs_unpack` + b) strictness annotation `cfs_bang` + c) multiplicity annotation `cfs_multiplicity` + In the case of Haskell-98 style declarations, this only applies to record syntax. + d) documentation `cfs_doc` -} ----------------------- ===================================== libraries/ghc-internal/src/GHC/Internal/TypeError.hs ===================================== @@ -162,7 +162,7 @@ Note [The Unsatisfiable representation-polymorphism trick] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The class method `unsatisfiableLifted :: forall (a::Type). Unsatisfiable msg => a` works only for lifted types `a`. What if we want an unsatisfiable value of type -`Int#`, say? The function `unsatisfiable` has a representation-polymoprhic type +`Int#`, say? The function `unsatisfiable` has a representation-polymorphic type unsatisfiable :: forall {rep} (msg :: ErrorMessage) (b :: TYPE rep). Unsatisfiable msg => b and yet is defined in terms of `unsatisfiableLifted`. How? By instantiating View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be8b685781e859303aebc6572398ab5b8187543a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/be8b685781e859303aebc6572398ab5b8187543a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 11:36:21 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 06:36:21 -0500 Subject: [Git][ghc/ghc][wip/T18462] 36 commits: warnings: Find out if a qualified name is in the interactive scope directly Message-ID: <679229b589327_30c37b14c194477449@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - c8f73b5f by Sjoerd Visscher at 2025-01-23T12:33:13+01:00 Multiplicity annotation on records - - - - - 3a78c48a by Sjoerd Visscher at 2025-01-23T12:34:09+01:00 Add HsConFieldSpec - - - - - 23d879a1 by Sjoerd Visscher at 2025-01-23T12:34:58+01:00 Restrict XBangTy and XRectTy to GhcPs phase - - - - - 4678db17 by Sjoerd Visscher at 2025-01-23T12:35:45+01:00 Showing error message regressions - - - - - bc5e8b2b by Sjoerd Visscher at 2025-01-23T12:36:11+01:00 Add doc field to CFS - - - - - 1f8df70e by Sjoerd Visscher at 2025-01-23T12:36:11+01:00 Add documentation - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Ppr.hs - compiler/GHC/Driver/Session.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be8b685781e859303aebc6572398ab5b8187543a...1f8df70e452568b53f891944f4d328b977d82d8b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be8b685781e859303aebc6572398ab5b8187543a...1f8df70e452568b53f891944f4d328b977d82d8b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 11:48:01 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 23 Jan 2025 06:48:01 -0500 Subject: [Git][ghc/ghc][wip/T24359] Moving towards the new plan [skip ci] Message-ID: <67922c71ba892_30c37b17011c8779af@gitlab.mail> Simon Peyton Jones pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 32e0aa05 by Simon Peyton Jones at 2025-01-23T11:47:35+00:00 Moving towards the new plan [skip ci] ... as discussed between Simon and Sam - - - - - 6 changed files: - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Solve.hs Changes: ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -952,22 +952,28 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- Simplify the constraints - ; ev_binds_var <- newTcEvBinds - ; wanted <- setTcLevel rhs_tclvl $ - runTcSWithEvBinds ev_binds_var $ - solveWanteds wanted + -- Simplify the constraints enough to perform unificaitons + ; wanted_clone <- cloneWC wanted + ; _ <- setTcLevel rhs_tclvl $ + runTcS $ + solveWanteds wanted_clone + ; wanted <- liftZonkM $ zonkWC wanted -- Quantify over the the constraints - ; qevs <- mapM newEvVar $ - ctsPreds $ - approximateWC False wanted + ; (quant_cts, residual_wanted) <- getRuleQuantCts wanted + ; let qevs = map ctEvId (bagToList quant_cts) + -- Wrap the call in bindings for any other constraints + ; ev_binds_var1 <- newTcEvBinds ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var + ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var1 emptyVarSet tv_bndrs qevs - wanted + residual_wanted + ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var1)) spec_e' + -- The free vars of `lhs_call` are `qevs`, plus the explicit `rule_bndrs` + -- and any free tyvars of the above + ; ; traceTc "tcSpecPrag:SpecSigE" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' @@ -975,7 +981,6 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) , text "spec_e:" <+> ppr spec_e' , text "inl:" <+> ppr inl ] - ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) spec_e' ; return [SpecPragE { spe_fn_nm = nm , spe_fn_id = poly_id , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order @@ -1483,7 +1488,8 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; lhs_wanted <- liftZonkM $ zonkWC lhs_wanted -- Note [The SimplifyRule Plan] step 3 - ; (quant_evs, residual_lhs_wanted) <-getRuleQuantCts lhs_wanted + ; (quant_cts, residual_lhs_wanted) <-getRuleQuantCts lhs_wanted + ; let qant_evs = map ctEvId (bagToTolist quant_cts) ; traceTc "simplifyRule" $ vcat [ text "LHS of rule" <+> doubleQuotes (ftext name) @@ -1496,7 +1502,7 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; return (quant_evs, residual_lhs_wanted, dont_default) } -getRuleQuantCts :: WantedConstraints -> TcM ([EvVar], WantedConstraints) +getRuleQuantCts :: WantedConstraints -> TcM (Cts, WantedConstraints) -- Extract all the constraints that we can quantify over, -- also returning the depleted WantedConstraints -- @@ -1513,11 +1519,8 @@ getRuleQuantCts :: WantedConstraints -> TcM ([EvVar], WantedConstraints) -- see GHC.Tc.Utils.Unify.implicationNeeded. Not doing so caused #14732. getRuleQuantCts wc - = do { quant_evs <- mapM mk_one (bagToList quant_cts) - ; return (quant_evs, residual_wc) } + = float_wc emptyVarSet wc where - (quant_cts, residual_wc) = float_wc emptyVarSet wc - float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_errors = errs }) = ( simple_yes `andCts` implic_yes ===================================== compiler/GHC/Tc/Solver/Default.hs ===================================== @@ -973,7 +973,7 @@ tryDefaultGroup wanteds (Proposal assignments) errInvalidDefaultedTyVar :: WantedConstraints -> Proposal -> NonEmpty TcTyVar -> TcS () errInvalidDefaultedTyVar wanteds (Proposal assignments) problematic_tvs - = failTcS $ TcRnInvalidDefaultedTyVar tidy_wanteds tidy_assignments tidy_problems + = failWithTcS $ TcRnInvalidDefaultedTyVar tidy_wanteds tidy_assignments tidy_problems where proposal_tvs = concatMap (\(tv, ty) -> tv : tyCoVarsOfTypeList ty) assignments tidy_env = tidyFreeTyCoVars emptyTidyEnv $ proposal_tvs ++ NE.toList problematic_tvs ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -885,7 +885,8 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls | otherwise -- Wanted, but not cached = do { dflags <- getDynFlags - ; lkup_res <- matchClassInst dflags inerts cls xis dict_loc + ; mode <- getModeTcS + ; lkup_res <- matchClassInst dflags mode inerts cls xis dict_loc ; case lkup_res of OneInst { cir_what = what } -> do { insertSafeOverlapFailureTcS what work_item @@ -940,10 +941,14 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> InertSet +matchClassInst :: DynFlags -> TcSMode + -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult -matchClassInst dflags inerts clas tys loc +matchClassInst dflags mode inerts clas tys loc + | TcSSpecPrag <- mode -- See Note [Handling new-form SPECIALISE pragmas] + = return NoInstance -- in GHc.Tc.Gen.Sig + -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance -- whether top level, or local quantified constraints. ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2018,8 +2018,9 @@ finishCanWithIrred :: CtIrredReason -> CtEvidence -> TcS (StopOrContinue (Either IrredCt a)) finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, - -- and the TcS abort-if-insoluble flag is on. - when (isInsolubleReason reason) tryEarlyAbortTcS + -- and the TcSMode is TcsHoleFits + mode <- getModeTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -14,9 +14,10 @@ module GHC.Tc.Solver.Monad ( -- The TcS monad - TcS, runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, - failTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, - runTcSEqualities, + TcS, TcSMode(..), + runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, + runTcSEqualities, runTcSSpecPrag, + failTcS, failWithTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, nestTcS, nestImplicTcS, setEvBindsTcS, emitImplicationTcS, emitTvImplicationTcS, emitFunDepWanteds, @@ -37,7 +38,7 @@ module GHC.Tc.Solver.Monad ( stopWithStage, nopStage, -- Tracing etc - panicTcS, traceTcS, tryEarlyAbortTcS, + panicTcS, traceTcS, getModeTcS, traceFireTcS, bumpStepCountTcS, csTraceTcS, wrapErrTcS, wrapWarnTcS, resetUnificationFlag, setUnificationFlag, @@ -856,6 +857,7 @@ data TcSMode | TcSSpecPrag -- Don't use instance declarations or upack forall constraints -- when simplifying a SPECIALISE pragma + deriving( Eq ) instance Outputable TcSMode where ppr TcSVanilla = text "TcSVanilla" @@ -922,9 +924,11 @@ wrapWarnTcS :: TcM a -> TcS a wrapWarnTcS = wrapTcS panicTcS :: SDoc -> TcS a -failTcS :: TcRnMessage -> TcS a +failTcS :: TcS a +failWithTcS :: TcRnMessage -> TcS a warnTcS, addErrTcS :: TcRnMessage -> TcS () -failTcS = wrapTcS . TcM.failWith +failTcS = wrapTcS TcM.failM +failWithTcS = wrapTcS . TcM.failWith warnTcS msg = wrapTcS (TcM.addDiagnostic msg) addErrTcS = wrapTcS . TcM.addErr panicTcS doc = pprPanic "GHC.Tc.Solver.Monad" doc @@ -986,11 +990,13 @@ csTraceTcM mk_doc msg }) } {-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] -runTcS :: TcS a -- What to run - -> TcM (a, EvBindMap) +runTcSWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSWithEvBinds = runTcSWorker True TcSVanilla + +runTcS :: TcS a -> TcM (a, EvBindMap) runTcS tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; res <- runTcSWithEvBinds ev_binds_var tcs + ; res <- runTcSWorker True TcSVanilla aev_binds_var tcs ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var ; return (res, ev_binds) } @@ -1000,39 +1006,43 @@ runTcS tcs runTcSEarlyAbort :: TcS a -> TcM a runTcSEarlyAbort tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; runTcSWithEvBinds' True TcSHoleFits ev_binds_var tcs } + ; runTcSWorker' True TcSHoleFits ev_binds_var tcs } -- | This can deal only with equality constraints. runTcSEqualities :: TcS a -> TcM a runTcSEqualities thing_inside - = do { ev_binds_var <- TcM.newNoTcEvBinds - ; runTcSWithEvBinds ev_binds_var thing_inside } + = do { ev_binds_var <- TcM.newNoTcEvBinds -- No bindings + ; runTcSWorker True TcSVanilla ev_binds_var thing_inside } + +-- | This version of runTcS uses mode TcSSpecPrag +runTcSSpecPrag :: TcS a -> TcM (a, Bag EvBind) +runTcSSpecPrag thing_inside + = do { ev_binds_var <- TcM.newTcEvBinds + ; res <- runTcSWorker True TcSSpecPrag ev_binds_var tcs + ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var + ; return (res, evBindMapBinds ev_binds) } -- | A variant of 'runTcS' that takes and returns an 'InertSet' for -- later resumption of the 'TcS' session. runTcSInerts :: InertSet -> TcS a -> TcM (a, InertSet) runTcSInerts inerts tcs = do - ev_binds_var <- TcM.newTcEvBinds - runTcSWithEvBinds' False False ev_binds_var $ do - setInertSet inerts - a <- tcs - new_inerts <- getInertSet - return (a, new_inerts) - -runTcSWithEvBinds :: EvBindsVar - -> TcS a - -> TcM a -runTcSWithEvBinds = runTcSWithEvBinds' True TcSVanilla - -runTcSWithEvBinds' :: Bool -- ^ Restore type variable cycles afterwards? - -- Don't if you want to reuse the InertSet. - -- See also Note [Type equality cycles] - -- in GHC.Tc.Solver.Equality - -> TcSMode - -> EvBindsVar - -> TcS a - -> TcM a -runTcSWithEvBinds' restore_cycles mode ev_binds_var tcs + = do { ev_binds_var <- TcM.newTcEvBinds + ; runTcWorker False TcSVanilla ev_binds_var $ + do { setInertSet inerts + ; a <- tcs + ; new_inerts <- getInertSet + ; return (a, new_inerts) } } + +-- runTcSWorker is not exported +runTcSWorker :: Bool -- ^ Restore type variable cycles afterwards? + -- Don't if you want to reuse the InertSet. + -- See also Note [Type equality cycles] + -- in GHC.Tc.Solver.Equality + -> TcSMode + -> EvBindsVar + -> TcS a + -> TcM a +runTcSWorker restore_cycles mode ev_binds_var tcs = do { unified_var <- TcM.newTcRef 0 ; step_count <- TcM.newTcRef 0 ; inert_var <- TcM.newTcRef emptyInert @@ -1101,7 +1111,7 @@ nestImplicTcS :: EvBindsVar -> TcLevel -> TcS a -> TcS a nestImplicTcS ref inner_tclvl (TcS thing_inside) - = TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var } -> + = TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var }) -> do { inerts <- TcM.readTcRef old_inert_var ; let nest_inert = inerts { inert_cycle_breakers = pushCycleBreakerVarStack (inert_cycle_breakers inerts) ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -923,7 +923,7 @@ solveSimpleWanteds simples -- See Note [The solveSimpleWanteds loop] go n limit wc | n `intGtLimit` limit - = failTcS $ TcRnSimplifierTooManyIterations simples limit wc + = failWithTcS $ TcRnSimplifierTooManyIterations simples limit wc | isEmptyBag (wc_simple wc) = return (n,wc) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/32e0aa0571ac34032426a94b8f2f1be10002bdd9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/32e0aa0571ac34032426a94b8f2f1be10002bdd9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 11:53:34 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 23 Jan 2025 06:53:34 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/test-hc-opts Message-ID: <67922dbe6629_30c37b14c1958811ae@gitlab.mail> Matthew Pickering pushed new branch wip/test-hc-opts at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/test-hc-opts You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 12:09:34 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 07:09:34 -0500 Subject: [Git][ghc/ghc][wip/T18462] 4 commits: Restrict XBangTy and XRectTy to GhcPs phase Message-ID: <6792317e2c5a1_30c37b1832934859cb@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: e7bddd47 by Sjoerd Visscher at 2025-01-23T13:09:03+01:00 Restrict XBangTy and XRectTy to GhcPs phase Fix - - - - - 8cc1eafa by Sjoerd Visscher at 2025-01-23T13:09:04+01:00 Showing error message regressions - - - - - 336fe5ae by Sjoerd Visscher at 2025-01-23T13:09:25+01:00 Add doc field to CFS - - - - - 72ec38fb by Sjoerd Visscher at 2025-01-23T13:09:25+01:00 Add documentation - - - - - 30 changed files: - compiler/GHC/Core/Rules.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Errors/Types.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Type.hs - libraries/ghc-internal/src/GHC/Internal/TypeError.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/parser/should_fail/T3811c.stderr - testsuite/tests/parser/should_fail/unpack_inside_type.stderr - testsuite/tests/printer/T18791.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f8df70e452568b53f891944f4d328b977d82d8b...72ec38fba5198553bdd1f57fb94374bd7d1fe1ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1f8df70e452568b53f891944f4d328b977d82d8b...72ec38fba5198553bdd1f57fb94374bd7d1fe1ea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 12:21:23 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 23 Jan 2025 07:21:23 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/splice-imports-with-lift-extension Message-ID: <67923443a5d0e_30c37b1df99a8917e2@gitlab.mail> Matthew Pickering pushed new branch wip/splice-imports-with-lift-extension at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/splice-imports-with-lift-extension You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 15:51:42 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 10:51:42 -0500 Subject: [Git][ghc/ghc][wip/T18462] Unannotated multiplicity based on type Message-ID: <6792658e461c0_3e7a8e3f8a18740b@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 1a49aa49 by Sjoerd Visscher at 2025-01-23T16:51:08+01:00 Unannotated multiplicity based on type - - - - - 25 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/printer/T18791.stderr - utils/check-exact/ExactPrint.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 Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -539,11 +539,11 @@ deriving instance Data (HsTyLit GhcTc) -- deriving instance (Data mult, DataIdLR p p, Typeable on) => Data (HsMultAnnOn on mult p) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsType GhcPs)) GhcPs) -deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsType GhcPs)) GhcPs) +deriving instance Data (HsMultAnnOn OnConField (LocatedA (HsType GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcTc)) GhcTc) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsExpr GhcPs)) GhcPs) -deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsExpr GhcPs)) GhcPs) +deriving instance Data (HsMultAnnOn OnConField (LocatedA (HsExpr GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcTc)) GhcTc) @@ -559,7 +559,7 @@ deriving instance Data (ConDeclField GhcTc) -- deriving instance (DataIdLR p p, Typeable on) => Data (HsConFieldSpec on p) deriving instance Data (HsConFieldSpec OnArrow GhcPs) -deriving instance Data (HsConFieldSpec OnRecField GhcPs) +deriving instance Data (HsConFieldSpec OnConField GhcPs) deriving instance Typeable on => Data (HsConFieldSpec on GhcRn) deriving instance Typeable on => Data (HsConFieldSpec on GhcTc) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -26,9 +26,9 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( Mult, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), - HsUnannotatedMult(..), pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, + pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, EpLinearArrow(..), - hsNoMultAnn, isUnrestricted, hsMultIsLinear, + hsNoMultAnn, isUnrestricted, pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, @@ -129,7 +129,7 @@ import GHC.Utils.Outputable import GHC.Utils.Misc (count) import Data.Maybe -import Data.Data (Data) +import Data.Data (Data, Proxy (..)) import qualified Data.Semigroup as S import GHC.Data.Bag @@ -531,39 +531,46 @@ instance NoAnn EpLinearArrow where noAnn = EpPct1 noAnn noAnn type instance XUnannotated OnArrow _ GhcPs = TokRarrow -type instance XUnannotated OnRecField _ GhcPs = TokDcolon +type instance XUnannotated OnConField _ GhcPs = TokDcolon type instance XUnannotated _ _ GhcRn = NoExtField type instance XUnannotated _ _ GhcTc = NoExtField type instance XLinearAnn OnArrow _ GhcPs = EpLinearArrow -type instance XLinearAnn OnRecField _ GhcPs = (EpToken "%1", TokDcolon) +type instance XLinearAnn OnConField _ GhcPs = (EpToken "%1", TokDcolon) type instance XLinearAnn _ _ GhcRn = NoExtField type instance XLinearAnn _ _ GhcTc = NoExtField type instance XExplicitMult OnArrow _ GhcPs = (EpToken "%", TokRarrow) -type instance XExplicitMult OnRecField _ GhcPs = (EpToken "%", TokDcolon) +type instance XExplicitMult OnConField _ GhcPs = (EpToken "%", TokDcolon) type instance XExplicitMult _ _ GhcRn = NoExtField type instance XExplicitMult _ _ GhcTc = NoExtField type instance XXMultAnnOn _ _ (GhcPass _) = DataConCantHappen -hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => HsMultAnnOn on (LHsType GhcPs) GhcPs -hsNoMultAnn = HsUnannotated HsUnannOne noAnn +hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) + => HsMultAnnOn on (LHsType GhcPs) GhcPs +hsNoMultAnn = HsUnannotated noAnn isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (multAnnToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName isUnrestricted _ = False -multAnnToHsType :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> LHsType GhcRn +multAnnToHsType :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> LHsType GhcRn multAnnToHsType = expandHsMultAnnOn (HsTyVar noAnn NotPromoted) -- | Convert an multiplicity annotation into its corresponding multiplicity. -- In essence this erases the information of whether the programmer wrote an explicit -- multiplicity or a shorthand. -- In this polymorphic function, `t` can be `HsType` or `HsExpr` -expandHsMultAnnOn :: (LocatedN Name -> t GhcRn) -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn -> LocatedA (t GhcRn) -expandHsMultAnnOn mk_var (HsUnannotated HsUnannOne _) = noLocA (mk_var (noLocA oneDataConName)) -expandHsMultAnnOn mk_var (HsUnannotated HsUnannMany _) = noLocA (mk_var (noLocA manyDataConName)) +expandHsMultAnnOn :: forall on t. IsHsMultAnnOnWhat on + => (LocatedN Name -> t GhcRn) + -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn + -> LocatedA (t GhcRn) +expandHsMultAnnOn mk_var (HsUnannotated _) = noLocA (mk_var (noLocA mult)) + where + mult = case hsMultAnnOnWhat (Proxy :: Proxy on) of + OnArrow -> manyDataConName + OnConField -> oneDataConName expandHsMultAnnOn mk_var (HsLinearAnn _) = noLocA (mk_var (noLocA oneDataConName)) expandHsMultAnnOn _mk_var (HsExplicitMult _ p) = p @@ -574,7 +581,7 @@ instance -- See #18846 pprHsArrow :: (Outputable mult, OutputableBndrId pass) => HsArrowOf mult (GhcPass pass) -> SDoc -pprHsArrow (HsUnannotated _ _) = pprArrowWithMultiplicity visArgTypeLike (Left False) +pprHsArrow (HsUnannotated _) = pprArrowWithMultiplicity visArgTypeLike (Left False) pprHsArrow (HsLinearAnn _) = pprArrowWithMultiplicity visArgTypeLike (Left True) pprHsArrow (HsExplicitMult _ p) = pprArrowWithMultiplicity visArgTypeLike (Right (ppr p)) @@ -591,7 +598,7 @@ instance OutputableBndrId p ppr_mult :: HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc ppr_mult mult tyDoc = case mult of - HsUnannotated _ _ -> dcolon <+> tyDoc + HsUnannotated _ -> dcolon <+> tyDoc HsLinearAnn _ -> text "%1" <+> dcolon <+> tyDoc HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon <+> tyDoc ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -86,6 +86,7 @@ import GHC.Types.Name.Env import GHC.TypeLits import Data.Kind (Constraint) +import Data.Proxy import qualified GHC.LanguageExtensions as LangExt @@ -2861,11 +2862,18 @@ repGadtDataCons cons details res_ty -- TH currently only supports linear constructors. -- We also accept the (->) arrow when -XLinearTypes is off, because this -- denotes a linear field. -verifyLinearFields :: [HsConFieldSpec on GhcRn] -> MetaM () +verifyLinearFields :: forall on. IsHsMultAnnOnWhat on => [HsConFieldSpec on GhcRn] -> MetaM () verifyLinearFields ps = do linear <- lift $ xoptM LangExt.LinearTypes let allGood = all (hsMultIsLinear linear . cfs_multiplicity) ps unless allGood $ notHandled ThNonLinearDataCon + where + hsMultIsLinear linearTypesEnabled (HsUnannotated _) = + case hsMultAnnOnWhat (Proxy :: Proxy on) of + OnArrow -> not linearTypesEnabled + OnConField -> True + hsMultIsLinear _ HsLinearAnn{} = True + hsMultIsLinear _ _ = False -- Desugar the arguments in a data constructor declared with prefix syntax. repPrefixConArgs :: [HsConFieldSpec OnArrow GhcRn] @@ -2885,7 +2893,7 @@ repRecConArgs lips = do where rep_ip ip = mapM (rep_one_ip (cd_fld_spec ip)) (cd_fld_names ip) - rep_one_ip :: HsConFieldSpec OnRecField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) + rep_one_ip :: HsConFieldSpec OnConField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) rep_one_ip t n = do { MkC v <- lookupOcc (unLoc . foLabel $ unLoc n) ; MkC ty <- repConFieldSpec t ; rep2 varBangTypeName [v,ty] } ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1795,7 +1795,7 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where , toHie decls ] -instance ToHie (HsConFieldSpec on GhcRn) where +instance IsHsMultAnnOnWhat on => ToHie (HsConFieldSpec on GhcRn) where toHie (CFS _ _ _ w t doc) = concatM [ toHie (multAnnToHsType w) , toHie t ===================================== compiler/GHC/Parser.y ===================================== @@ -2601,7 +2601,7 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3)))} + (mkConFieldSpec (HsUnannotated (epUniTok $2)) $3)))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) (ConDeclField noExtField ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3520,7 +3520,7 @@ mkMultAnn pct t@(L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) pct1 = epTokenWidenR pct (locA (getLoc t)) mkMultAnn pct t = HsMultAnn pct t -mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnRecField GhcPs +mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnConField GhcPs mkMultField pct (L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) col t -- See #18888 for the use of (SourceText "1") above = mkConFieldSpec (HsLinearAnn (pct1, col)) t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -706,7 +706,7 @@ rnHsMultAnnOn env = rnHsMultAnnOnWith (rnLHsTyKi env) rnHsMultAnnOnWith :: (LocatedA (mult GhcPs) -> RnM (LocatedA (mult GhcRn), FreeVars)) -> HsMultAnnOn on (LocatedA (mult GhcPs)) GhcPs -> RnM (HsMultAnnOn on (LocatedA (mult GhcRn)) GhcRn, FreeVars) -rnHsMultAnnOnWith _rn (HsUnannotated mult _) = pure (HsUnannotated mult noExtField, emptyFVs) +rnHsMultAnnOnWith _rn (HsUnannotated _) = pure (HsUnannotated noExtField, emptyFVs) rnHsMultAnnOnWith _rn (HsLinearAnn _) = pure (HsLinearAnn noExtField, emptyFVs) rnHsMultAnnOnWith rn (HsExplicitMult _ p) = (\(mult, fvs) -> (HsExplicitMult noExtField mult, fvs)) <$> rn p ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -1387,7 +1387,7 @@ rn_ty_pat ty@(XHsType{}) = do liftRnFV $ rnHsType ctxt ty rn_ty_pat_arrow :: HsArrow GhcPs -> TPRnM (HsArrow GhcRn) -rn_ty_pat_arrow (HsUnannotated mult _) = pure (HsUnannotated mult noExtField) +rn_ty_pat_arrow (HsUnannotated _) = pure (HsUnannotated noExtField) rn_ty_pat_arrow (HsLinearAnn _) = pure (HsLinearAnn noExtField) rn_ty_pat_arrow (HsExplicitMult _ p) = rn_lty_pat p <&> (\mult -> HsExplicitMult noExtField mult) ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -991,7 +991,7 @@ expr_to_type earg = ; return (L l (HsFunTy noExtField mult' arg' res'))} where go_arrow :: HsArrowOf (LHsExpr GhcRn) GhcRn -> TcM (HsArrow GhcRn) - go_arrow (HsUnannotated mult _) = pure (HsUnannotated mult noExtField) + go_arrow (HsUnannotated _) = pure (HsUnannotated noExtField) go_arrow (HsLinearAnn{}) = pure (HsLinearAnn noExtField) go_arrow (HsExplicitMult _ exp) = HsExplicitMult noExtField <$> go exp go (L l (HsForAll _ tele expr)) = ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -947,7 +947,7 @@ concern things that the renamer can't handle. -} -tcMult :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tcMult :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tcMult hc = tc_mult typeLevelMode hc -- | Info about the context in which we're checking a type. Currently, @@ -1364,7 +1364,7 @@ Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in "GHC.Core.TyCo -} ------------------------------------------ -tc_mult :: TcTyMode -> HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tc_mult :: IsHsMultAnnOnWhat on => TcTyMode -> HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tc_mult mode ty = tc_check_lhs_type mode (multAnnToHsType ty) multiplicityTy ------------------------------------------ tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> ExpKind ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1806,7 +1806,8 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: ConArgKind -- Expected kind of the argument(s) +kcConArgTys :: IsHsMultAnnOnWhat on + => ConArgKind -- Expected kind of the argument(s) -> [HsConFieldSpec on GhcRn] -- User-written argument types -> TcM () kcConArgTys exp_kind arg_tys @@ -3988,7 +3989,8 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: IsHsMultAnnOnWhat on + => ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (CFS (_, src) unp str w bty _) @@ -4011,7 +4013,7 @@ tcRecConDeclFields exp_kind fields exploded = concatMap explode combined (_,btys) = unzip exploded -tcDataConMult :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tcDataConMult :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tcDataConMult arr@(HsUnrestrictedArrow _) = do -- See Note [Function arrows in GADT constructors] linearEnabled <- xoptM LangExt.LinearTypes ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -776,7 +776,8 @@ cvtSrcStrictness NoSourceStrictness = NoSrcStrict cvtSrcStrictness SourceLazy = SrcLazy cvtSrcStrictness SourceStrict = SrcStrict -cvt_arg :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) +cvt_arg :: (NoAnn (XUnannotated on (LHsType GhcPs) GhcPs), IsHsMultAnnOnWhat on) + => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) cvt_arg (Bang su ss, ty) = do { ty'' <- cvtType ty ; let ty' = parenthesizeHsType appPrec ty'' ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -22,10 +22,9 @@ GHC.Hs.Type: Abstract syntax: user-defined types -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* module Language.Haskell.Syntax.Type ( - HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), + HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), IsHsMultAnnOnWhat(..), pattern HsUnrestrictedArrow, XUnannotated, XLinearAnn, XExplicitMult, XXMultAnnOn, - hsMultIsLinear, HsType(..), LHsType, HsKind, LHsKind, HsBndrVis(..), XBndrRequired, XBndrInvisible, XXBndrVis, @@ -919,28 +918,35 @@ data HsTyLit pass type HsArrow pass = HsArrowOf (LHsType pass) pass type HsArrowOf = HsMultAnnOn OnArrow --- HsMultAnnOn is used both to represent function arrows and multiplicity annotations --- in the record declaration syntax. But the default multiplicity is different --- between the two uses. In record syntax, the default is One, but on arrows, the --- default is Many. `HsUnannotatedMult` is used to distinguish between the two uses. -data HsUnannotatedMult = HsUnannOne | HsUnannMany - deriving (Eq, Ord, Data) - pattern HsUnrestrictedArrow :: XUnannotated on mult pass -> HsMultAnnOn on mult pass -pattern HsUnrestrictedArrow a = HsUnannotated HsUnannMany a - -data HsMultAnnOnWhat = OnArrow | OnRecField +pattern HsUnrestrictedArrow a = HsUnannotated a --- | Denotes the type of arrows in the surface language +-- HsMultAnnOn is used both to represent function arrows and multiplicity annotations +-- in the data declaration syntax. But the default multiplicity is different +-- between the two uses. In constructors, the default is One, but on arrows, the +-- default is Many. (But note that non-record GADT syntax follows the default of arrows.) +-- `HsMultAnnOnWhat` is used to distinguish between the two uses. +data HsMultAnnOnWhat = OnArrow | OnConField + +-- Get a value level representation of the `HsMultAnnOnWhat` kind. +class IsHsMultAnnOnWhat (on :: HsMultAnnOnWhat) where + hsMultAnnOnWhat :: proxy on -> HsMultAnnOnWhat +instance IsHsMultAnnOnWhat OnArrow where + hsMultAnnOnWhat _ = OnArrow +instance IsHsMultAnnOnWhat OnConField where + hsMultAnnOnWhat _ = OnConField + +-- | Denotes multiplicity annotations in the surface language data HsMultAnnOn (on :: HsMultAnnOnWhat) mult pass - = HsUnannotated HsUnannotatedMult !(XUnannotated on mult pass) - -- ^ a -> b or a → b + = HsUnannotated !(XUnannotated on mult pass) + -- ^ a -> b or a → b or { nm :: a } | HsLinearAnn !(XLinearAnn on mult pass) - -- ^ a %1 -> b or a %1 → b, or a ⊸ b + -- ^ a %1 -> b or a %1 → b, or a ⊸ b, or { nm %1 :: a } | HsExplicitMult !(XExplicitMult on mult pass) !mult - -- ^ a %m -> b or a %m → b (very much including `a %Many -> b`! + -- ^ a %m -> b or a %m → b or { nm %m :: a } + -- (very much including `a %Many -> b`! -- This is how the programmer wrote it). It is stored as an -- `HsType` so as to preserve the syntax as written in the -- program. @@ -952,12 +958,6 @@ type family XLinearAnn (on :: HsMultAnnOnWhat) mult p type family XExplicitMult (on :: HsMultAnnOnWhat) mult p type family XXMultAnnOn (on :: HsMultAnnOnWhat) mult p -hsMultIsLinear :: Bool -> HsMultAnnOn on mult pass -> Bool -hsMultIsLinear _ (HsUnannotated HsUnannOne _) = True -hsMultIsLinear linear (HsUnannotated HsUnannMany _) = not linear -hsMultIsLinear _ HsLinearAnn{} = True -hsMultIsLinear _ _ = False - {- Note [Unit tuples] ~~~~~~~~~~~~~~~~~~ @@ -1061,7 +1061,7 @@ data ConDeclField pass = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_spec :: HsConFieldSpec OnRecField pass } + cd_fld_spec :: HsConFieldSpec OnConField pass } | XConDeclField !(XXConDeclField pass) {- Note [ConDeclField pass] ===================================== testsuite/tests/ghc-api/exactprint/Test20239.stderr ===================================== @@ -257,7 +257,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { Test20239.hs:7:62-63 }) (NormalSyntax))) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr ===================================== @@ -254,7 +254,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { T17544_kw.hs:19:21-22 }) (NormalSyntax))) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr ===================================== @@ -951,7 +951,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:28:15-16 }) (NormalSyntax))) @@ -1024,7 +1023,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:29:15-16 }) (NormalSyntax))) @@ -1184,7 +1182,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:33:10-11 }) (NormalSyntax))) @@ -1257,7 +1254,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:34:10-11 }) (NormalSyntax))) @@ -1429,7 +1425,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:40:8-9 }) (NormalSyntax))) @@ -1502,7 +1497,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:42:8-9 }) (NormalSyntax))) ===================================== testsuite/tests/parser/should_compile/DumpParsedAst.stderr ===================================== @@ -254,7 +254,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:9:20-21 }) (NormalSyntax))) @@ -960,7 +959,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:14-15 }) (NormalSyntax))) @@ -993,7 +991,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:29-30 }) (NormalSyntax))) @@ -1020,7 +1017,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:20-21 }) (NormalSyntax))) @@ -1407,7 +1403,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:18:33-34 }) (NormalSyntax))) @@ -1540,7 +1535,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:21:22-23 }) (NormalSyntax))) @@ -1573,7 +1567,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:21:27-28 }) (NormalSyntax))) @@ -1699,7 +1692,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:30-31 }) (NormalSyntax))) @@ -1772,7 +1764,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:54-55 }) (NormalSyntax))) @@ -1799,7 +1790,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:45-46 }) (NormalSyntax))) @@ -1908,7 +1898,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:23:36-37 }) (NormalSyntax))) @@ -1980,7 +1969,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:23:27-28 }) (NormalSyntax))) ===================================== testsuite/tests/parser/should_compile/DumpRenamedAst.stderr ===================================== @@ -648,7 +648,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -757,7 +756,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -787,7 +785,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -906,7 +903,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -971,7 +967,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -994,7 +989,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1093,7 +1087,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1159,7 +1152,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1846,7 +1838,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1951,7 +1942,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1981,7 +1971,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -2004,7 +1993,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn ===================================== testsuite/tests/parser/should_compile/T14189.stderr ===================================== @@ -207,7 +207,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (NoExtField)) (L (EpAnn ===================================== testsuite/tests/printer/T18791.stderr ===================================== @@ -128,7 +128,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { T18791.hs:5:14-15 }) (NormalSyntax))) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -834,9 +834,9 @@ markEpUniToken (EpUniTok aa isUnicode) = do -- --------------------------------------------------------------------- markArrow :: (Monad m, Monoid w, ExactPrint a) => HsArrowOf a GhcPs -> EP w m (HsArrowOf a GhcPs) -markArrow (HsUnannotated t arr) = do +markArrow (HsUnannotated arr) = do arr' <- markEpUniToken arr - return (HsUnannotated t arr') + return (HsUnannotated arr') markArrow (HsLinearAnn (EpPct1 pct1 arr)) = do pct1' <- markEpToken pct1 arr' <- markEpUniToken arr @@ -850,11 +850,11 @@ markArrow (HsExplicitMult (pct, arr) t) = do arr' <- markEpUniToken arr return (HsExplicitMult (pct', arr') t') -markRecFieldMult :: (Monad m, Monoid w, ExactPrint a) => HsMultAnnOn OnRecField a GhcPs -> EP w m (HsMultAnnOn OnRecField a GhcPs) -markRecFieldMult (HsUnannotated t col) = do +markRecFieldMult :: (Monad m, Monoid w, ExactPrint a) => HsMultAnnOn OnConField a GhcPs -> EP w m (HsMultAnnOn OnConField a GhcPs) +markRecFieldMult (HsUnannotated col) = do traceM $ "markRecFieldMult:HsUnannotated" col' <- markEpUniToken col - return (HsUnannotated t col') + return (HsUnannotated col') markRecFieldMult (HsLinearAnn (pct1, col)) = do traceM $ "markRecFieldMult:HsLinearAnn" pct1' <- markEpToken pct1 @@ -4449,7 +4449,7 @@ instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where arr' <- markArrow arr return (CFS an' unp str arr' t' doc) -instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where +instance ExactPrint (HsConFieldSpec OnConField GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a exact (CFS an unp str mult t doc) = do ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -1049,7 +1049,7 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype) = -- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX ppRecFieldMultAnn unicode (CFS _ _ _ arr _ _) following = case arr of - HsUnannotated _ _ -> following + HsUnannotated _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following @@ -1318,7 +1318,7 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u = where arr = case mult of HsLinearAnn _ -> lollipop u - HsUnannotated _ _ -> arrow u + HsUnannotated _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u <+> arrow u ppr_mono_ty (HsTyVar _ NotPromoted (L _ name)) _ = ppDocName name ppr_mono_ty (HsTyVar _ IsPromoted (L _ name)) _ = char '\'' <> ppDocName name ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1557,7 +1557,7 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype) = -- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _ _) following = case arr of - HsUnannotated _ _ -> following + HsUnannotated _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following @@ -1821,7 +1821,7 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u q e = where arr = case mult of HsLinearAnn _ -> lollipop u - HsUnannotated _ _ -> arrow u + HsUnannotated _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u q e <+> arrow u ppr_mono_ty (HsTupleTy _ con tys) u q _ = tupleParens con (map (ppLType u q HideEmptyContexts) tys) ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -990,9 +990,9 @@ synifyMult vs t = case t of ManyTy -> HsUnrestrictedArrow noExtField ty -> HsExplicitMult noExtField (synifyType WithinType vs ty) -synifyMultRec :: [TyVar] -> Mult -> HsMultAnnOn OnRecField (LHsType GhcRn) GhcRn +synifyMultRec :: [TyVar] -> Mult -> HsMultAnnOn OnConField (LHsType GhcRn) GhcRn synifyMultRec vs t = case t of - OneTy -> HsUnannotated HsUnannOne noExtField + OneTy -> HsUnannotated noExtField ty -> HsExplicitMult noExtField (synifyType WithinType vs ty) synifyPatSynType :: PatSyn -> LHsType GhcRn ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -341,7 +341,7 @@ renameMaybeInjectivityAnn renameMaybeInjectivityAnn = traverse renameInjectivityAnn renameMultAnnOn :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> RnM (HsMultAnnOn on (LHsType DocNameI) DocNameI) -renameMultAnnOn (HsUnannotated mult _) = return (HsUnannotated mult noExtField) +renameMultAnnOn (HsUnannotated _) = return (HsUnannotated noExtField) renameMultAnnOn (HsLinearAnn _) = return (HsLinearAnn noExtField) renameMultAnnOn (HsExplicitMult _ p) = HsExplicitMult noExtField <$> renameLType p View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a49aa49ca942643866890c20f074fd1b3e4a1a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a49aa49ca942643866890c20f074fd1b3e4a1a4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 16:10:54 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 11:10:54 -0500 Subject: [Git][ghc/ghc][wip/T18462] Unannotated multiplicity based on type Message-ID: <67926a0e1bcfd_3e7a8ec0d9248325@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: bd8f0ccd by Sjoerd Visscher at 2025-01-23T17:10:33+01:00 Unannotated multiplicity based on type - - - - - 26 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/printer/T18791.stderr - utils/check-exact/ExactPrint.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 Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -539,11 +539,11 @@ deriving instance Data (HsTyLit GhcTc) -- deriving instance (Data mult, DataIdLR p p, Typeable on) => Data (HsMultAnnOn on mult p) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsType GhcPs)) GhcPs) -deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsType GhcPs)) GhcPs) +deriving instance Data (HsMultAnnOn OnConField (LocatedA (HsType GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcTc)) GhcTc) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsExpr GhcPs)) GhcPs) -deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsExpr GhcPs)) GhcPs) +deriving instance Data (HsMultAnnOn OnConField (LocatedA (HsExpr GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcTc)) GhcTc) @@ -559,7 +559,7 @@ deriving instance Data (ConDeclField GhcTc) -- deriving instance (DataIdLR p p, Typeable on) => Data (HsConFieldSpec on p) deriving instance Data (HsConFieldSpec OnArrow GhcPs) -deriving instance Data (HsConFieldSpec OnRecField GhcPs) +deriving instance Data (HsConFieldSpec OnConField GhcPs) deriving instance Typeable on => Data (HsConFieldSpec on GhcRn) deriving instance Typeable on => Data (HsConFieldSpec on GhcTc) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -26,9 +26,9 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( Mult, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), - HsUnannotatedMult(..), pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, + pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, EpLinearArrow(..), - hsNoMultAnn, isUnrestricted, hsMultIsLinear, + hsNoMultAnn, isUnrestricted, pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, @@ -129,7 +129,7 @@ import GHC.Utils.Outputable import GHC.Utils.Misc (count) import Data.Maybe -import Data.Data (Data) +import Data.Data (Data, Proxy (..)) import qualified Data.Semigroup as S import GHC.Data.Bag @@ -531,39 +531,46 @@ instance NoAnn EpLinearArrow where noAnn = EpPct1 noAnn noAnn type instance XUnannotated OnArrow _ GhcPs = TokRarrow -type instance XUnannotated OnRecField _ GhcPs = TokDcolon +type instance XUnannotated OnConField _ GhcPs = TokDcolon type instance XUnannotated _ _ GhcRn = NoExtField type instance XUnannotated _ _ GhcTc = NoExtField type instance XLinearAnn OnArrow _ GhcPs = EpLinearArrow -type instance XLinearAnn OnRecField _ GhcPs = (EpToken "%1", TokDcolon) +type instance XLinearAnn OnConField _ GhcPs = (EpToken "%1", TokDcolon) type instance XLinearAnn _ _ GhcRn = NoExtField type instance XLinearAnn _ _ GhcTc = NoExtField type instance XExplicitMult OnArrow _ GhcPs = (EpToken "%", TokRarrow) -type instance XExplicitMult OnRecField _ GhcPs = (EpToken "%", TokDcolon) +type instance XExplicitMult OnConField _ GhcPs = (EpToken "%", TokDcolon) type instance XExplicitMult _ _ GhcRn = NoExtField type instance XExplicitMult _ _ GhcTc = NoExtField type instance XXMultAnnOn _ _ (GhcPass _) = DataConCantHappen -hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => HsMultAnnOn on (LHsType GhcPs) GhcPs -hsNoMultAnn = HsUnannotated HsUnannOne noAnn +hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) + => HsMultAnnOn on (LHsType GhcPs) GhcPs +hsNoMultAnn = HsUnannotated noAnn isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (multAnnToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName isUnrestricted _ = False -multAnnToHsType :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> LHsType GhcRn +multAnnToHsType :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> LHsType GhcRn multAnnToHsType = expandHsMultAnnOn (HsTyVar noAnn NotPromoted) -- | Convert an multiplicity annotation into its corresponding multiplicity. -- In essence this erases the information of whether the programmer wrote an explicit -- multiplicity or a shorthand. -- In this polymorphic function, `t` can be `HsType` or `HsExpr` -expandHsMultAnnOn :: (LocatedN Name -> t GhcRn) -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn -> LocatedA (t GhcRn) -expandHsMultAnnOn mk_var (HsUnannotated HsUnannOne _) = noLocA (mk_var (noLocA oneDataConName)) -expandHsMultAnnOn mk_var (HsUnannotated HsUnannMany _) = noLocA (mk_var (noLocA manyDataConName)) +expandHsMultAnnOn :: forall on t. IsHsMultAnnOnWhat on + => (LocatedN Name -> t GhcRn) + -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn + -> LocatedA (t GhcRn) +expandHsMultAnnOn mk_var (HsUnannotated _) = noLocA (mk_var (noLocA mult)) + where + mult = case hsMultAnnOnWhat (Proxy :: Proxy on) of + OnArrow -> manyDataConName + OnConField -> oneDataConName expandHsMultAnnOn mk_var (HsLinearAnn _) = noLocA (mk_var (noLocA oneDataConName)) expandHsMultAnnOn _mk_var (HsExplicitMult _ p) = p @@ -574,7 +581,7 @@ instance -- See #18846 pprHsArrow :: (Outputable mult, OutputableBndrId pass) => HsArrowOf mult (GhcPass pass) -> SDoc -pprHsArrow (HsUnannotated _ _) = pprArrowWithMultiplicity visArgTypeLike (Left False) +pprHsArrow (HsUnannotated _) = pprArrowWithMultiplicity visArgTypeLike (Left False) pprHsArrow (HsLinearAnn _) = pprArrowWithMultiplicity visArgTypeLike (Left True) pprHsArrow (HsExplicitMult _ p) = pprArrowWithMultiplicity visArgTypeLike (Right (ppr p)) @@ -591,7 +598,7 @@ instance OutputableBndrId p ppr_mult :: HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc ppr_mult mult tyDoc = case mult of - HsUnannotated _ _ -> dcolon <+> tyDoc + HsUnannotated _ -> dcolon <+> tyDoc HsLinearAnn _ -> text "%1" <+> dcolon <+> tyDoc HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon <+> tyDoc ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -86,6 +86,7 @@ import GHC.Types.Name.Env import GHC.TypeLits import Data.Kind (Constraint) +import Data.Proxy import qualified GHC.LanguageExtensions as LangExt @@ -2861,11 +2862,18 @@ repGadtDataCons cons details res_ty -- TH currently only supports linear constructors. -- We also accept the (->) arrow when -XLinearTypes is off, because this -- denotes a linear field. -verifyLinearFields :: [HsConFieldSpec on GhcRn] -> MetaM () +verifyLinearFields :: forall on. IsHsMultAnnOnWhat on => [HsConFieldSpec on GhcRn] -> MetaM () verifyLinearFields ps = do linear <- lift $ xoptM LangExt.LinearTypes let allGood = all (hsMultIsLinear linear . cfs_multiplicity) ps unless allGood $ notHandled ThNonLinearDataCon + where + hsMultIsLinear linearTypesEnabled (HsUnannotated _) = + case hsMultAnnOnWhat (Proxy :: Proxy on) of + OnArrow -> not linearTypesEnabled + OnConField -> True + hsMultIsLinear _ HsLinearAnn{} = True + hsMultIsLinear _ _ = False -- Desugar the arguments in a data constructor declared with prefix syntax. repPrefixConArgs :: [HsConFieldSpec OnArrow GhcRn] @@ -2885,7 +2893,7 @@ repRecConArgs lips = do where rep_ip ip = mapM (rep_one_ip (cd_fld_spec ip)) (cd_fld_names ip) - rep_one_ip :: HsConFieldSpec OnRecField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) + rep_one_ip :: HsConFieldSpec OnConField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) rep_one_ip t n = do { MkC v <- lookupOcc (unLoc . foLabel $ unLoc n) ; MkC ty <- repConFieldSpec t ; rep2 varBangTypeName [v,ty] } ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1795,7 +1795,7 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where , toHie decls ] -instance ToHie (HsConFieldSpec on GhcRn) where +instance IsHsMultAnnOnWhat on => ToHie (HsConFieldSpec on GhcRn) where toHie (CFS _ _ _ w t doc) = concatM [ toHie (multAnnToHsType w) , toHie t ===================================== compiler/GHC/Parser.y ===================================== @@ -2601,7 +2601,7 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3)))} + (mkConFieldSpec (HsUnannotated (epUniTok $2)) $3)))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) (ConDeclField noExtField ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3520,7 +3520,7 @@ mkMultAnn pct t@(L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) pct1 = epTokenWidenR pct (locA (getLoc t)) mkMultAnn pct t = HsMultAnn pct t -mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnRecField GhcPs +mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnConField GhcPs mkMultField pct (L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) col t -- See #18888 for the use of (SourceText "1") above = mkConFieldSpec (HsLinearAnn (pct1, col)) t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -706,7 +706,7 @@ rnHsMultAnnOn env = rnHsMultAnnOnWith (rnLHsTyKi env) rnHsMultAnnOnWith :: (LocatedA (mult GhcPs) -> RnM (LocatedA (mult GhcRn), FreeVars)) -> HsMultAnnOn on (LocatedA (mult GhcPs)) GhcPs -> RnM (HsMultAnnOn on (LocatedA (mult GhcRn)) GhcRn, FreeVars) -rnHsMultAnnOnWith _rn (HsUnannotated mult _) = pure (HsUnannotated mult noExtField, emptyFVs) +rnHsMultAnnOnWith _rn (HsUnannotated _) = pure (HsUnannotated noExtField, emptyFVs) rnHsMultAnnOnWith _rn (HsLinearAnn _) = pure (HsLinearAnn noExtField, emptyFVs) rnHsMultAnnOnWith rn (HsExplicitMult _ p) = (\(mult, fvs) -> (HsExplicitMult noExtField mult, fvs)) <$> rn p ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -1387,7 +1387,7 @@ rn_ty_pat ty@(XHsType{}) = do liftRnFV $ rnHsType ctxt ty rn_ty_pat_arrow :: HsArrow GhcPs -> TPRnM (HsArrow GhcRn) -rn_ty_pat_arrow (HsUnannotated mult _) = pure (HsUnannotated mult noExtField) +rn_ty_pat_arrow (HsUnannotated _) = pure (HsUnannotated noExtField) rn_ty_pat_arrow (HsLinearAnn _) = pure (HsLinearAnn noExtField) rn_ty_pat_arrow (HsExplicitMult _ p) = rn_lty_pat p <&> (\mult -> HsExplicitMult noExtField mult) ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -991,7 +991,7 @@ expr_to_type earg = ; return (L l (HsFunTy noExtField mult' arg' res'))} where go_arrow :: HsArrowOf (LHsExpr GhcRn) GhcRn -> TcM (HsArrow GhcRn) - go_arrow (HsUnannotated mult _) = pure (HsUnannotated mult noExtField) + go_arrow (HsUnannotated _) = pure (HsUnannotated noExtField) go_arrow (HsLinearAnn{}) = pure (HsLinearAnn noExtField) go_arrow (HsExplicitMult _ exp) = HsExplicitMult noExtField <$> go exp go (L l (HsForAll _ tele expr)) = ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -947,7 +947,7 @@ concern things that the renamer can't handle. -} -tcMult :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tcMult :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tcMult hc = tc_mult typeLevelMode hc -- | Info about the context in which we're checking a type. Currently, @@ -1364,7 +1364,7 @@ Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in "GHC.Core.TyCo -} ------------------------------------------ -tc_mult :: TcTyMode -> HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tc_mult :: IsHsMultAnnOnWhat on => TcTyMode -> HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tc_mult mode ty = tc_check_lhs_type mode (multAnnToHsType ty) multiplicityTy ------------------------------------------ tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> ExpKind ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1806,7 +1806,8 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: ConArgKind -- Expected kind of the argument(s) +kcConArgTys :: IsHsMultAnnOnWhat on + => ConArgKind -- Expected kind of the argument(s) -> [HsConFieldSpec on GhcRn] -- User-written argument types -> TcM () kcConArgTys exp_kind arg_tys @@ -3988,7 +3989,8 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: IsHsMultAnnOnWhat on + => ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (CFS (_, src) unp str w bty _) @@ -4011,7 +4013,7 @@ tcRecConDeclFields exp_kind fields exploded = concatMap explode combined (_,btys) = unzip exploded -tcDataConMult :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tcDataConMult :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tcDataConMult arr@(HsUnrestrictedArrow _) = do -- See Note [Function arrows in GADT constructors] linearEnabled <- xoptM LangExt.LinearTypes ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -776,7 +776,8 @@ cvtSrcStrictness NoSourceStrictness = NoSrcStrict cvtSrcStrictness SourceLazy = SrcLazy cvtSrcStrictness SourceStrict = SrcStrict -cvt_arg :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) +cvt_arg :: (NoAnn (XUnannotated on (LHsType GhcPs) GhcPs), IsHsMultAnnOnWhat on) + => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) cvt_arg (Bang su ss, ty) = do { ty'' <- cvtType ty ; let ty' = parenthesizeHsType appPrec ty'' ===================================== compiler/Language/Haskell/Syntax/Decls.hs ===================================== @@ -1116,7 +1116,7 @@ or contexts in two parts: -- | The arguments in a Haskell98-style data constructor. type HsConDeclH98Details pass - = HsConDetails Void (HsConFieldSpec OnArrow pass) (XRec pass [LConDeclField pass]) + = HsConDetails Void (HsConFieldSpec OnConField pass) (XRec pass [LConDeclField pass]) -- The Void argument to HsConDetails here is a reflection of the fact that -- type applications are not allowed in data constructor declarations. ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -22,10 +22,9 @@ GHC.Hs.Type: Abstract syntax: user-defined types -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* module Language.Haskell.Syntax.Type ( - HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), + HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), IsHsMultAnnOnWhat(..), pattern HsUnrestrictedArrow, XUnannotated, XLinearAnn, XExplicitMult, XXMultAnnOn, - hsMultIsLinear, HsType(..), LHsType, HsKind, LHsKind, HsBndrVis(..), XBndrRequired, XBndrInvisible, XXBndrVis, @@ -919,28 +918,35 @@ data HsTyLit pass type HsArrow pass = HsArrowOf (LHsType pass) pass type HsArrowOf = HsMultAnnOn OnArrow --- HsMultAnnOn is used both to represent function arrows and multiplicity annotations --- in the record declaration syntax. But the default multiplicity is different --- between the two uses. In record syntax, the default is One, but on arrows, the --- default is Many. `HsUnannotatedMult` is used to distinguish between the two uses. -data HsUnannotatedMult = HsUnannOne | HsUnannMany - deriving (Eq, Ord, Data) - pattern HsUnrestrictedArrow :: XUnannotated on mult pass -> HsMultAnnOn on mult pass -pattern HsUnrestrictedArrow a = HsUnannotated HsUnannMany a - -data HsMultAnnOnWhat = OnArrow | OnRecField +pattern HsUnrestrictedArrow a = HsUnannotated a --- | Denotes the type of arrows in the surface language +-- HsMultAnnOn is used both to represent function arrows and multiplicity annotations +-- in the data declaration syntax. But the default multiplicity is different +-- between the two uses. In constructors, the default is One, but on arrows, the +-- default is Many. (But note that non-record GADT syntax follows the default of arrows.) +-- `HsMultAnnOnWhat` is used to distinguish between the two uses. +data HsMultAnnOnWhat = OnArrow | OnConField + +-- Get a value level representation of the `HsMultAnnOnWhat` kind. +class IsHsMultAnnOnWhat (on :: HsMultAnnOnWhat) where + hsMultAnnOnWhat :: proxy on -> HsMultAnnOnWhat +instance IsHsMultAnnOnWhat OnArrow where + hsMultAnnOnWhat _ = OnArrow +instance IsHsMultAnnOnWhat OnConField where + hsMultAnnOnWhat _ = OnConField + +-- | Denotes multiplicity annotations in the surface language data HsMultAnnOn (on :: HsMultAnnOnWhat) mult pass - = HsUnannotated HsUnannotatedMult !(XUnannotated on mult pass) - -- ^ a -> b or a → b + = HsUnannotated !(XUnannotated on mult pass) + -- ^ a -> b or a → b or { nm :: a } | HsLinearAnn !(XLinearAnn on mult pass) - -- ^ a %1 -> b or a %1 → b, or a ⊸ b + -- ^ a %1 -> b or a %1 → b, or a ⊸ b, or { nm %1 :: a } | HsExplicitMult !(XExplicitMult on mult pass) !mult - -- ^ a %m -> b or a %m → b (very much including `a %Many -> b`! + -- ^ a %m -> b or a %m → b or { nm %m :: a } + -- (very much including `a %Many -> b`! -- This is how the programmer wrote it). It is stored as an -- `HsType` so as to preserve the syntax as written in the -- program. @@ -952,12 +958,6 @@ type family XLinearAnn (on :: HsMultAnnOnWhat) mult p type family XExplicitMult (on :: HsMultAnnOnWhat) mult p type family XXMultAnnOn (on :: HsMultAnnOnWhat) mult p -hsMultIsLinear :: Bool -> HsMultAnnOn on mult pass -> Bool -hsMultIsLinear _ (HsUnannotated HsUnannOne _) = True -hsMultIsLinear linear (HsUnannotated HsUnannMany _) = not linear -hsMultIsLinear _ HsLinearAnn{} = True -hsMultIsLinear _ _ = False - {- Note [Unit tuples] ~~~~~~~~~~~~~~~~~~ @@ -1061,7 +1061,7 @@ data ConDeclField pass = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_spec :: HsConFieldSpec OnRecField pass } + cd_fld_spec :: HsConFieldSpec OnConField pass } | XConDeclField !(XXConDeclField pass) {- Note [ConDeclField pass] ===================================== testsuite/tests/ghc-api/exactprint/Test20239.stderr ===================================== @@ -257,7 +257,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { Test20239.hs:7:62-63 }) (NormalSyntax))) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr ===================================== @@ -254,7 +254,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { T17544_kw.hs:19:21-22 }) (NormalSyntax))) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr ===================================== @@ -951,7 +951,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:28:15-16 }) (NormalSyntax))) @@ -1024,7 +1023,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:29:15-16 }) (NormalSyntax))) @@ -1184,7 +1182,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:33:10-11 }) (NormalSyntax))) @@ -1257,7 +1254,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:34:10-11 }) (NormalSyntax))) @@ -1429,7 +1425,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:40:8-9 }) (NormalSyntax))) @@ -1502,7 +1497,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:42:8-9 }) (NormalSyntax))) ===================================== testsuite/tests/parser/should_compile/DumpParsedAst.stderr ===================================== @@ -254,7 +254,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:9:20-21 }) (NormalSyntax))) @@ -960,7 +959,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:14-15 }) (NormalSyntax))) @@ -993,7 +991,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:29-30 }) (NormalSyntax))) @@ -1020,7 +1017,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:20-21 }) (NormalSyntax))) @@ -1407,7 +1403,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:18:33-34 }) (NormalSyntax))) @@ -1540,7 +1535,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:21:22-23 }) (NormalSyntax))) @@ -1573,7 +1567,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:21:27-28 }) (NormalSyntax))) @@ -1699,7 +1692,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:30-31 }) (NormalSyntax))) @@ -1772,7 +1764,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:54-55 }) (NormalSyntax))) @@ -1799,7 +1790,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:45-46 }) (NormalSyntax))) @@ -1908,7 +1898,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:23:36-37 }) (NormalSyntax))) @@ -1980,7 +1969,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:23:27-28 }) (NormalSyntax))) ===================================== testsuite/tests/parser/should_compile/DumpRenamedAst.stderr ===================================== @@ -648,7 +648,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -757,7 +756,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -787,7 +785,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -906,7 +903,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -971,7 +967,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -994,7 +989,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1093,7 +1087,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1159,7 +1152,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1846,7 +1838,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1951,7 +1942,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1981,7 +1971,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -2004,7 +1993,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn ===================================== testsuite/tests/parser/should_compile/T14189.stderr ===================================== @@ -207,7 +207,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (NoExtField)) (L (EpAnn ===================================== testsuite/tests/printer/T18791.stderr ===================================== @@ -128,7 +128,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { T18791.hs:5:14-15 }) (NormalSyntax))) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -834,9 +834,9 @@ markEpUniToken (EpUniTok aa isUnicode) = do -- --------------------------------------------------------------------- markArrow :: (Monad m, Monoid w, ExactPrint a) => HsArrowOf a GhcPs -> EP w m (HsArrowOf a GhcPs) -markArrow (HsUnannotated t arr) = do +markArrow (HsUnannotated arr) = do arr' <- markEpUniToken arr - return (HsUnannotated t arr') + return (HsUnannotated arr') markArrow (HsLinearAnn (EpPct1 pct1 arr)) = do pct1' <- markEpToken pct1 arr' <- markEpUniToken arr @@ -850,11 +850,11 @@ markArrow (HsExplicitMult (pct, arr) t) = do arr' <- markEpUniToken arr return (HsExplicitMult (pct', arr') t') -markRecFieldMult :: (Monad m, Monoid w, ExactPrint a) => HsMultAnnOn OnRecField a GhcPs -> EP w m (HsMultAnnOn OnRecField a GhcPs) -markRecFieldMult (HsUnannotated t col) = do +markRecFieldMult :: (Monad m, Monoid w, ExactPrint a) => HsMultAnnOn OnConField a GhcPs -> EP w m (HsMultAnnOn OnConField a GhcPs) +markRecFieldMult (HsUnannotated col) = do traceM $ "markRecFieldMult:HsUnannotated" col' <- markEpUniToken col - return (HsUnannotated t col') + return (HsUnannotated col') markRecFieldMult (HsLinearAnn (pct1, col)) = do traceM $ "markRecFieldMult:HsLinearAnn" pct1' <- markEpToken pct1 @@ -4449,7 +4449,7 @@ instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where arr' <- markArrow arr return (CFS an' unp str arr' t' doc) -instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where +instance ExactPrint (HsConFieldSpec OnConField GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a exact (CFS an unp str mult t doc) = do ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -1049,7 +1049,7 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype) = -- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX ppRecFieldMultAnn unicode (CFS _ _ _ arr _ _) following = case arr of - HsUnannotated _ _ -> following + HsUnannotated _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following @@ -1318,7 +1318,7 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u = where arr = case mult of HsLinearAnn _ -> lollipop u - HsUnannotated _ _ -> arrow u + HsUnannotated _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u <+> arrow u ppr_mono_ty (HsTyVar _ NotPromoted (L _ name)) _ = ppDocName name ppr_mono_ty (HsTyVar _ IsPromoted (L _ name)) _ = char '\'' <> ppDocName name ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1557,7 +1557,7 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype) = -- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _ _) following = case arr of - HsUnannotated _ _ -> following + HsUnannotated _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following @@ -1821,7 +1821,7 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u q e = where arr = case mult of HsLinearAnn _ -> lollipop u - HsUnannotated _ _ -> arrow u + HsUnannotated _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u q e <+> arrow u ppr_mono_ty (HsTupleTy _ con tys) u q _ = tupleParens con (map (ppLType u q HideEmptyContexts) tys) ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -990,9 +990,9 @@ synifyMult vs t = case t of ManyTy -> HsUnrestrictedArrow noExtField ty -> HsExplicitMult noExtField (synifyType WithinType vs ty) -synifyMultRec :: [TyVar] -> Mult -> HsMultAnnOn OnRecField (LHsType GhcRn) GhcRn +synifyMultRec :: [TyVar] -> Mult -> HsMultAnnOn OnConField (LHsType GhcRn) GhcRn synifyMultRec vs t = case t of - OneTy -> HsUnannotated HsUnannOne noExtField + OneTy -> HsUnannotated noExtField ty -> HsExplicitMult noExtField (synifyType WithinType vs ty) synifyPatSynType :: PatSyn -> LHsType GhcRn ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -341,7 +341,7 @@ renameMaybeInjectivityAnn renameMaybeInjectivityAnn = traverse renameInjectivityAnn renameMultAnnOn :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> RnM (HsMultAnnOn on (LHsType DocNameI) DocNameI) -renameMultAnnOn (HsUnannotated mult _) = return (HsUnannotated mult noExtField) +renameMultAnnOn (HsUnannotated _) = return (HsUnannotated noExtField) renameMultAnnOn (HsLinearAnn _) = return (HsLinearAnn noExtField) renameMultAnnOn (HsExplicitMult _ p) = HsExplicitMult noExtField <$> renameLType p View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bd8f0ccd2dd0a0bebf8c7ee09b81f6111e7fa075 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bd8f0ccd2dd0a0bebf8c7ee09b81f6111e7fa075 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 16:30:00 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 23 Jan 2025 11:30:00 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/coreprep-sat-name Message-ID: <67926e88a5261_3e7a8e8522949362e@gitlab.mail> Ben Gamari pushed new branch wip/coreprep-sat-name at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/coreprep-sat-name You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 16:36:03 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 11:36:03 -0500 Subject: [Git][ghc/ghc][wip/T18462] Unannotated multiplicity based on type Message-ID: <67926ff32a56b_3e7a8e10b5a58938eb@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: b657e6d2 by Sjoerd Visscher at 2025-01-23T17:35:42+01:00 Unannotated multiplicity based on type - - - - - 27 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/printer/T18791.stderr - utils/check-exact/ExactPrint.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 Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -539,11 +539,11 @@ deriving instance Data (HsTyLit GhcTc) -- deriving instance (Data mult, DataIdLR p p, Typeable on) => Data (HsMultAnnOn on mult p) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsType GhcPs)) GhcPs) -deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsType GhcPs)) GhcPs) +deriving instance Data (HsMultAnnOn OnConField (LocatedA (HsType GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcTc)) GhcTc) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsExpr GhcPs)) GhcPs) -deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsExpr GhcPs)) GhcPs) +deriving instance Data (HsMultAnnOn OnConField (LocatedA (HsExpr GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcTc)) GhcTc) @@ -559,7 +559,7 @@ deriving instance Data (ConDeclField GhcTc) -- deriving instance (DataIdLR p p, Typeable on) => Data (HsConFieldSpec on p) deriving instance Data (HsConFieldSpec OnArrow GhcPs) -deriving instance Data (HsConFieldSpec OnRecField GhcPs) +deriving instance Data (HsConFieldSpec OnConField GhcPs) deriving instance Typeable on => Data (HsConFieldSpec on GhcRn) deriving instance Typeable on => Data (HsConFieldSpec on GhcTc) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -26,9 +26,9 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( Mult, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), - HsUnannotatedMult(..), pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, + pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, EpLinearArrow(..), - hsNoMultAnn, isUnrestricted, hsMultIsLinear, + hsNoMultAnn, isUnrestricted, pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, @@ -129,7 +129,7 @@ import GHC.Utils.Outputable import GHC.Utils.Misc (count) import Data.Maybe -import Data.Data (Data) +import Data.Data (Data, Proxy (..)) import qualified Data.Semigroup as S import GHC.Data.Bag @@ -531,39 +531,46 @@ instance NoAnn EpLinearArrow where noAnn = EpPct1 noAnn noAnn type instance XUnannotated OnArrow _ GhcPs = TokRarrow -type instance XUnannotated OnRecField _ GhcPs = TokDcolon +type instance XUnannotated OnConField _ GhcPs = TokDcolon type instance XUnannotated _ _ GhcRn = NoExtField type instance XUnannotated _ _ GhcTc = NoExtField type instance XLinearAnn OnArrow _ GhcPs = EpLinearArrow -type instance XLinearAnn OnRecField _ GhcPs = (EpToken "%1", TokDcolon) +type instance XLinearAnn OnConField _ GhcPs = (EpToken "%1", TokDcolon) type instance XLinearAnn _ _ GhcRn = NoExtField type instance XLinearAnn _ _ GhcTc = NoExtField type instance XExplicitMult OnArrow _ GhcPs = (EpToken "%", TokRarrow) -type instance XExplicitMult OnRecField _ GhcPs = (EpToken "%", TokDcolon) +type instance XExplicitMult OnConField _ GhcPs = (EpToken "%", TokDcolon) type instance XExplicitMult _ _ GhcRn = NoExtField type instance XExplicitMult _ _ GhcTc = NoExtField type instance XXMultAnnOn _ _ (GhcPass _) = DataConCantHappen -hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => HsMultAnnOn on (LHsType GhcPs) GhcPs -hsNoMultAnn = HsUnannotated HsUnannOne noAnn +hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) + => HsMultAnnOn on (LHsType GhcPs) GhcPs +hsNoMultAnn = HsUnannotated noAnn isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (multAnnToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName isUnrestricted _ = False -multAnnToHsType :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> LHsType GhcRn +multAnnToHsType :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> LHsType GhcRn multAnnToHsType = expandHsMultAnnOn (HsTyVar noAnn NotPromoted) -- | Convert an multiplicity annotation into its corresponding multiplicity. -- In essence this erases the information of whether the programmer wrote an explicit -- multiplicity or a shorthand. -- In this polymorphic function, `t` can be `HsType` or `HsExpr` -expandHsMultAnnOn :: (LocatedN Name -> t GhcRn) -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn -> LocatedA (t GhcRn) -expandHsMultAnnOn mk_var (HsUnannotated HsUnannOne _) = noLocA (mk_var (noLocA oneDataConName)) -expandHsMultAnnOn mk_var (HsUnannotated HsUnannMany _) = noLocA (mk_var (noLocA manyDataConName)) +expandHsMultAnnOn :: forall on t. IsHsMultAnnOnWhat on + => (LocatedN Name -> t GhcRn) + -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn + -> LocatedA (t GhcRn) +expandHsMultAnnOn mk_var (HsUnannotated _) = noLocA (mk_var (noLocA mult)) + where + mult = case hsMultAnnOnWhat (Proxy :: Proxy on) of + OnArrow -> manyDataConName + OnConField -> oneDataConName expandHsMultAnnOn mk_var (HsLinearAnn _) = noLocA (mk_var (noLocA oneDataConName)) expandHsMultAnnOn _mk_var (HsExplicitMult _ p) = p @@ -574,7 +581,7 @@ instance -- See #18846 pprHsArrow :: (Outputable mult, OutputableBndrId pass) => HsArrowOf mult (GhcPass pass) -> SDoc -pprHsArrow (HsUnannotated _ _) = pprArrowWithMultiplicity visArgTypeLike (Left False) +pprHsArrow (HsUnannotated _) = pprArrowWithMultiplicity visArgTypeLike (Left False) pprHsArrow (HsLinearAnn _) = pprArrowWithMultiplicity visArgTypeLike (Left True) pprHsArrow (HsExplicitMult _ p) = pprArrowWithMultiplicity visArgTypeLike (Right (ppr p)) @@ -591,7 +598,7 @@ instance OutputableBndrId p ppr_mult :: HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc ppr_mult mult tyDoc = case mult of - HsUnannotated _ _ -> dcolon <+> tyDoc + HsUnannotated _ -> dcolon <+> tyDoc HsLinearAnn _ -> text "%1" <+> dcolon <+> tyDoc HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon <+> tyDoc @@ -1308,7 +1315,7 @@ pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty doc) = pprHsConFieldSpecNoMult :: (OutputableBndrId p) => HsConFieldSpec on (GhcPass p) -> SDoc pprHsConFieldSpecNoMult = pprHsConFieldSpecWith (\_ d -> d) -hsPlainTypeField :: LHsType GhcPs -> HsConFieldSpec OnArrow GhcPs +hsPlainTypeField :: NoAnn (XLinearAnn on (LHsType GhcPs) GhcPs) => LHsType GhcPs -> HsConFieldSpec on GhcPs hsPlainTypeField = mkConFieldSpec (HsLinearAnn noAnn) mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -86,6 +86,7 @@ import GHC.Types.Name.Env import GHC.TypeLits import Data.Kind (Constraint) +import Data.Proxy import qualified GHC.LanguageExtensions as LangExt @@ -2861,14 +2862,22 @@ repGadtDataCons cons details res_ty -- TH currently only supports linear constructors. -- We also accept the (->) arrow when -XLinearTypes is off, because this -- denotes a linear field. -verifyLinearFields :: [HsConFieldSpec on GhcRn] -> MetaM () +verifyLinearFields :: forall on. IsHsMultAnnOnWhat on => [HsConFieldSpec on GhcRn] -> MetaM () verifyLinearFields ps = do linear <- lift $ xoptM LangExt.LinearTypes let allGood = all (hsMultIsLinear linear . cfs_multiplicity) ps unless allGood $ notHandled ThNonLinearDataCon + where + hsMultIsLinear linearTypesEnabled (HsUnannotated _) = + case hsMultAnnOnWhat (Proxy :: Proxy on) of + OnArrow -> not linearTypesEnabled + OnConField -> True + hsMultIsLinear _ HsLinearAnn{} = True + hsMultIsLinear _ _ = False -- Desugar the arguments in a data constructor declared with prefix syntax. -repPrefixConArgs :: [HsConFieldSpec OnArrow GhcRn] +repPrefixConArgs :: IsHsMultAnnOnWhat on + => [HsConFieldSpec on GhcRn] -> MetaM (Core [M TH.BangType]) repPrefixConArgs ps = do verifyLinearFields ps @@ -2885,7 +2894,7 @@ repRecConArgs lips = do where rep_ip ip = mapM (rep_one_ip (cd_fld_spec ip)) (cd_fld_names ip) - rep_one_ip :: HsConFieldSpec OnRecField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) + rep_one_ip :: HsConFieldSpec OnConField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) rep_one_ip t n = do { MkC v <- lookupOcc (unLoc . foLabel $ unLoc n) ; MkC ty <- repConFieldSpec t ; rep2 varBangTypeName [v,ty] } ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1795,7 +1795,7 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where , toHie decls ] -instance ToHie (HsConFieldSpec on GhcRn) where +instance IsHsMultAnnOnWhat on => ToHie (HsConFieldSpec on GhcRn) where toHie (CFS _ _ _ w t doc) = concatM [ toHie (multAnnToHsType w) , toHie t ===================================== compiler/GHC/Parser.y ===================================== @@ -2601,7 +2601,7 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3)))} + (mkConFieldSpec (HsUnannotated (epUniTok $2)) $3)))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) (ConDeclField noExtField ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3520,7 +3520,7 @@ mkMultAnn pct t@(L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) pct1 = epTokenWidenR pct (locA (getLoc t)) mkMultAnn pct t = HsMultAnn pct t -mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnRecField GhcPs +mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnConField GhcPs mkMultField pct (L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) col t -- See #18888 for the use of (SourceText "1") above = mkConFieldSpec (HsLinearAnn (pct1, col)) t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -706,7 +706,7 @@ rnHsMultAnnOn env = rnHsMultAnnOnWith (rnLHsTyKi env) rnHsMultAnnOnWith :: (LocatedA (mult GhcPs) -> RnM (LocatedA (mult GhcRn), FreeVars)) -> HsMultAnnOn on (LocatedA (mult GhcPs)) GhcPs -> RnM (HsMultAnnOn on (LocatedA (mult GhcRn)) GhcRn, FreeVars) -rnHsMultAnnOnWith _rn (HsUnannotated mult _) = pure (HsUnannotated mult noExtField, emptyFVs) +rnHsMultAnnOnWith _rn (HsUnannotated _) = pure (HsUnannotated noExtField, emptyFVs) rnHsMultAnnOnWith _rn (HsLinearAnn _) = pure (HsLinearAnn noExtField, emptyFVs) rnHsMultAnnOnWith rn (HsExplicitMult _ p) = (\(mult, fvs) -> (HsExplicitMult noExtField mult, fvs)) <$> rn p ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1927,12 +1927,12 @@ rnDataDefn doc (HsDataDefn { dd_cType = cType, dd_ctxt = context, dd_cons = cond has_labelled_fields _ = False has_strictness_flags condecl - = any (isSrcStrict . cfs_bang) (con_args condecl) + = any isSrcStrict (con_arg_bangs condecl) - con_args (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = args - con_args (ConDeclH98 { con_args = PrefixCon _ args }) = args - con_args (ConDeclH98 { con_args = InfixCon arg1 arg2 }) = [arg1, arg2] - con_args _ = [] + con_arg_bangs (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = map cfs_bang args + con_arg_bangs (ConDeclH98 { con_args = PrefixCon _ args }) = map cfs_bang args + con_arg_bangs (ConDeclH98 { con_args = InfixCon arg1 arg2 }) = [cfs_bang arg1, cfs_bang arg2] + con_arg_bangs _ = [] {- Note [Type data declarations] ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -1387,7 +1387,7 @@ rn_ty_pat ty@(XHsType{}) = do liftRnFV $ rnHsType ctxt ty rn_ty_pat_arrow :: HsArrow GhcPs -> TPRnM (HsArrow GhcRn) -rn_ty_pat_arrow (HsUnannotated mult _) = pure (HsUnannotated mult noExtField) +rn_ty_pat_arrow (HsUnannotated _) = pure (HsUnannotated noExtField) rn_ty_pat_arrow (HsLinearAnn _) = pure (HsLinearAnn noExtField) rn_ty_pat_arrow (HsExplicitMult _ p) = rn_lty_pat p <&> (\mult -> HsExplicitMult noExtField mult) ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -991,7 +991,7 @@ expr_to_type earg = ; return (L l (HsFunTy noExtField mult' arg' res'))} where go_arrow :: HsArrowOf (LHsExpr GhcRn) GhcRn -> TcM (HsArrow GhcRn) - go_arrow (HsUnannotated mult _) = pure (HsUnannotated mult noExtField) + go_arrow (HsUnannotated _) = pure (HsUnannotated noExtField) go_arrow (HsLinearAnn{}) = pure (HsLinearAnn noExtField) go_arrow (HsExplicitMult _ exp) = HsExplicitMult noExtField <$> go exp go (L l (HsForAll _ tele expr)) = ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -947,7 +947,7 @@ concern things that the renamer can't handle. -} -tcMult :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tcMult :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tcMult hc = tc_mult typeLevelMode hc -- | Info about the context in which we're checking a type. Currently, @@ -1364,7 +1364,7 @@ Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in "GHC.Core.TyCo -} ------------------------------------------ -tc_mult :: TcTyMode -> HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tc_mult :: IsHsMultAnnOnWhat on => TcTyMode -> HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tc_mult mode ty = tc_check_lhs_type mode (multAnnToHsType ty) multiplicityTy ------------------------------------------ tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> ExpKind ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1806,7 +1806,8 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: ConArgKind -- Expected kind of the argument(s) +kcConArgTys :: IsHsMultAnnOnWhat on + => ConArgKind -- Expected kind of the argument(s) -> [HsConFieldSpec on GhcRn] -- User-written argument types -> TcM () kcConArgTys exp_kind arg_tys @@ -3988,7 +3989,8 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: IsHsMultAnnOnWhat on + => ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (CFS (_, src) unp str w bty _) @@ -4011,7 +4013,7 @@ tcRecConDeclFields exp_kind fields exploded = concatMap explode combined (_,btys) = unzip exploded -tcDataConMult :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tcDataConMult :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tcDataConMult arr@(HsUnrestrictedArrow _) = do -- See Note [Function arrows in GADT constructors] linearEnabled <- xoptM LangExt.LinearTypes ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -776,7 +776,8 @@ cvtSrcStrictness NoSourceStrictness = NoSrcStrict cvtSrcStrictness SourceLazy = SrcLazy cvtSrcStrictness SourceStrict = SrcStrict -cvt_arg :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) +cvt_arg :: (NoAnn (XUnannotated on (LHsType GhcPs) GhcPs), IsHsMultAnnOnWhat on) + => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) cvt_arg (Bang su ss, ty) = do { ty'' <- cvtType ty ; let ty' = parenthesizeHsType appPrec ty'' ===================================== compiler/Language/Haskell/Syntax/Decls.hs ===================================== @@ -1116,7 +1116,7 @@ or contexts in two parts: -- | The arguments in a Haskell98-style data constructor. type HsConDeclH98Details pass - = HsConDetails Void (HsConFieldSpec OnArrow pass) (XRec pass [LConDeclField pass]) + = HsConDetails Void (HsConFieldSpec OnConField pass) (XRec pass [LConDeclField pass]) -- The Void argument to HsConDetails here is a reflection of the fact that -- type applications are not allowed in data constructor declarations. ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -22,10 +22,9 @@ GHC.Hs.Type: Abstract syntax: user-defined types -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* module Language.Haskell.Syntax.Type ( - HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), + HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), IsHsMultAnnOnWhat(..), pattern HsUnrestrictedArrow, XUnannotated, XLinearAnn, XExplicitMult, XXMultAnnOn, - hsMultIsLinear, HsType(..), LHsType, HsKind, LHsKind, HsBndrVis(..), XBndrRequired, XBndrInvisible, XXBndrVis, @@ -919,28 +918,35 @@ data HsTyLit pass type HsArrow pass = HsArrowOf (LHsType pass) pass type HsArrowOf = HsMultAnnOn OnArrow --- HsMultAnnOn is used both to represent function arrows and multiplicity annotations --- in the record declaration syntax. But the default multiplicity is different --- between the two uses. In record syntax, the default is One, but on arrows, the --- default is Many. `HsUnannotatedMult` is used to distinguish between the two uses. -data HsUnannotatedMult = HsUnannOne | HsUnannMany - deriving (Eq, Ord, Data) - pattern HsUnrestrictedArrow :: XUnannotated on mult pass -> HsMultAnnOn on mult pass -pattern HsUnrestrictedArrow a = HsUnannotated HsUnannMany a - -data HsMultAnnOnWhat = OnArrow | OnRecField +pattern HsUnrestrictedArrow a = HsUnannotated a --- | Denotes the type of arrows in the surface language +-- HsMultAnnOn is used both to represent function arrows and multiplicity annotations +-- in the data declaration syntax. But the default multiplicity is different +-- between the two uses. In constructors, the default is One, but on arrows, the +-- default is Many. (But note that non-record GADT syntax follows the default of arrows.) +-- `HsMultAnnOnWhat` is used to distinguish between the two uses. +data HsMultAnnOnWhat = OnArrow | OnConField + +-- Get a value level representation of the `HsMultAnnOnWhat` kind. +class IsHsMultAnnOnWhat (on :: HsMultAnnOnWhat) where + hsMultAnnOnWhat :: proxy on -> HsMultAnnOnWhat +instance IsHsMultAnnOnWhat OnArrow where + hsMultAnnOnWhat _ = OnArrow +instance IsHsMultAnnOnWhat OnConField where + hsMultAnnOnWhat _ = OnConField + +-- | Denotes multiplicity annotations in the surface language data HsMultAnnOn (on :: HsMultAnnOnWhat) mult pass - = HsUnannotated HsUnannotatedMult !(XUnannotated on mult pass) - -- ^ a -> b or a → b + = HsUnannotated !(XUnannotated on mult pass) + -- ^ a -> b or a → b or { nm :: a } | HsLinearAnn !(XLinearAnn on mult pass) - -- ^ a %1 -> b or a %1 → b, or a ⊸ b + -- ^ a %1 -> b or a %1 → b, or a ⊸ b, or { nm %1 :: a } | HsExplicitMult !(XExplicitMult on mult pass) !mult - -- ^ a %m -> b or a %m → b (very much including `a %Many -> b`! + -- ^ a %m -> b or a %m → b or { nm %m :: a } + -- (very much including `a %Many -> b`! -- This is how the programmer wrote it). It is stored as an -- `HsType` so as to preserve the syntax as written in the -- program. @@ -952,12 +958,6 @@ type family XLinearAnn (on :: HsMultAnnOnWhat) mult p type family XExplicitMult (on :: HsMultAnnOnWhat) mult p type family XXMultAnnOn (on :: HsMultAnnOnWhat) mult p -hsMultIsLinear :: Bool -> HsMultAnnOn on mult pass -> Bool -hsMultIsLinear _ (HsUnannotated HsUnannOne _) = True -hsMultIsLinear linear (HsUnannotated HsUnannMany _) = not linear -hsMultIsLinear _ HsLinearAnn{} = True -hsMultIsLinear _ _ = False - {- Note [Unit tuples] ~~~~~~~~~~~~~~~~~~ @@ -1061,7 +1061,7 @@ data ConDeclField pass = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_spec :: HsConFieldSpec OnRecField pass } + cd_fld_spec :: HsConFieldSpec OnConField pass } | XConDeclField !(XXConDeclField pass) {- Note [ConDeclField pass] ===================================== testsuite/tests/ghc-api/exactprint/Test20239.stderr ===================================== @@ -257,7 +257,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { Test20239.hs:7:62-63 }) (NormalSyntax))) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr ===================================== @@ -254,7 +254,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { T17544_kw.hs:19:21-22 }) (NormalSyntax))) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr ===================================== @@ -951,7 +951,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:28:15-16 }) (NormalSyntax))) @@ -1024,7 +1023,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:29:15-16 }) (NormalSyntax))) @@ -1184,7 +1182,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:33:10-11 }) (NormalSyntax))) @@ -1257,7 +1254,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:34:10-11 }) (NormalSyntax))) @@ -1429,7 +1425,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:40:8-9 }) (NormalSyntax))) @@ -1502,7 +1497,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:42:8-9 }) (NormalSyntax))) ===================================== testsuite/tests/parser/should_compile/DumpParsedAst.stderr ===================================== @@ -254,7 +254,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:9:20-21 }) (NormalSyntax))) @@ -960,7 +959,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:14-15 }) (NormalSyntax))) @@ -993,7 +991,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:29-30 }) (NormalSyntax))) @@ -1020,7 +1017,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:20-21 }) (NormalSyntax))) @@ -1407,7 +1403,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:18:33-34 }) (NormalSyntax))) @@ -1540,7 +1535,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:21:22-23 }) (NormalSyntax))) @@ -1573,7 +1567,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:21:27-28 }) (NormalSyntax))) @@ -1699,7 +1692,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:30-31 }) (NormalSyntax))) @@ -1772,7 +1764,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:54-55 }) (NormalSyntax))) @@ -1799,7 +1790,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:45-46 }) (NormalSyntax))) @@ -1908,7 +1898,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:23:36-37 }) (NormalSyntax))) @@ -1980,7 +1969,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:23:27-28 }) (NormalSyntax))) ===================================== testsuite/tests/parser/should_compile/DumpRenamedAst.stderr ===================================== @@ -648,7 +648,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -757,7 +756,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -787,7 +785,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -906,7 +903,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -971,7 +967,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -994,7 +989,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1093,7 +1087,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1159,7 +1152,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1846,7 +1838,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1951,7 +1942,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1981,7 +1971,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -2004,7 +1993,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn ===================================== testsuite/tests/parser/should_compile/T14189.stderr ===================================== @@ -207,7 +207,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (NoExtField)) (L (EpAnn ===================================== testsuite/tests/printer/T18791.stderr ===================================== @@ -128,7 +128,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { T18791.hs:5:14-15 }) (NormalSyntax))) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -834,9 +834,9 @@ markEpUniToken (EpUniTok aa isUnicode) = do -- --------------------------------------------------------------------- markArrow :: (Monad m, Monoid w, ExactPrint a) => HsArrowOf a GhcPs -> EP w m (HsArrowOf a GhcPs) -markArrow (HsUnannotated t arr) = do +markArrow (HsUnannotated arr) = do arr' <- markEpUniToken arr - return (HsUnannotated t arr') + return (HsUnannotated arr') markArrow (HsLinearAnn (EpPct1 pct1 arr)) = do pct1' <- markEpToken pct1 arr' <- markEpUniToken arr @@ -850,11 +850,11 @@ markArrow (HsExplicitMult (pct, arr) t) = do arr' <- markEpUniToken arr return (HsExplicitMult (pct', arr') t') -markRecFieldMult :: (Monad m, Monoid w, ExactPrint a) => HsMultAnnOn OnRecField a GhcPs -> EP w m (HsMultAnnOn OnRecField a GhcPs) -markRecFieldMult (HsUnannotated t col) = do +markRecFieldMult :: (Monad m, Monoid w, ExactPrint a) => HsMultAnnOn OnConField a GhcPs -> EP w m (HsMultAnnOn OnConField a GhcPs) +markRecFieldMult (HsUnannotated col) = do traceM $ "markRecFieldMult:HsUnannotated" col' <- markEpUniToken col - return (HsUnannotated t col') + return (HsUnannotated col') markRecFieldMult (HsLinearAnn (pct1, col)) = do traceM $ "markRecFieldMult:HsLinearAnn" pct1' <- markEpToken pct1 @@ -4449,7 +4449,7 @@ instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where arr' <- markArrow arr return (CFS an' unp str arr' t' doc) -instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where +instance ExactPrint (HsConFieldSpec OnConField GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a exact (CFS an unp str mult t doc) = do ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -1049,7 +1049,7 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype) = -- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX ppRecFieldMultAnn unicode (CFS _ _ _ arr _ _) following = case arr of - HsUnannotated _ _ -> following + HsUnannotated _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following @@ -1318,7 +1318,7 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u = where arr = case mult of HsLinearAnn _ -> lollipop u - HsUnannotated _ _ -> arrow u + HsUnannotated _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u <+> arrow u ppr_mono_ty (HsTyVar _ NotPromoted (L _ name)) _ = ppDocName name ppr_mono_ty (HsTyVar _ IsPromoted (L _ name)) _ = char '\'' <> ppDocName name ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1557,7 +1557,7 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype) = -- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _ _) following = case arr of - HsUnannotated _ _ -> following + HsUnannotated _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following @@ -1821,7 +1821,7 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u q e = where arr = case mult of HsLinearAnn _ -> lollipop u - HsUnannotated _ _ -> arrow u + HsUnannotated _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u q e <+> arrow u ppr_mono_ty (HsTupleTy _ con tys) u q _ = tupleParens con (map (ppLType u q HideEmptyContexts) tys) ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -990,9 +990,9 @@ synifyMult vs t = case t of ManyTy -> HsUnrestrictedArrow noExtField ty -> HsExplicitMult noExtField (synifyType WithinType vs ty) -synifyMultRec :: [TyVar] -> Mult -> HsMultAnnOn OnRecField (LHsType GhcRn) GhcRn +synifyMultRec :: [TyVar] -> Mult -> HsMultAnnOn OnConField (LHsType GhcRn) GhcRn synifyMultRec vs t = case t of - OneTy -> HsUnannotated HsUnannOne noExtField + OneTy -> HsUnannotated noExtField ty -> HsExplicitMult noExtField (synifyType WithinType vs ty) synifyPatSynType :: PatSyn -> LHsType GhcRn ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -341,7 +341,7 @@ renameMaybeInjectivityAnn renameMaybeInjectivityAnn = traverse renameInjectivityAnn renameMultAnnOn :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> RnM (HsMultAnnOn on (LHsType DocNameI) DocNameI) -renameMultAnnOn (HsUnannotated mult _) = return (HsUnannotated mult noExtField) +renameMultAnnOn (HsUnannotated _) = return (HsUnannotated noExtField) renameMultAnnOn (HsLinearAnn _) = return (HsLinearAnn noExtField) renameMultAnnOn (HsExplicitMult _ p) = HsExplicitMult noExtField <$> renameLType p View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b657e6d2e2702c51f8f8de4efb27ff75d0c1e282 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b657e6d2e2702c51f8f8de4efb27ff75d0c1e282 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 16:42:23 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 23 Jan 2025 11:42:23 -0500 Subject: [Git][ghc/ghc][wip/coreprep-sat-name] 437 commits: Bump GHC version to 9.13 Message-ID: <6792716f4efc6_3e7a8e140401096340@gitlab.mail> Ben Gamari pushed to branch wip/coreprep-sat-name at Glasgow Haskell Compiler / GHC Commits: e4ac1b0d by Zubin Duggal at 2024-09-27T19:12:24+05:30 Bump GHC version to 9.13 - - - - - da20cac1 by Andreas Klebinger at 2024-10-02T22:18:48-04:00 SpecConstr: Introduce a separate argument limit for forced specs. We used to put no limit at all on specializations forced via the SPEC argument. This isn't always reasonable so we introduce a very high limit that applies to forced specializations, a flag to control it, and we now emit a warning if we fail a specialization because we exceed the warning. Fixes #25197 - - - - - 39497eed by Andreas Klebinger at 2024-10-02T22:19:24-04:00 ghc-experimental: Expose primops and ghc extensions via GHC.PrimOps This will be the new place for functions that would have gone into GHC.Exts in the past but are not stable enough to do so now. Addresses #25242 - - - - - e9dc2690 by Sylvain Henry at 2024-10-02T22:20:06-04:00 RTS: cleanup timerfd file descriptors after a fork (#25280) When we init a timerfd-based ticker, we should be careful to cleanup the old file descriptors (e.g. after a fork). - - - - - 64e876bc by Rodrigo Mesquita at 2024-10-02T22:20:43-04:00 determinism: Deterministic MonadGetUnique LlvmM Update LlvmM to thread a unique deterministic supply (using UniqDSMT), and use it in the MonadGetUnique instance. This makes uniques sampled from LlvmM deterministic, which guarantees object determinism with -fllvm. Fixes #25274 - - - - - 36bbb167 by Matthew Pickering at 2024-10-02T22:21:18-04:00 Bump LLVM upper bound to allow LLVM 19 Also bumps the ci-images commit so that the deb12 images uses LLVM 19 for testing. ------------------------- Metric Decrease: size_hello_artifact_gzip size_hello_unicode_gzip ------------------------- Fixes #25295 - - - - - 0029ca91 by Matthew Pickering at 2024-10-02T22:21:54-04:00 configure: Allow happy-2.0.2 happy-2.0.2 can be used to compile GHC. happy-2.0 and 2.0.1 have bugs which make it unsuitable to use. The version bound is now == 1.20.* || >= 2.0.2 && < 2.1 Fixes #25276 - - - - - 92976985 by ARATA Mizuki at 2024-10-02T22:22:35-04:00 Use bundled llc/opt on Windows (#22438) - - - - - af59749a by Matthew Pickering at 2024-10-02T22:23:11-04:00 Fix registerArch for riscv64 The register allocator doesn't support vector registers on riscv64, therefore advertise as NoVectors. Fixes #25314 - - - - - a49e66fc by Matthew Pickering at 2024-10-02T22:23:11-04:00 riscv: Avoid using csrr instruction to test for vector registers The csrr instruction isn't allowed in qemu user-mode, and raises an illegal instruction error when it is encountered. Therefore for now, we just hard-code that there is no support for vector registers since the rest of the compiler doesn't support vector registers for riscv. Fixes #25312 - - - - - 115a30e9 by Andreas Klebinger at 2024-10-02T22:23:11-04:00 Add support for fp min/max to riscv Fixes #25313 - - - - - f28b5992 by Ben Gamari at 2024-10-02T22:23:47-04:00 testsuite/perf: Report better error message on malformed note Previously a malformed perf note resulted in very poor errors. Here we slight improve this situation. - - - - - 51377508 by Ben Gamari at 2024-10-02T22:23:47-04:00 testsuite: Handle division-by-zero more gracefully Previously we would fail with an ZeroDivisionError. Fixes #25321 - - - - - 50490075 by Matthew Pickering at 2024-10-03T05:55:13-04:00 ci: Add nightly & release ubuntu-22.04 jobs This adds build of bindists on ubuntu-22.04 on nightly and release pipelines. We also update ghcup-metadata to provide ubuntu-22.04 bindists on ubuntu-22.04. Fixes #25317 - - - - - 9cf1cef5 by Zubin Duggal at 2024-10-03T05:55:49-04:00 haddock: Bump binary interface version to 46. This allows haddock to give good error messages when being used on mismatched interface files. We bump to 46 since GHC 9.12 uses version 45: https://gitlab.haskell.org/ghc/ghc/-/commit/362afd632032ee8f174690c3ffe0015076b83ce6 This should have been done in e4ac1b0d281b85a0144d1ef6f84a1df00e236052 but was overlooked. - - - - - 2293c0b7 by Andreas Klebinger at 2024-10-03T05:56:25-04:00 Change versionig of ghc-experimental to follow ghc versions. Just like ghc-internal it will now use the @ProjectVersionForLib@ macro for versioning. This means for ghc=9.10.1, ghc-experimental's version will be 9.1001.0 and so on. This fixes #25289 - - - - - 876d6e0e by Ben Gamari at 2024-10-04T15:07:53+01:00 base: Add `HasCallStack` constraint to `ioError` As proposed in core-libraries-committee#275. - - - - - 9bfd9fd0 by Matthew Pickering at 2024-10-04T15:08:03+01:00 Fix toException method for ExceptionWithContext Fixes #25235 - - - - - ac004028 by Matthew Pickering at 2024-10-04T15:09:07+01:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - bcb293f2 by Cheng Shao at 2024-10-04T17:59:28-04:00 testsuite: remove accidentally checked in debug print logic - - - - - 68e2da5a by Rodrigo Mesquita at 2024-10-05T10:36:15-04:00 Deprecation for WarnCompatUnqualifiedImports Fixes #25330 - - - - - 4327f0e8 by Andrew Lelechenko at 2024-10-05T10:36:52-04:00 Restrict Data.List.NonEmpty.unzip to NonEmpty (a, b) -> (NonEmpty a, NonEmpty b) Implementing the final phase of CLC proposal https://github.com/haskell/core-libraries-committee/issues/86 - - - - - ceca9efb by Cheng Shao at 2024-10-06T02:18:31+00:00 driver: fix runWorkerLimit on wasm This commit fixes link-time unresolved symbol errors for sem_open etc on wasm, by making runWorkerLimit always behave single-threaded. This avoids introducing the jobserver logic into the final wasm module and thus avoids referencing the posix semaphore symbols. - - - - - 135fd1ac by Torsten Schmits at 2024-10-06T02:18:31+00:00 Parallelize getRootSummary computations in dep analysis downsweep This reuses the upsweep step's infrastructure to process batches of modules in parallel. I benchmarked this by running `ghc -M` on two sets of 10,000 modules; one with a linear dependency chain and the other with a binary tree. Comparing different values for the number of modules per thread suggested an optimum at `length targets `div` (n_cap * 2)`, with results similar to this one (6 cores, 12 threads): ``` Benchmark 1: linear 1 jobs Time (mean ± σ): 1.775 s ± 0.026 s [User: 1.377 s, System: 0.399 s] Range (min … max): 1.757 s … 1.793 s 2 runs Benchmark 2: linear 6 jobs Time (mean ± σ): 876.2 ms ± 20.9 ms [User: 1833.2 ms, System: 518.6 ms] Range (min … max): 856.2 ms … 898.0 ms 3 runs Benchmark 3: linear 12 jobs Time (mean ± σ): 793.5 ms ± 23.2 ms [User: 2318.9 ms, System: 718.6 ms] Range (min … max): 771.9 ms … 818.0 ms 3 runs ``` Results don't differ much when the batch size is reduced to a quarter of that, but there's significant thread scheduling overhead for a size of 1: ``` Benchmark 1: linear 1 jobs Time (mean ± σ): 2.611 s ± 0.029 s [User: 2.851 s, System: 0.783 s] Range (min … max): 2.591 s … 2.632 s 2 runs Benchmark 2: linear 6 jobs Time (mean ± σ): 1.189 s ± 0.007 s [User: 2.707 s, System: 1.103 s] Range (min … max): 1.184 s … 1.194 s 2 runs Benchmark 3: linear 12 jobs Time (mean ± σ): 1.097 s ± 0.006 s [User: 2.938 s, System: 1.300 s] Range (min … max): 1.093 s … 1.101 s 2 runs ``` Larger batches also slightly worsen performance. - - - - - 535a2117 by Daniel Díaz at 2024-10-06T09:51:46-04:00 Clarify the meaning of "exactly once" in LinearTypes Solves documentaion issue #25084. - - - - - 92f8939a by Krzysztof Gogolewski at 2024-10-06T09:52:22-04:00 Only allow (a => b) :: Constraint rather than CONSTRAINT rep Fixes #25243 - - - - - 4a2f0f13 by Alan Zimmerman at 2024-10-07T05:16:54-04:00 EPA: Remove unused hsCaseAnnsRest We never populate it, so remove it. - - - - - 5099057b by John Paul Adrian Glaubitz at 2024-10-07T05:17:40-04:00 rts: Fix invocation of __ieee_set_fp_control() on alpha-linux Fixes the following error when building GHC on alpha-linux: rts/posix/Signals.c: In function ‘initDefaultHandlers’: rts/posix/Signals.c:709:5: error: error: implicit declaration of function ‘ieee_set_fp_control’ [-Wimplicit-function-declaration] 709 | ieee_set_fp_control(0); | ^~~~~~~~~~~~~~~~~~~ | 709 | ieee_set_fp_control(0); | - - - - - c9590ba0 by Teo Camarasu at 2024-10-07T05:18:17-04:00 Add changelog entries for !12479 - - - - - bf9c9566 by Matthew Pickering at 2024-10-07T13:19:30-04:00 javascript: Read fields of ObjectBlock lazily When linking a module with a large dependency footprint too much of the object files were forced during linking. This lead to a large amount of memory taken up by thunks which would never be forced On the PartialDownsweep test this halves the memory required (from 25G to 13G). Towards #25324 ------------------------- Metric Increase: size_hello_obj ------------------------- - - - - - 571329df by Matthew Pickering at 2024-10-07T13:20:06-04:00 ci: Run the i386 validation job when i386 label is set This is helpful when making changes to base and must update the javascript and i386 base exports files. - - - - - e68f9aaf by Matthew Pickering at 2024-10-07T13:20:42-04:00 Rewrite partitionByWorkerSize to avoid pattern match checker bug With `-g3` the pattern match checker would warn about these incomplete patterns. This affects the debug_info builds on CI. ``` Pattern match(es) are non-exhaustive In an equation for ‘go’: Patterns of type ‘[a]’, ‘[a]’, ‘[SpecFailWarning]’ not matched: (_:_) _ _ | 2514 | go [] small warnings = (small, warnings) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... ``` Workaround for #25338 - - - - - d915dc8b by Arnaud Spiwack at 2024-10-07T19:23:00-04:00 Remove the wrapper/coercion-passing logic for submultiplicity checks Instead, we use a dedicated DelayedError, which is emitted systematically on submultiplicity checks, but is suppressed if we can indeed solve the submultiplicity constraint with a reflexivity coercion. This way, we don't have to return anything from `tcSubMult`, which now looks like a regular constraint check, the rest is implementation detail. This removes all of the strange boilerplate that I'd been struggling with under the previous implementation. Even if submultiplicity checks are not properly constraints, this way it's contained entirely within a `WantedConstraint`. Much more pleasant. Closes #25128. - - - - - 1d226116 by Sven Tennie at 2024-10-07T19:23:37-04:00 AArch64: Implement switch/jump tables (#19912) This improves the performance of Cmm switch statements (compared to a chain of if statements.) - - - - - 3fe621dd by Mario Blažević at 2024-10-07T19:24:18-04:00 Fixes #25256, missing parens inside TH-printed pattern type signature - - - - - ea4b4391 by ARATA Mizuki at 2024-10-07T19:24:59-04:00 Better documentation for floatRange function Closes #16479 - - - - - ff09205c by Andreas Klebinger at 2024-10-07T19:25:35-04:00 Adjust progress message for hadrian to include cwd. Fixes #25335 - - - - - 5fd320da by Sven Tennie at 2024-10-07T19:26:12-04:00 CCallConv test: Align argument types The C calling convention / standard requires that arguments and their values are of the same type. - - - - - c6e5fd3d by Cheng Shao at 2024-10-07T19:26:47-04:00 hadrian: remove unused ghciWithDebugger field from flavour config This patch removes the ghciWithDebugger field from flavour config since it's actually not used anywhere. - - - - - 9c9c790d by sheaf at 2024-10-07T19:27:23-04:00 user's guide: update docs for X86 CPU flags This commit updates the section of the user's guide pertaining to X86 feature flags with the following changes: - the NCG backend now supports SIMD, so remove all text that says the contrary, - the LLVM backend does not "automatically detect" features, so remove any text that makes that claim. - - - - - a1ecc826 by Sven Tennie at 2024-10-08T13:36:03-04:00 ci: RISCV64 cross-compile testing This adds a validation job which tests that we can build a riscv64 cross compiler and build a simple program using it. We do not currently run the whole testsuite. Towards #25254 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - d5c2577f by Arnaud Spiwack at 2024-10-08T13:36:44-04:00 Remove unused accumulators in partition_errors - - - - - 55609880 by Andrzej Rybczak at 2024-10-09T16:41:46-04:00 Fix typo in the @since annotation of annotateIO - - - - - ef481813 by Alan Zimmerman at 2024-10-09T16:42:23-04:00 EPA: Remove [AddEpAnn] from (most of) HsExpr EPA: introduce EpAnnLam for lambda annotationsi, and remove `glAA` from `Parser.y`, it is the same as `glR` EPA: Remove unused annotation from XOpApp EPA: Use EpToken for XNPat and XNegApp EPA: specific anns for XExplicitTuple / XTuplePat / sumPatParens. EPA: Use specific annotation for MultiIf EPA: Move annotations into FunRhs EPA: Remove [AddEpAnn] from SigPat and ExprWithTySig EPA: Remove [AddEpAnn] from ArithSeq EPA: Remove [AddEpAnn] from HsProc EPA: Remove [AddEpAnn] from HsStatic EPA: Remove [AddEpAnn] from BindStmt EPA: Remove [AddEpAnn] from TransStmt EPA: Remove [AddEpAnn] from HsTypedSplice EPA: Remove [AddEpAnn] from HsUntypedSpliceExpr - - - - - 69960230 by Fabian Thorand at 2024-10-10T19:03:59+00:00 Handle exceptions from IO manager backend If an IO manager backend throws, it will not actually have registered the file descriptor. However, at that point, the IO manager state was already updated to assume the file descriptor is being tracked, leading to errors and an eventual deadlock down the line as documented in the issue #21969. The fix for this is to undo the IO manager state change in case the backend throws (just as we already do when the backend signals that the file type is not supported). The exception then bubbles up to user code. That way we make sure that 1. the bookkeeping state of the IO manager is consistent with the actions taken by the backend, even in the presence of unexpected failures, and 2. the error is not silent and visible to user code, making failures easier to debug. - - - - - 1587cccf by Hassan Al-Awwadi at 2024-10-11T03:52:36-04:00 Put RdrName in the foExt field of FieldOcc The main purpose of this commit is to rip RdrName out of FieldOcc, in accordance with #21592, and as a side note it has simplified the method we use to deal with ambiguity somewhat. To do the first, we make FieldOccs store (LIdP p) instead of always storing Located RdrName, and moved the readername to the extension points where necessary. For the second, well, we just turn an ambiguous RdrName into a unbound Name through mkUnboundName. Later during disambiguateRecordBinds of the type checking phase, we will try and do type-directed disambiguation based on the rdrName field (for now), so this hack works out fine. See Note [Ambiguous FieldOcc in record updates] for more details. There are two additional minor changes in this commit: * The HsRecSel constructor of HsExpr has been moved to the extension constuctors, since its really GHC specific. * HsProjection no longer has a Located DotFieldOcc as a field, but just a regular DotFieldOcc, since DotFieldOcc already wraps a located FieldLabelString co-authored by: @Jade <Jade512 at proton.me> @alt-romes <rodrigo.m.mesquita at gmail.com> - - - - - 2338a971 by Cheng Shao at 2024-10-11T03:53:13-04:00 driver: bail out when -fllvm is passed to GHC not configured with LLVM This patch makes GHC bail out with an proper error message when it's not configured with LLVM but users attempt to pass -fllvm, see #25011 and added comment for details. Fixes #25011 Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - 78ad81ec by Cristiano Moraes at 2024-10-11T03:53:55-04:00 configure: Find C++ probing when GCC version is the latest but G++ is old #23118 - - - - - 083703a1 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Consider Wanteds with rewriters as insoluble This MR fixes #25325 See GHC.Tc.Types.Constraint, Note [Insoluble Wanteds], especially (IW2) There is a small change in the error message for T14172, but it looks entirely acceptable to me. - - - - - 0dfaeb66 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Wibbles - - - - - 09d24d82 by Simon Peyton Jones at 2024-10-11T03:54:32-04:00 Spelling errors - - - - - 694489ed by sheaf at 2024-10-11T03:55:14-04:00 LLVM: use sse4.2 instead of sse42 LLVM expects the former instead of the latter since version 3.4. Fixes #25019 - - - - - 06ae8507 by sheaf at 2024-10-11T03:55:14-04:00 LLVM: make SSE4.2 imply +popcnt For consistency with the NCG as well as with Clang and GCC, we make the SSE4.2 feature flag imply +popcnt when using the LLVM backend. Fixes #25353 - - - - - 3fe843c7 by Cheng Shao at 2024-10-11T03:55:50-04:00 Drop obsolete libffi Makefile This patch drops obsolete libffi Makefile from the tree, given it's completely unused since removal of make build system in !7094. - - - - - df70405c by Ben Gamari at 2024-10-11T03:56:26-04:00 ghc-internal: Fix incomplete matches on IOError As noted in #25362, these incomplete matches were previously not being warned about. They were easily addressed by use of `GHC.Internal.Event.Windows.withException`. Closes #25362. - - - - - 8584504b by Matthew Pickering at 2024-10-11T03:57:02-04:00 compiler: Fix orientation of GHC.Hs.Doc boot file We should be free to import things from Language.Haskell.Syntax in GHC modules. Therefore the the boot file for the loop between ImpExp and GHC.Hs.Doc was in the wrong place. Issue #21592 - - - - - d029f170 by Ben Gamari at 2024-10-11T23:43:17-04:00 testsuite: Normalise trailing digits from hole fits output The type variables in the holes fit output from `abstract_refinement_hole_fits` is quite sensitive to compiler configuration. Specifically, a slight change in the inlining behavior of `throw` changes type variable naming in `(>>=)` and a few others. Ideally we would make hole fits output more deterministic but in the meantime we simply normalise this difference away as it not relevant to the test's goal. - - - - - da5d7d0d by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Add test for #25066 - - - - - eb7ddae1 by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Fix #25066 As noted in #25066, the exception backtrace proposal introduced a rather subtle performance regression due to simplification producing Core which the demand analyser concludes may diverge with a precise exception. The nature of the problem is more completely described in the new Note [Hiding precise exception signature in throw]. The (rather hacky) solution we use here hides the problematic optimisation through judicious use of `noinline`. Ultimately however we will want a more principled solution (e.g. #23847). Fixes #255066 CLC proposal: https://github.com/haskell/core-libraries-committee/issues/290 Metric Decrease: T9872d - - - - - 0060ece7 by Ben Gamari at 2024-10-11T23:43:17-04:00 base: Improve documentation of Control.Exception.Backtrace - - - - - 18f532f3 by Ben Gamari at 2024-10-11T23:43:53-04:00 Bump process submodule to v1.6.25.0 - - - - - a9a3badf by Hassan Al-Awwadi at 2024-10-11T23:44:29-04:00 Move HsInteger and HsRat to an extension constructor These constructors were only used during the TC stage, or during template haskell. It seemed clear that it was independent of the source syntax represented in L.H.S, and thus we removed it according to #21592. - - - - - 4dd30cba by Artem Pelenitsyn at 2024-10-11T23:45:09-04:00 Docs: Linear types: link Strict Patterns subsection Also, fix a bug in RST with missing newline before a listing. Co-authored-by: Arnaud Spiwack <arnaud at spiwack.net> - - - - - adca5f2b by Ben Gamari at 2024-10-11T23:45:45-04:00 users guide: Address remaining TODOs in eventlog format docs Closes #25296. - - - - - 9291c125 by Sylvain Henry at 2024-10-11T23:46:26-04:00 Fix z-encoding of tuples (#25364) Tuples with prefix/suffix strings weren't always properly encoded with their shortcut notations. Fix this. - - - - - c08b68bc by Sven Tennie at 2024-10-11T23:47:01-04:00 Delete constants that can be deduced There are macros in MachRegs.h to figure those out. - - - - - 8b402da2 by Zubin Duggal at 2024-10-12T20:36:57+00:00 hadrian: Handle broken symlinks properly when creating source dist directories If we have a broken symlink in the repository, don't try to `need` the symlink or the target of the symlink. Attempting to do so has `shake` attempt to read the target to compute its hash, which fails because the target doesn't exist. - - - - - 16f97667 by Zubin Duggal at 2024-10-12T20:36:57+00:00 hadrian: exclude cabal.project.symlink.broken from source archives Cabal 3.14 introduced a broken symlink in its testsuite. Unfortunately, this broke our source distribution as we use use `tar --dereference` to avoid issues with symlink compatibility on windows, and `tar --dereference` chokes when it encounters any broken symlinks. We can't get rid of `--dereference` because symlinks are generally broken on windows, so the only option is to exclude this file from source archives. see also https://github.com/haskell/cabal/issues/10442 - - - - - f1a2c9fc by Zubin Duggal at 2024-10-12T20:36:57+00:00 Bump Cabal submodule to 3.14 Metric Decrease: MultiLayerModulesTH_OneShot Metric Increase: haddock.Cabal - - - - - 745dd590 by Ben Gamari at 2024-10-14T09:13:12-04:00 users-guide: Document GHCi :where command Resolve #24509. - - - - - e9cc4699 by Alan Zimmerman at 2024-10-14T09:13:48-04:00 EPA: Remove [AddEpAnn] from IE, Pat and some Tys EPA: Remove [AddEpAnn] from LazyPat EPA: Remove [AddEpAnn] from RecordCon/RecordUpd/ConPat EPA: Remove [AddEpAnn] from HsFieldBind EPA: Remove [AddEpAnn] from PatSynBind EPA: Remove [AddEpAnn] from IPBind EPA: Remove [AddEpAnn] from FixSig EPA: Remove [AddEpAnn] from activation rules EPA: Remove [AddEpann] from SpecInstSig EPA: Remove [AddEpAnn] from MinimalSig EPA: Remove [AddEpAnn] from SCCFunSig EPA: Remove [AddEpAnn] from CompleteMatchSig EPA: Remove [AddEpAnn] from AnnSig, as used in PatSynSig, ClassOpSig, TypeSig EPA: Remove [AddEpAnn] from IEThingAbs EPA: Remove [AddEpAnn] from IEThingAll / IEThingWith EPA: Remove [AddEpAnn] from IEModuleContents EPA: Remove [AddEpAnn] from HsOpTy EPA: Remove [AddEpAnn] for various binders EPA: Remove [AddEpAnn] for HsIParamTy - - - - - 81a570bf by Sebastian Graf at 2024-10-14T22:15:31-04:00 Desugaring, plus -Wincomplete-record-selectors This commit does several related things: * Major refactor of the handling of applications in the desugarer. Now all applications are handled in `dsApp`, `ds_app` and related functions. This dramatically simplifies the code and removes complicated cruft that had accumulated. Hooray. Fixes #25281. * Improve the handling of -Wincomplete-record-selectors. We now incorporate the result type of unsaturated record selector applications as well as consider long-distance information in getField applications. Plus, the implmentation now builds the improved `dsApp` stuff above, so it is much easier to understand. Plus, incorporates improved error message wording suggested by Adam Gundry in !12685. Fixes #24824, #24891 See the long Note [Detecting incomplete record selectors] * Add -Wincomplete-record-selectors to -Wall, as specified in GHC Proposal 516. To do this, I also had to add -Wno-incomplete-record-selectors to the build flags for Cabal in GHC's CI. See hadrian/src/Settings/Warnings.hs. We can remove this when Cabal is updated so that it doesn't trigger the warning: https://github.com/haskell/cabal/issues/10402 2.6% decrease in compile time allocation in RecordUpPerf Metric Decrease: RecordUpdPerf - - - - - ae7bc08e by Simon Peyton Jones at 2024-10-14T22:15:31-04:00 Elmininate incomplete record selectors This patch is a pure refactor of GHC's source code, to avoid the use of partial record selectors. It was provoked by adding -Wincomplete-record-selectors to -Wall (as the GHC Proposal specified), which in turn showed up lots of places where GHC was using incomplete record selectors. This patch does mostly-simple refactoring to make it clear to the pattern match checker that there is in fact no partiality. There is one externally-visible change: I changed the data type HoleFit to split out the two cases data HoleFit = TcHoleFit TcHoleFit | RawHoleFit SDoc data TcHoleFit = HoleFit { ...lots of fields } There are large swathes of code that just deal with `TcHoleFit`, and having it as a separate data types makes it apparent that `RawHoleFit` can't occur. This makes it much better -- but the change is visible in the HolePlugin interface. I decided that there are so few clients of this API that it's worth the change. I moved several functions from Language.Haskell.Syntax to GHC.Hs. Reason, when instantiated at (GhcPass _), the extension data construtcor is guaranteed unused, and that justifies omitted patterns in these functions. By putting them in GHC.Hs.X I can specialise the type for (GhcPass _) and thereby make the function total. An interesting side-light is that there were a few local function definitions without a type signature, like this one in GHC.Parser.Header convImport (L _ i) = (ideclPkgQual i, reLoc $ ideclName i) This is fully closed, and so is generalised; but that generalises it to any old pass, not (GhcPass _), so GHC rightly complains about the use of the selector `ideclPkgQual`. I added a type signature to `i`, thus convImport (L _ (i::ImportDecl GhcPs)) = (ideclPkgQual i, reLoc $ ideclName i) which specialised the function enough to make the record selector complete. Quite a surprising consequence of local let-generalisation! - - - - - 6a067226 by Simon Peyton Jones at 2024-10-14T22:15:31-04:00 Add -Werror=-Wno-error=incomplete-record-selectors to hadrian-multi In the main MR, -Wall now includes -Wincomplete-record-selectors. However `hadrian-multi` has many, many warnings about incomplete record selectors, so this patch stops those warnings being treated as errors. (See discussion on !13308.) A better fix would be to remove the use of incomplete record selectors, since each of them represents a potential crash. - - - - - edeafc14 by Ben Gamari at 2024-10-14T22:16:08-04:00 users-guide: Document field coalescence - - - - - 55b83587 by ARATA Mizuki at 2024-10-14T22:16:49-04:00 LLVM backend: Use correct rounding for Float literals Fixes #22033 - - - - - e59fe5c6 by Hassan Al-Awwadi at 2024-10-15T08:25:33+00:00 Changed import from Ghc. module to L.H.S module Progresses #21592 For some reason we still imported GHC.Types.Fixity when the definitino of Fixity and LexicalFixity have already been moved to Language.Haskell.Syntax.Basic. This fixes that for - - - - - ab1767d5 by Simon Peyton Jones at 2024-10-15T23:45:04-04:00 Add a release-notes entry for -Wincomplete-record-selectors - - - - - 6f0a62db by ur4t at 2024-10-16T15:33:43+00:00 GHCi: fix improper location of ghci_history file Fixes #24266 - - - - - 5f67db48 by Alan Zimmerman at 2024-10-17T05:18:43-04:00 EPA: Remove [AddEpAnn] commit 3 EPA: Remove [AddEpAnn] from HsDocTy EPA: Remove [AddEpAnn] from HsBangTy EPA: Remove [AddEpAnn] from HsExplicitListTy EPA: Remove [AddEpAnn] from HsExplicitTupleTy EPA: Remove [AddEpAnn] from HsTypedBracket EPA: Remove [AddEpAnn] from HsUntypedBracket EPA: Remove [AddEpAnn] from PatBuilderOpApp EPA: break out 'EpToken "|"' from ClassDecl anns EPA: Remove [AddEpAnn] from ClassDecl EPA: Remove [AddEpAnn] from SynDecl - - - - - fbbbd010 by Daan Rijks at 2024-10-17T05:19:19-04:00 Expand the haddocks for Control.Category - - - - - 076c1a10 by Andrew Lelechenko at 2024-10-17T05:19:19-04:00 documentation: more examples for Control.Category - - - - - 90891962 by Cheng Shao at 2024-10-17T16:41:18+00:00 ghci: mitigate host/target word size mismatch in BCOByteArray serialization This patch mitigates a severe host/target word size mismatch issue in BCOByteArray serialization logic introduced since !12142, see added note for detailed explanation. - - - - - 839ac52e by Cheng Shao at 2024-10-17T16:41:18+00:00 ghci: use plain malloc for mkConInfoTable on non-TNTC platforms This patch avoids using mmap() to allocate executable memory for mkConInfoTable on platforms without tables-next-to-code, see added comment for explanation. - - - - - a998f69d by Cheng Shao at 2024-10-17T16:41:18+00:00 ghc-internal: add missing CPPs for wasm This patch adds some missing CPP guards to ghc-internal, given those functions are non existent on wasm and would cause linking issues. - - - - - 71a471e7 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: rename prelude.js to prelude.mjs This commit renames prelude.js to prelude.mjs for wasm backend rts jsbits, and slightly adjusts the jsbits contents. This is for preparing the implementation of dyld.mjs that contains wasm dynamic linker logic, which needs to import prelude.mjs as a proper ESM module. - - - - - 33d9db17 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: add __wrapped_freeJSVal This commit wraps imported freeJSVal in a __wrapped_freeJSVal C function for wasm backend RTS. In general, wasm imports are only supposed to be directly called by C; they shouldn't be used as function pointers, which confuses wasm-ld at link-time when generating shared libraries. - - - - - 0d0a16a8 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: correct stale link in comment - - - - - 90a35c41 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: drop interpretBCO support from non-dyn ways on wasm This commit drops interpretBCO support from non dynamic rts ways on wasm. The bytecode interpreter is only useful when the RTS linker also works, and on wasm it only works for dynamic ways anyway. An additional benefit of dropping interpretBCO is reduction in code size of linked wasm modules, especially since interpretBCO references ffi_call which is an auto-generated large function in libffi-wasm and unused by most user applications. - - - - - 98a32ec5 by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: don't build predefined GloblRegs for wasm PIC mode This commit wraps the predefined GlobalRegs in Wasm.S under a CPP guard to prevent building for PIC mode. When building dynamic ways of RTS, the wasm globals that represent STG GlobalRegs will be created and supplied by dyld.mjs. The current wasm dylink convention doesn't properly support exporting relocatable wasm globals at all, any wasm global exported by a .so is assumed to be a GOT.mem entry. - - - - - bef94bde by Cheng Shao at 2024-10-17T16:41:18+00:00 rts: fix conflicting StgRun definitions on wasm This commit fixes conflicting StgRun definition when building dynamic ways of RTS for wasm in unregisterised mode. - - - - - a6a82cdb by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: use targetSupportsRPaths predicate This commit changes the hostSupportsRPaths predicate to targetSupportsRPaths and use that to decide whether to pass RPATH-related link-time options. It's not applied to stage0, we should just use the default link-time options of stageBoot ghc. - - - - - f232c872 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: disable internal-interpreter of ghc library when cross compiling This commit disable the internal-interpreter flag of ghc library when cross compiling, only external interpreter works in such cases. - - - - - 577c1819 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: enable internal-interpreter for ghc-bin stage0 This commit enables internal-interpreter flag for ghc-bin even when compiling stage0, as long as target supports ghci. It enables ghci functionality for cross targets that support ghci, since cross ghc-bin is really stage0. - - - - - c247f2ee by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: fix CFLAGS for gmp shared objs on wasm This commit adds -fvisibility=default to CFLAGS of gmp when building for wasm. This is required to generate the ghc-bignum shared library without linking errors. Clang defaults to -fvisibility=hidden for wasm targets, which will cause issues when a symbol is expected to be exported in a shared library but without explicit visibility attribute annotation. - - - - - 775410fd by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: re-enable PIC for gmp on wasm This commit re-enables --with-pic=yes configuration option of gmp when building for wasm, given we're about to include support for shared libraries, TH and ghci. - - - - - b45080a3 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian: add the host_fully_static flavour transformer This commit adds the host_fully_static flavour transformer to hadrian, which ensures stage0 is fully statically linked while still permitting stage1 libdir to contain shared libraries. This is intended to be used by the wasm backend to build portable linux bindists that contain wasm shared libraries. - - - - - 5043507c by Cheng Shao at 2024-10-17T16:41:18+00:00 ci: update wasm jobs configuration This commit bumps ci-image revision to use updated wasm toolchain, and use host_fully_static instead of fully_static for wasm jobs so to ensure wasm shared libraries can be properly built. - - - - - 2956a3f7 by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian/testsuite: implement config.cross logic This commit implements the config.cross field in the testsuite driver. It comes from the "cross compiling" ghc info field for both in-tree/out-of-tree GHC, and is an accurate predicate of whether we're cross-compiling or not (compared to the precense of target emulator), and is useful to implement predicates to assert the precense of internal interpreter (only available on non-cross GHC) for tests that do require it (e.g. plugins). - - - - - 8c74a0ed by Cheng Shao at 2024-10-17T16:41:18+00:00 hadrian/compiler: implement targetRTSLinkerOnlySupportsSharedLibs This patch implements the targetRTSLinkerOnlySupportsSharedLibs predicate in hadrian. Its definition in hadrian is the single source of truth, and the information propagates to ghc settings file, ghc driver and testsuite driver. It is used in various places to ensure dynamic dependency is selected when the target RTS linker only supports loading dynamic code. - - - - - b4c3c340 by Cheng Shao at 2024-10-17T16:41:18+00:00 testsuite: don't use host cpu features when testing cross ghc This patch disables CPU feature detection logic when testing cross GHC, since those features don't make sense for the target anyway. - - - - - 3c21b696 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: implement & use req_plugins predicate This commit implements req_plugins predicate to indicate that the test requires plugin functionality. Currently this means cross GHC is disabled since internal-interpreter doesn't work in cross GHC yet. - - - - - 93b8af80 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: make use of config.interp_force_dyn This commit takes config.interp_force_dyn into consideration when setting up TH/ghci way flags. - - - - - 94673d41 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: bump T17572 timeout - - - - - 2b5efc2d by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: bump T22744 pre_cmd timeout - - - - - 45102e2a by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip terminfo_so for cross ghc - - - - - 05e40406 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: fix shared library size tests for cross ghc This commit fixes shared library size tests (e.g. array_so in testsuite/tests/perf/size/all.T) when testing cross ghc. Previously, if shared library file extension of host and target differs, those tests will fail with framework errors due to not finding the right files. - - - - - fa68f833 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip ghc api tests that attempt to spawn processes inside wasm This commit skips a few ghc api tests on wasm, since they would attempt to spawn processes inside wasm, which is not supported at all. - - - - - 1241c04e by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: skip T22840 due to broken -dtag-inference-checks on wasm - - - - - 78c8b900 by Cheng Shao at 2024-10-17T16:41:19+00:00 testsuite: ensure $(ghciWayFlags) can be overridden This commit revises boilerplate.mk in testsuite as well as a few other places, to ensure the tests that do make use of $(ghciWayFlags) can receive the right $(ghciWayFlags) from testsuite driver config. - - - - - 47989ecc by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: skip rdynamic on wasm - - - - - fefb4ea1 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: skip T2615 on wasm This commit marks T2615 as skip on wasm, given LD_* environment variables aren't supported on wasm anyway. - - - - - 77c79762 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: mark MultiLayerModulesTH_Make/MultiLayerModulesTH_OneShot as fragile on wasm - - - - - 69bb4745 by Cheng Shao at 2024-10-17T16:41:24+00:00 testsuite: fix T16180 on wasm This commit fixes T16180 on wasm once TH support is flipped on. The fix is simply adding right asm code for wasm. - - - - - 621c753d by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: fix -fexternal-interpreter flag for JS backend Previously, -fexternal-interpreter is broken for JS backend, since GHC would attempt to launch a non-existent ghc-iserv* executable. This commit fixes it by adjusting pattern matching order in setTopSessionDynFlags. - - - - - 80aa8983 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: use interpreterDynamic predicate in preloadLib This commit use the interpreterDynamic predicate in preloadLib to decide if we should do dynLoadObjs instead of loadObj. Previously we used hostIsDynamic which was only written with non-cross internal interpreter in mind. The testsuite is also adjusted to remove hard-wired -fPIC flag for cbits (doesn't work in i386 RTS linker in vanilla way, #25260) and properly pass ghc_th_way_flags to ghc. - - - - - 74411461 by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix Cmm dynamic CLabels for wasm This commit fixes the handling of dynamic CLabels for the wasm backend. Just do the simplest handling: preserve the original CLabel, both unreg/NCG backends can handle them properly without issue. - - - - - f6abaf13 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: add necessary compile-time flags for wasm PIC mode This commit adds necessary compile-time flags when compiling for wasm PIC mode, see added comment for detailed explanation. - - - - - 9745fcfb by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: add necessary link-time flags for wasm shared libs This commit adds necessary link-time flags for wasm shared libs, see added comments for detailed explanation. - - - - - 649aae00 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: enforce -fno-use-rpaths for wasm This commit ensures the GHC driver never passes any RPATH-related link-time flags on wasm, which is not supported at all. - - - - - 47baa904 by Cheng Shao at 2024-10-17T16:41:24+00:00 driver: ensure static archives are picked when linking static .wasm modules This commit ensures static archives are picked when linking .wasm modules which are supposed to be fully static, even when ghc may be invoked with -dynamic, see added comment for explanation. - - - - - fc3a5591 by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix dynamic_too_enable for targets that require dynamic libraries This commit fixes dynamic_too_enable for targets whose RTS linker can only load dynamic code. - - - - - 94ef949e by Cheng Shao at 2024-10-17T16:41:24+00:00 compiler: fix checkNonStdWay for targets that require dynamic libraries This commit fixes checkNonStdWay to ensure that for targets whose RTS linker can only load dynamic code, the dynamic way of object is selected. - - - - - 88e99248 by Cheng Shao at 2024-10-17T16:41:24+00:00 ghc-bin: enforce dynamic way when the target requires so This commit makes ghc-bin use dynamic way when it is doing interactive stuff on certain targets whose RTS linker can only handle dynamic code. - - - - - 549582ef by Cheng Shao at 2024-10-17T16:41:24+00:00 hadrian/ghci: add wasm dyld This commit adds the wasm dynamic linker implementation, as well as ghci logic to call it and hadrian logic to install it to the correct location. See the top-level note in utils/jsffi/dyld.mjs for more details. - - - - - b562e3a6 by Cheng Shao at 2024-10-17T16:41:29+00:00 driver: fix getGccSearchDirectory for wasm target This commit fixes getGccSearchDirectory logic for wasm target, ensures the correct search directory containing libc.so etc can be found by GHC. getGccSearchDirectory is also exported so it can be used elsewhere to obtain the wasi-sdk libdir and pass to the dyld script. - - - - - 2d6107dc by Cheng Shao at 2024-10-17T16:41:29+00:00 driver: add wasm backend iserv logic This commit adds wasm backend iserv logic to the driver, see added comments for explanation. - - - - - 61f5baa5 by Cheng Shao at 2024-10-17T16:41:29+00:00 compiler: add PIC support to wasm backend NCG This commit adds support for generating PIC to the wasm backend NCG. - - - - - 652e7239 by Cheng Shao at 2024-10-17T16:41:29+00:00 hadrian/compiler: flip on support for shared libs & ghci for wasm This commit flips on the support for shared libs and ghci for the wasm target, given all required support logic has been added in previous commits. - - - - - 74a1f681 by Cheng Shao at 2024-10-17T16:41:29+00:00 testsuite: flip on support for shared libs, TH & ghci for wasm This commit flips on support for shared libs, TH & ghci for wasm in the testsuite, given support has been landed in previous commits. - - - - - 525d451e by Cheng Shao at 2024-10-17T23:03:34-04:00 Revert "compiler: start deprecating cmmToRawCmmHook" This reverts commit 1c064ef1f3e1aa2afc996e962ad53effa99ec5f4. Turns out the GHC-WPC project does use it to observe Cmm in the pipeline, see #25363. - - - - - 5bcfefd5 by Cheng Shao at 2024-10-17T23:04:09-04:00 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. - - - - - eb67875f by Matthew Craven at 2024-10-18T12:18:35+00:00 Bump transformers submodule The svg image files mentioned in transformers.cabal were previously not checked in, which broke sdist generation. - - - - - 366a1109 by Matthew Craven at 2024-10-18T12:18:35+00:00 Remove reference to non-existent file in haddock.cabal - - - - - 826852e9 by Matthew Craven at 2024-10-18T12:18:35+00:00 Move tests T11462 and T11525 into tests/tcplugins - - - - - dbe27152 by Matthew Craven at 2024-10-18T12:18:35+00:00 Repair the 'build-cabal' hadrian target Fixes #23117. Fixes #23281. Fixes #23490. This required: * Updating the bit-rotted compiler/Setup.hs and its setup-depends * Listing a few recently-added libraries and utilities in cabal.project-reinstall * Setting allow-boot-library-installs to 'True' since Cabal now considers the 'ghc' package itself a boot library for the purposes of this flag Additionally, the allow-newer block in cabal.project-reinstall was removed. This block was probably added because when the libraries/Cabal submodule is too new relative to the cabal-install executable, solving the setup-depends for any package with a custom setup requires building an old Cabal (from Hackage) against the in-tree version of base, and this can fail un-necessarily due to tight version bounds on base. However, the blind allow-newer can also cause the solver to go berserk and choose a stupid build plan that has no business succeeding, and the failures when this happens are dreadfully confusing. (See #23281 and #24363.) Why does setup-depends solving insist on an old version of Cabal? See: https://github.com/haskell/cabal/blob/0a0b33983b0f022b9697f7df3a69358ee9061a89/cabal-install/src/Distribution/Client/ProjectPlanning.hs#L1393-L1410 The right solution here is probably to use the in-tree cabal-install from libraries/Cabal/cabal-install with the build-cabal target rather than whatever the environment happens to provide. But this is left for future work. - - - - - b3c00c62 by Matthew Craven at 2024-10-18T12:18:35+00:00 Revert "CI: Disable the test-cabal-reinstall job" This reverts commit 38c3afb64d3ffc42f12163c6f0f0d5c414aa8255. - - - - - a04959b8 by Daneel Yaitskov at 2024-10-19T09:34:15-04:00 base: speed up traceEventIO and friends when eventlogging is turned off #17949 Check the RTS flag before doing any work with the given lazy string. Fix #17949 Co-authored-by: Michael Peyton Jones <me at michaelpj.com> Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> - - - - - eff16c22 by Matthew Pickering at 2024-10-19T21:55:55-04:00 ci: Add support for ONLY_JOBS variable to trigger any validation pipeline By setting the ONLY_JOBS variable to the name of the job (or multiple jobs), the resulting pipeline will include a validation job for that pipeline. For example - if you set ONLY_JOBS="x86_64-linux-ubuntu22_04-validate" then a ubuntu22_04 job will be included in the validation pipeline. This is useful for testing specific jobs. Fixes #25332 - - - - - 280b6278 by Zubin Duggal at 2024-10-19T21:56:31-04:00 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit d83f5bd730a8aef37d8a38b3560590d9798f8e45) - - - - - 25edf849 by Alan Zimmerman at 2024-10-19T21:57:08-04:00 EPA: Remove [AddEpAnn] Commit 4 EPA: Remove [AddEpAnn] from DataDecl This is quite a big change. The most important part is moving the annotations into HsDataDefn, using a specific annotation data type. It has a knock-on to everything that uses HsDataDefn EPA: Remove [AddEpAnn] for FunDep EPA: Remove [AddEpann] from FamilyDecl EPA: Remove [AddEpAnn] From InjectivityAnn EPA: Remove [AddEpAnn] from DefaultDecl EPA: Remove [AddEpAnn] from RuleDecls EPA: Remove [AddEpAnn] from Warnings - - - - - d5f42045 by Luite Stegeman at 2024-10-20T16:34:47-04:00 Interpreter: Add locking for communication with external interpreter This adds locking to communication with the external interpreter to prevent concurrent tasks interfering with each other. This fixes Template Haskell with the external interpreter in parallel (-j) builds. Fixes #25083 - - - - - d6bfea76 by Matthew James Kraai at 2024-10-20T16:35:29-04:00 Use monospace font for "Either a b" in fmap docs The documentation for fmap shows "`Either a b`" in the default font instead of showing "Either a b" in a monospace font. - - - - - 4bc7f9c8 by Luite Stegeman at 2024-10-20T16:36:15-04:00 Parser: remove non-ASCII characters from Parser.y Non-ASCII characters in the source causes a problem with the default Haskell Language Server setup in VSCode. Two characters seems to have been left in by accident. Workaround for #25396 - - - - - 7f61ed4e by Alan Zimmerman at 2024-10-21T06:39:45-04:00 EPA: Remove [AddEpAnn] Commit 5 EPA: Remove [AddEpAnn] from AnnPragma EPA: Remove [AddEpAnn] From ForeignDecl EPA: Remove [AddEpAnn] from RoleAnnotDecl EPA: Remove [AddEpAnn] from StandaloneKindSig EPA: Remove [AddEpAnn] From HsDeriving EPA: Remove [AddEpAnn] from ConDeclField EPA: Remove [AddEpAnn] from ConDeclGADT EPA: Remove [AddEpAnn] from ConDeclH98 EPA: Remove [AddEpAnn] from ClsInstDecl - - - - - f8694fe7 by Cheng Shao at 2024-10-21T06:40:21-04:00 wasm: bump dyld v8 heap size limit This patch adds `--max-old-space-size=8192` to wasm dyld shebang arguments to bump V8 heap size limit. The default limit (`heap_size_limit` returned by `v8.getHeapStatistics()`) is dynamically determined and a bit too low under certain workloads, and V8 would waste too much CPU time to garbage collect old generation heap more aggressively. Bumping the limit to 8G doesn't imply dyld would really take that much memory at run-time, but it lessens V8 heap stress significantly. - - - - - d328d173 by Luite Stegeman at 2024-10-21T12:39:18+00:00 Add requestTickyCounterSamples to GHC.Internal.Profiling This allows the user to request ticky counters to be written to the eventlog at specific times. See #24645 - - - - - 71765b1d by Simon Peyton Jones at 2024-10-21T20:55:00-04:00 Move defaulting code into a new module GHC.Tc.Solver had reached 4,000 lines -- although quite a lot of them are comments. This MR * Adds the new module GHC.Tc.Solver.Default, which has all the complex, but well modularised, defaulting code * Moves a bit of code from GHC.Tc.Solver into the existing GHC.Tc.Solver.Solve. Notably solveWanteds and simplifyWantedsTcM, which are called from GHC.Tc.Solver.Default It's a pure refactor. No code changes. - - - - - a398227b by Simon Peyton Jones at 2024-10-21T20:55:00-04:00 Improve the generalisation code in Solver.simplifyInfer The code in `decideQuantification` has become quite complicated. This MR straightens it out, adds a new Note, and on the way fixes #25266. See especially Note [decideAndPromoteTyVars] which is is where all the action happens in this MR. - - - - - 148059fe by Andrzej Rybczak at 2024-10-21T20:55:40-04:00 Adjust catches to properly rethrow exceptions https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13302 implemented exception rethrowing proposal, but it didn't adjust `catches`. This fixes it. - - - - - 25121dbc by doyougnu at 2024-10-22T09:38:18-04:00 linker: add --optimistic-linking flag This patch adds: - the --optimistic-linking flag which binds unknown symbols in the runtime linker to 0xDEADBEEF instead of exiting with failure - The test T25240 which tests these flags using dead code in the FFI system. - closes #25240 This patch is part of the upstreaming haskell.nix patches project. - - - - - f19e076d by doyougnu at 2024-10-22T09:38:18-04:00 ghc-internal: hide linkerOptimistic in MiscFlags - - - - - edc02197 by Cheng Shao at 2024-10-22T09:38:54-04:00 hadrian: fix bindist executable wrapper logic for cross targets This commit fixes an oversight of hadrian wrapper generation logic: when doing cross compilation, `wrapper` is called on executable names with cross prefix, therefore we must use `isSuffixOf` when matching to take the cross prefix into account. Also add missing cross prefix to ghci wrapper content and fix hsc2hs wrapper logic. - - - - - edf3bdf5 by Andreas Klebinger at 2024-10-22T16:30:42-04:00 mkTick: Push ticks through unsafeCoerce#. unsafeCoerce# doesn't exist at runtime so we should treat it like a Cast for the purpose of mkTick. This means if we have `{-# SCC foo #-} (unsafeCoerce# trivial_expr))` we now push the scope part of the cost centre up to `trivial_expr` at which point we can discard it completely if the expression is trivial enough. This fixes #25212. - - - - - 1bdb1317 by Cheng Shao at 2024-10-22T16:31:17-04:00 hadrian: enable late-CCS for perf flavour as well This patch enables late-CCS for perf flavour so that the testsuite can pass for perf as well. Fixes #25308. - - - - - fde12aba by Cheng Shao at 2024-10-22T16:31:54-04:00 hadrian: make sure ghc-bin internal-interpreter is disabled for stage0 when not cross compiling This patch disables internal-interpreter flag for stage0 ghc-bin when not cross compiling, see added comment for explanation. Fixes #25406. - - - - - 6ab8d751 by ignatiusm at 2024-10-24T01:23:35-04:00 Improve heap overflow exception message (#25198) Catch heap overflow exceptions and suggest using `+RTS -M<size>`. Fix #25198 - - - - - b3f7fb80 by Rodrigo Mesquita at 2024-10-24T01:24:12-04:00 determinism: Interface re-export list det In 'DocStructureItem' we want to make sure the 'Avails' are sorted, for interface file determinism. This commit introduces 'DetOrdAvails', a newtype that should only be constructed by sorting Avails with 'sortAvails' unless the avails are known to be deterministically ordered. This newtype is used by 'DocStructureItem' where 'Avails' was previously used to ensure the list of avails is deterministically sorted by construction. Note: Even though we order the constructors and avails in the interface file, the order of constructors in the haddock output is still determined from the order of declaration in the source. This was also true before, when the list of constructors in the interface file <docs> section was non-deterministic. Some haddock tests such as "ConstructorArgs" observe this (check the order of constructors in out/ConstructorArgs.html vs src/ConstructorArgs.hs vs its interface file) The updated tests are caused by haddock corners where the order in the source is not preserved (and was non-deterministic before this PR): * Module header in the latex backend * Re-export of pattern synonyms associated to a datatype (#25342) Fixes #25304 - - - - - e39c8c99 by Rodrigo Mesquita at 2024-10-24T01:24:12-04:00 Revert "ci: Allow abi-test to fail." After #25304, the abi-test with interface and object determinism succeeds. This reverts commit 7b37afc9f3e79559055488998ee73187886a0e00. - - - - - 7b1b0c6d by Alan Zimmerman at 2024-10-24T13:07:02-04:00 EPA: reduce [AddEpann] in AnnList Remove it from the `al_rest` field, and make `AnnList` parameterized on a type to be used in `al_rest`, for the various use cases. - - - - - 4a00731e by Rodrigo Mesquita at 2024-10-24T13:07:38-04:00 Fix -fobject-determinism flag definition The flag should be defined as an fflag to make sure the -fno-object-determinism flag is also an available option. Fixes #25397 - - - - - 55e4b9f2 by Sebastian Graf at 2024-10-25T07:01:54-04:00 CorePrep: Attach evaldUnfolding to floats to detect more values See `Note [Pin evaluatedness on floats]`. - - - - - 9f57c96d by Sebastian Graf at 2024-10-25T07:01:54-04:00 Make DataCon workers strict in strict fields (#20749) This patch tweaks `exprIsConApp_maybe`, `exprIsHNF` and friends, and Demand Analysis so that they exploit and maintain strictness of DataCon workers. See `Note [Strict fields in Core]` for details. Very little needed to change, and it puts field seq insertion done by Tag Inference into a new perspective: That of *implementing* strict field semantics. Before Tag Inference, DataCon workers are strict. Afterwards they are effectively lazy and field seqs happen around use sites. History has shown that there is no other way to guarantee taggedness and thus the STG Strict Field Invariant. Knock-on changes: * I reworked the whole narrative around "Tag inference". It's now called "EPT enforcement" and I recycyled the different overview Notes into `Note [EPT enforcement]`. * `exprIsHNF` previously used `exprOkForSpeculation` on unlifted arguments instead of recursing into `exprIsHNF`. That regressed the termination analysis in CPR analysis (which simply calls out to `exprIsHNF`), so I made it call `exprOkForSpeculation`, too. * There's a small regression in Demand Analysis, visible in the changed test output of T16859: Previously, a field seq on a variable would give that variable a "used exactly once" demand, now it's "used at least once", because `dmdTransformDataConSig` accounts for future uses of the field that actually all go through the case binder (and hence won't re-enter the potential thunk). The difference should hardly be observable. * The Simplifier's fast path for data constructors only applies to lazy data constructors now. I observed regressions involving Data.Binary.Put's `Pair` data type. * Unfortunately, T21392 does no longer reproduce after this patch, so I marked it as "not broken" in order to track whether we regress again in the future. Fixes #20749, the satisfying conclusion of an annoying saga (cf. the ideas in #21497 and #22475). Compiler perf generally improves, sometimes drastically: Baseline Test Metric value New value Change -------------------------------------------------------------------------------- ManyConstructors(normal) ghc/alloc 3,629,760,116 3,711,852,800 +2.3% BAD MultiLayerModulesTH_OneShot(normal) ghc/alloc 2,502,735,440 2,565,282,888 +2.5% BAD T12707(normal) ghc/alloc 804,399,798 791,807,320 -1.6% GOOD T17516(normal) ghc/alloc 964,987,744 1,008,383,520 +4.5% T18140(normal) ghc/alloc 75,381,152 49,860,560 -33.9% GOOD T18698b(normal) ghc/alloc 232,614,457 184,262,736 -20.8% GOOD T18923(normal) ghc/alloc 62,002,368 58,301,408 -6.0% GOOD T20049(normal) ghc/alloc 75,719,168 70,494,368 -6.9% GOOD T3294(normal) ghc/alloc 1,237,925,833 1,157,638,992 -6.5% GOOD T9233(normal) ghc/alloc 686,490,105 635,166,688 -7.5% GOOD geo. mean -0.7% minimum -33.9% maximum +4.5% I looked at T17516. It seems we do a few more simplifier iterations and end up with a larger program. It seems that some things inline more, while other things inline less. I don't see low-hanging fruit. I also looked at MultiLayerModulesTH_OneShot. It appears we generate a strange join point in the `getUnique` method of `Uniquable GHC.Unit.Types.Module` that should better call-site inline, but does not. Perhaps with !11492. NoFib does not seem affected much either: +-------------------------------++--+------------+-----------+---------------+-----------+ | || | base/ | std. err. | T20749/ (rel) | std. err. | +===============================++==+============+===========+===============+===========+ | spectral/last-piece || | 7.263e8 | 0.0% | +0.62% | 0.0% | +===============================++==+============+===========+===============+===========+ | geom mean || | +0.00% | | | | +-------------------------------++--+------------+-----------+---------------+-----------+ I had a look at last-piece. Nothing changes in stg-final, but there is a bit of ... movement around Data.Map.insert's use of GHC.Exts.lazy that is gone in stg-final. Co-Authored-By: Jaro Reinders <jaro.reinders at gmail.com> Metric Decrease: T12707 T18140 T18698b T18923 T19695 T20049 T3294 T9233 T21839c Metric Increase: ManyConstructors MultiLayerModulesTH_OneShot - - - - - 0225249a by Simon Peyton Jones at 2024-10-25T07:02:32-04:00 Some renaming This is a pure refactor, tidying up some inconsistent naming: isEqPred --> isEqClassPred isEqPrimPred --> isEqPred isReprEqPrimPred --> isReprEqPred mkPrimEqPred --> mkNomEqPred mkReprPrimEqPred --> mkReprEqPred mkPrimEqPredRold --> mkEqPredRole Plus I moved mkNomEqPred, mkReprEqPred, mkEqPredRolek from GHC.Core.Coercion to GHC.Core.Predicate where they belong. That means that Coercion imports Predicate rather than vice versa -- better. - - - - - 15a3456b by Ryan Hendrickson at 2024-10-25T07:02:32-04:00 compiler: Fix deriving with method constraints See Note [Inferred contexts from method constraints] Co-authored-by: Simon Peyton Jones <simon.peytonjones at gmail.com> - - - - - dbc77ce8 by Alan Zimmerman at 2024-10-25T18:20:13+01:00 EPA: Remove AddEpann commit 7 EPA: Remove [AddEpAnn] from HYPHEN in Parser.y The return value is never used, as it is part of the backpack configuration parsing. EPA: Remove last [AddEpAnn] usages Remove residual usage in GHC. It is still used - In haddock TTG extension point definitions (to be removed) - Some check-exact residual, to be removed - Comments around DisambECP in PostProcess EPA: Clean up [AddEpAnn] from check-exact There is one left, to be cleaned up when we remove AddEpann itself EPA: Remove [AddEpAnn] from haddock The TTG extension points need a value, it is not critical what that value is, in most cases. EPA: Remove AddEpAnn from HsRuleAnn EPA: Remove AddEpAnn from HsCmdArrApp - - - - - 23ddcc01 by Simon Peyton Jones at 2024-10-26T12:44:34-04:00 Fix optimisation of InstCo It turned out (#25387) that the fix to #15725 was not quite right: commit 48efbc04bd45d806c52376641e1a7ed7278d1ec7 Date: Mon Oct 15 10:25:02 2018 +0200 Fix #15725 with an extra Sym Optimising InstCo is quite subtle, and the invariants surrounding the LiftingContext in the coercion optimiser were not stated explicitly. This patch refactors the InstCo optimisation, and documents these invariants. See * Note [Optimising InstCo] * Note [The LiftingContext in optCoercion] I also did some refactoring of course: * Instead of a Bool swap-flag, I am not using GHC.Types.Basic.SwapFlag * I added some invariant-checking the coercion-construction functions in GHC.Core.Coercion.Opt. (Sadly these invariants don't hold during typechecking, becuase the types are un-zonked, so I can't put these checks in GHC.Core.Coercion.) - - - - - 589fea7f by Cheng Shao at 2024-10-27T05:36:38-04:00 ghcid: use multi repl for ghcid - - - - - d52a0475 by Andrew Lelechenko at 2024-10-27T05:37:13-04:00 documentation: add motivating section to Control.Monad.Fix - - - - - 301c3b54 by Cheng Shao at 2024-10-27T05:37:49-04:00 wasm: fix safari console error message related to import("node:timers") This patch fixes the wasm backend JSFFI prelude script to avoid calling `import("node:timers")` on non-deno hosts. Safari doesn't like it and would print an error message to the console. Fixes https://gitlab.haskell.org/ghc/ghc-wasm-meta/-/issues/13. - - - - - 9f02dfb5 by Simon Peyton Jones at 2024-10-27T15:10:08-04:00 Add a missing tidy in UnivCo We were failing to tidy the argument coercions of a UnivCo, which led directly to #25391. The fix is, happily, trivial. I don't have a small repro case (it came up when building horde-ad, which uses typechecker plugins). It should be possible to make a repro case, by using a plugin (which builds a UnivCo) but I decided it was not worth the bother. The bug is egregious and easily fixed. - - - - - 853050c3 by Andrew Lelechenko at 2024-10-27T15:10:44-04:00 Bump text submodule to 2.1.2 - - - - - 90746a59 by Andrew Lelechenko at 2024-10-27T15:10:44-04:00 hadrian: allow -Wunused-imports for text package - - - - - 8a6691c3 by Alan Zimmerman at 2024-10-27T19:44:48+00:00 EPA: Remove AddEpAnn Commit 8/final EPA: Remove AddEpAnn from AnnList EPA: Remove AddEpAnn from GrhsAnn This is the last actual use EPA: Remove NameAdornment from NameAnn Also rework AnnContext to use EpToken, and AnnParen EPA: Remove AddEpAnn. Final removal There are now none left, except for in a large note/comment in PostProcess, describing the historical transition to the disambiguation infrastructure - - - - - d5e7990c by Alan Zimmerman at 2024-10-28T21:41:05+00:00 EPA: Remove AnnKeywordId. This was used as part of AddEpAnn, and is no longer needed. Also remove all the haddock comments about which of are attached to the various parts of the AST. This is now clearly captured in the appropriate TTG extension points, and the `ExactPrint.hs` file. - - - - - e08b8370 by Serge S. Gulin at 2024-10-29T23:17:01-04:00 JS: Re-add optimization for literal strings in genApp (fixes #23479) Based on https://gitlab.haskell.org/ghc/ghc/-/merge_requests/10588/ Co-authored-by: Sylvain Henry <sylvain at haskus.fr> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> Co-authored-by: Danil Berestov <goosedb at yandex.ru> ------------------------- Metric Decrease: T25046_perf_size_gzip size_hello_artifact size_hello_artifact_gzip size_hello_unicode size_hello_unicode_gzip ------------------------- - - - - - e3496ef6 by Cheng Shao at 2024-10-29T23:17:37-04:00 compiler: remove unused hscDecls/hscDeclsWithLocation This patch removes unused `hscDecls`/`hscDeclsWithLocation` functions from the compiler, to reduce maintenance burden when doing refactorings related to ghci. - - - - - b1eed26f by Cheng Shao at 2024-10-29T23:18:13-04:00 testsuite: add T25414 test case marked as broken This commit adds T25414 test case to demonstrate #25414. It is marked as broken and will be fixed by the next commit. - - - - - e70009bc by Cheng Shao at 2024-10-29T23:18:13-04:00 driver: fix foreign stub handling logic in hscParsedDecls This patch fixes foreign stub handling logic in `hscParsedDecls`. Previously foreign stubs were simply ignored here, so any feature that involve foreign stubs would not work in ghci (e.g. CApiFFI). The patch reuses `generateByteCode` logic and eliminates a large chunk of duplicate logic that implements Core to bytecode generation pipeline here. Fixes #25414. - - - - - 1d7cd7fe by Andreas Klebinger at 2024-10-30T19:14:28-04:00 Add since tag for -fwrite-if-compression in user guide. Partial fix for #25395 - - - - - b349fd1b by Alan Zimmerman at 2024-10-30T19:15:04-04:00 EPA: Remove some unused functions - - - - - f859d61c by Alan Zimmerman at 2024-10-30T19:15:04-04:00 EPA: use explicit vertical bar token for ExplicitSum / SumPat - - - - - 721ac00d by Ben Gamari at 2024-10-31T08:37:38-04:00 rts/Disassembler: Fix encoding of BRK_FUN instruction The offset of the CC field was not updated after the encoding change in b85b11994e0130ff2401dd4bbdf52330e0bcf776. Fix this. Fixes #25374. - - - - - 0bc94360 by Alan Zimmerman at 2024-10-31T08:38:15-04:00 EPA: Bring in last EpToken usages For import declarations, NameAnnCommas and NPlusKPat. And remove anchor, it is the same as epaLocationRealSrcSpan. - - - - - 0b11cdc0 by sheaf at 2024-10-31T08:38:55-04:00 Assert that ctEvCoercion is called on an equality Calling 'ctEvCoercion' on non-equality constraints is always incorrect. We add an assertion to this function to detect such cases; for example a type-checking plugin might erroneously do this. - - - - - ea458779 by doyougnu at 2024-11-01T18:11:33-04:00 ghc-internal: strict, unboxed src loc ranges - closes: #20449 - See CLC proposal: #55 - - - - - 778ac793 by Kazuki Okamoto at 2024-11-01T18:12:13-04:00 No haddock markup in doctest line - - - - - cf0deeaf by Andreas Klebinger at 2024-11-02T17:54:52-04:00 Reword -fexpose-overloaded-unfoldings docs. This should make them slightly clearer. Fixes #24844 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> - - - - - 1c21e7d4 by Andreas Klebinger at 2024-11-02T17:55:29-04:00 Compile T25062 simd tests even if we can't run them. Helps avoid them being utterly broken. Fixes #25341 - - - - - 573cad4b by Cheng Shao at 2024-11-02T17:56:04-04:00 Remove unused USE_REPORT_PRELUDE code paths from the tree This patch removes unused `USE_REPORT_PRELUDE` code paths from the tree. They have been present since the first git revision 4fb94ae5e5d632748fa2e6c35e259eccc5a1a3f4, and might have been useful for debugging purposes many years ago, but these code paths are never actually built. Removing these ease maintenance of relevant modules in the future, and also allows us to get rid of `CPP` extension in those modules as a nice byproduct. - - - - - 97f600c6 by Hassan Al-Awwadi at 2024-11-04T15:52:12+00:00 Refactored BooleanFormula to be in line with TTG (#21592) There are two parts to this commit. * We moved the definition of BooleanFormula over to L.H.S.BooleanFormula * We parameterized the BooleanFormula over the pass The GHC specific details of BooleanFormula remain in Ghc.Data.BooleanFormula. Because its parameterized over the pass its no longer a functor or traversable, but we defined bfMap and bfTraverse for the cases where we needed fmap and traverse originally. Most other changes are just churn. ------------------------- Metric Decrease: MultiLayerModulesTH_OneShot ------------------------- - - - - - d4fd3580 by Andreas Klebinger at 2024-11-05T07:36:16-05:00 ghc-heap: Fix incomplete selector warnings. Use utility functions instead of selectors to read partial attributes. Part of fixing #25380. - - - - - fdd9f62a by Peter Trommler at 2024-11-05T07:36:51-05:00 PPC NCG: Implement fmin and fmax - - - - - 8e217256 by Mike Pilgrem at 2024-11-07T04:34:20-05:00 Re CLC #293 - Don't specify Data.List.NonEmpty in terms of partial See https://github.com/haskell/core-libraries-committee/issues/293 `List.init` had already been driven out of `tails1` by 21fc180bec93d964a7f4ffdf2429ef6f74b49ab6 but this specification also avoided partial `fromList`, so I preferred it. The `changelog.md` for `base` is updated, with an entry added under `base-4.22.0.0`. - - - - - 346e4cd1 by Zubin Duggal at 2024-11-07T04:34:57-05:00 release: copy zip files into the correct directory Fixes #25446 - - - - - bbdbe225 by Zubin Duggal at 2024-11-07T04:34:57-05:00 release: Sign .gz bindists too Fixes #25447 - - - - - 0c722e14 by Hécate Kleidukos at 2024-11-07T04:35:37-05:00 hadrian: Enforce the usage of GHC >=9.8.1 for ghci-multi GHC 9.6 no good when it comes to multi-repl stuff, despite being well within the range of n-2 releases for bootstrapping, when the script was adapted to load haddock, in !12851 - - - - - d8f8a1c3 by Sylvain Henry at 2024-11-07T19:27:46-05:00 Handle the special ghc-prim:GHC.Prim module in the compiler Before this patch, some custom hacks were necessary in ghc-prim's Setup.hs to register the GHC.Prim (virtual) module and in Hadrian to generate haddocks properly. In this patch we special-case this module in the compiler itself instead (which it already is, see ghcPrimIface in GHC.Iface.Load). From Cabal/Hadrian's perspective GHC.Prim is now just a normal autogenerated module. This simplification is worthwhile on its own. It was found while looking into the work needed for #24453 which aims to merge ghc-prim, ghc-bignum, and ghc-internal. It's also one step closer to remove ghc-prim's custom setup. - - - - - a55adc8e by Cheng Shao at 2024-11-07T19:28:22-05:00 Clean up obsolete CPP guarded code paths from the tree This patch cleans up obsolete CPP guarded code paths from the tree. The minimum supported boot GHC version is 9.6, and all the pre-9.6 era code paths can be removed. - - - - - 9ede97f3 by Cheng Shao at 2024-11-07T19:28:58-05:00 Remove obsolete executable wrappers from the tree The executable wrappers are handled by hadrian and bindist Makefile. The various .wrapper scripts in the tree are unused since removal of Make build system, so this patch removes them all. - - - - - 7d42b2df by tristian at 2024-11-07T19:29:40-05:00 TcRnDuplicateDecls now suggests to use the DuplicateRecordFields extension. Fixes: !24627 - - - - - e56ed179 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: normalise some versions in callstacks (cherry picked from commit f230e29f30d0c1c566d4dd251807fcab76a2710e) - - - - - a28fc903 by Zubin Duggal at 2024-11-11T15:16:35+05:30 testsuite: use -fhide-source-paths to normalise some backpack tests (cherry picked from commit b19de476bc5ce5c7792e8af1354b94a4286a1a13) - - - - - ed16d303 by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite/haddock: strip version identifiers and unit hashes from html tests (cherry picked from commit fbf0889eadc410d43dd5c1657e320634b6738fa5) - - - - - e45e5836 by Zubin Duggal at 2024-11-11T15:16:36+05:30 haddock: oneshot tests can drop files if they share modtimes. Stop this by including the filename in the key. Ideally we would use `ghc -M` output to do a proper toposort Partially addresses #25372 (cherry picked from commit e78c7ef96e395f1ef41f04790aebecd0409b92b9) - - - - - 9104e6eb by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: fix normalisation of T9930fail so that it doesn't get tripped up by ghc executable (ARGV[0]) differences (cherry picked from commit a79a587e025d42d34bb30e115fc5c7cab6c1e030) - - - - - 2c31264a by Zubin Duggal at 2024-11-11T15:16:36+05:30 testsuite: normalise windows file seperators (cherry picked from commit f858875e03b9609656b542aaaaff85ad0a83878a) - - - - - 2807f91b by Zubin Duggal at 2024-11-11T15:21:30+05:30 testsuite: Also match <VERSION> placeholders when normalising callsites - - - - - c02add17 by Ben Gamari at 2024-11-12T01:22:11-05:00 configure: Check version number validity Here we verify the previously informal invariant that stable release version numbers must have three components, preventing costly failed releases. Specifically, the check fails in the following scenarios: * `version=9.13` while `RELEASE=YES` since this would imply a release made from an unstable branch * `version=9.13.0` since unstable versions should only have two components * `version=9.12` since this has the wrong number of version components for a stable branch Fixes #25390. - - - - - 747fd322 by Teo Camarasu at 2024-11-12T01:22:49-05:00 docs: link to #14474 in the template-haskell docs - - - - - 6d96bb62 by Zubin Duggal at 2024-11-12T01:23:25-05:00 testsuite: normalise execvp vs exec differences in process tests Fixes #25431 - - - - - 502e6711 by Torsten Schmits at 2024-11-12T01:24:01-05:00 fix test lint that accumulated while the checks were broken I didn't fix the issues flagged by the #ifdef linter because it were so many that it seemed like the rule has become obsolete. - - - - - 223a4cb5 by Torsten Schmits at 2024-11-12T01:24:02-05:00 test driver: fix file collection for regex linters When a testsuite linter is executed with the `tracked` strategy, the driver runs `git ls-tree` to collect eligible files. This appears to have ceased producing any paths – `ls-tree` restricts its results to the current working directory, which is `testsuite/tests/linters` in this case. As a quick fix, this patch changes the working directory to match expectations. - - - - - 9ad9ac63 by Alan Zimmerman at 2024-11-12T01:24:39-05:00 EPA: Capture location of '_' for wild card type binder And keep track of promotion status in HsExplicitTupleTy, so the round-trip ppr test works for it. Updates Haddock output too, using the PromotionFlag in HsExplicitTupleTy. Closes #25454 - - - - - c37b96fa by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix setImmediate() implementation for Cloudflare Workers This patch fixes setImmediate() implementation for Cloudflare Workers in the wasm backend's js prelude script. Cloudflare Workers doesn't support the MessageChannel API, and we use a setTimeout() based fallback implementation in this case. - - - - - bea8ea4c by Cheng Shao at 2024-11-12T01:25:15-05:00 wasm: fix FinalizationRegistry logic for Cloudflare Workers This patch fixes FinalizationRegistry related logic for Cloudflare Workers in wasm backend js post linker. Cloudflare Workers doesn't support FinalizationRegistry, in this case we use a dummy implementation that doesn't do anything. - - - - - 00d551bf by Cheng Shao at 2024-11-13T08:48:21-05:00 Remove obsolete cross-port script This patch removes the obsolete cross-port script in the tree. The script was based on the legacy Make build system which has been pruned from the tree long ago. For hadrian, proper support for two-stage bootstrapping onto a new unsupported platform is a work in progress in !11444. - - - - - 75a2eae4 by Cheng Shao at 2024-11-13T08:48:58-05:00 hadrian: fix bindist makefile for wasm32-wasi target This patch fixes one incoherent place between bindist makefile and hadrian logic: I forgot to include wasi/wasm32 in OsSupportsGHCi/ArchSupportsGHCi as well. And this results in incorrect settings file generated after installing the bindist, and "Use interpreter"/"Have interpreter" fields incorrectly have "NO" values where they should be "YES" like --info output of in-tree version. - - - - - 0614abef by Alan Zimmerman at 2024-11-13T08:49:34-05:00 EPA: Correctly capture leading semis in decl list Closes #25467 - - - - - 00d58ae1 by Sebastian Graf at 2024-11-13T15:21:23-05:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. - - - - - 93233a66 by Ben Gamari at 2024-11-13T15:21:59-05:00 boot: Do not attempt to update config.sub While Apple ARM hardware was new we found that the autoconf scripts included in some boot packages were too old. As a mitigation for this, we introduced logic in the `boot` script to update the `config.sub` with that from the GHC tree. However, this causes submodules which have `config.sub` committted to appear to be dirty. This is a considerable headache. Now since `config.sub` with full platform support is more common we can remove `boot`'s `config.sub` logic. Fixes #19574. - - - - - fa66fa64 by Ryan Scott at 2024-11-14T19:05:00-05:00 Add regression test for #16234 Issue #16234 was likely fixed by !9765. This adds a regression test to ensure that it remains fixed. Fixes #16234. - - - - - bfe64df8 by Matthew Pickering at 2024-11-14T19:05:36-05:00 ghc-internal: Update to Unicode 16 This patch updates the automatically generated code for querying unicode properties to unicode 16. Fixes #25402 - - - - - 1fd83f86 by Ben Gamari at 2024-11-14T19:06:13-05:00 configure: Accept happy-2.1.2 happy-2.1 was released in late Oct 2024. I have confirmed that master bootstraps with it. Here we teach configure to accept this tool. Fixes #25438. - - - - - aa58fc5b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Tighten up invariants of PACK - - - - - 8aa4c10a by Ben Gamari at 2024-11-14T19:06:49-05:00 testsuite: Fix badly escaped literals Use raw string literals to ensure that `\s` is correctly interpreted as a character class. - - - - - 0e084029 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts: Improve documentation of SLIDE bytecode instruction - - - - - 9bf3663b by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Assert that TEST*_P discriminators are valid - - - - - 1f668511 by Ben Gamari at 2024-11-14T19:06:49-05:00 rts/Interpreter: Improve documentation of TEST*_P instructions - - - - - 59e0a770 by Cheng Shao at 2024-11-14T19:07:25-05:00 misc: improve clangd compile_flags.txt flags This patch improves the compile_flags.txt config used to power clangd for the rts C codebase. The flags in the file are sampled & deduped from a real stage1 build with clang-19 and vastly improves the IDE accuracy when hacking the rts. For maximum code coverage under the default settings, compile_flags.txt defaults to threaded+profiled+dynamic+debug way. This does not mean profdyn needs to be actually built in _build/stage1 for IDE to work. To activate IDE for other RTS ways, simply remove one of the -D flags at the end of compile_flags.txt and restart clangd. - - - - - c2c562e0 by Ben Gamari at 2024-11-14T19:08:01-05:00 testsuite: Don't consider untracked files in dirtiness check Considering trees containing untracked files as dirty is a bridge too far. The chance of an untracked file significantly affecting measured performanced metrics is quite small whereas not collecting measurements is quite inconvenient for some workflows. We now ignore untracked files in the dirtiness check. Fixes #25471. - - - - - ed2ed6c5 by Cheng Shao at 2024-11-14T19:08:37-05:00 testsuite: add regression test T25473 This commit adds regression test T25473 marked as broken due to #25473. It will be fixed in the subsequent commit. - - - - - bd0a8b7e by Cheng Shao at 2024-11-14T19:08:37-05:00 wasm: fix foreign import javascript "wrapper" in TH/ghci This patch fixes foreign import javascript "wrapper" in wasm backend's TH/ghci by fixing the handling of dyld/finalization_registry magic variables. Fixes T25473 and closes #25473. - - - - - f1b0bc32 by Ben Gamari at 2024-11-14T19:09:13-05:00 rts/linker: Make FreeBSD declarations proper prototypes The iconv declarations for FreeBSD were previously not prototypes, leading to warnings. - - - - - 086cbbc1 by Ben Gamari at 2024-11-14T19:09:13-05:00 base: Drop redundant import in FreeBSD ExecutablePath implementation - - - - - 79ecd199 by Ben Gamari at 2024-11-14T19:09:13-05:00 compiler: Fix partial selector warnings in GHC.Runtime.Heap.Inspect - - - - - 1acb73bf by Andrew Lelechenko at 2024-11-15T06:10:47-05:00 gitlab: mention CLC in MR template - - - - - 8f2e0832 by Ben Gamari at 2024-11-15T06:11:24-05:00 rts: Allow use of GNU-stack notes on FreeBSD Previously we gated use of GNU-style non-executable stack notes to only apply on Linux. However, these are also supported by FreeBSD, which also uses ELF. Fix this. Fixes #25475. - - - - - 2c427cb0 by Ben Gamari at 2024-11-16T05:27:40-05:00 rts: Fix EINTR check in timerfd ticker When `poll` failed we previously checked that `errno == -EINTR` to silence the failure warning. However, this is wrong as `errno` values are generally not negated error codes (in contrast to many system call results, which is likely what the original author had in mind). Fixes #25477. - - - - - a0fa4941 by Ben Gamari at 2024-11-16T05:28:16-05:00 rts: Increase gen_workspace alignment to 128 bytes on AArch64 Increase to match the 128-byte cache-line size of Apple's ARMv8 implementation. Closes #25459. - - - - - 142d8afa by Ben Gamari at 2024-11-16T16:20:47-05:00 rts/RtsFlags: Refactor size parsing This makes a number of improvements mentioned in #20201: * fail if the argument cannot be parsed as a number (`-Mturtles`) * fail if an unrecognized unit is given (e.g. `-M1x`) - - - - - b7a146e5 by Ben Gamari at 2024-11-16T16:20:47-05:00 testsuite: Add tests for RTS flag parsing error handling See #20201. - - - - - ddb7afa6 by Ben Gamari at 2024-11-16T16:21:23-05:00 users guide: Mention language extensions in equality constraints discussion As suggested in #24127, mention the language extensions necessary for usage of equality constriants in their documentation. Closes #24127. - - - - - 36133dac by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/9.14.1-notes: Fix list syntax - - - - - 888de658 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide/debug-info: Fix duplicate flag descriptions - - - - - f120e427 by Ben Gamari at 2024-11-16T16:21:23-05:00 users-guide: Fix reference to 9.14.1 release notes - - - - - 8e975032 by Ben Gamari at 2024-11-16T16:21:59-05:00 Introduce GHC.Tc.Plugin.lookupTHName This makes it significantly more convenient (and less GHC-version-dependent) to resolve a template-haskell name into a GHC Name. As proposed in #24741. - - - - - a0e168ec by ARATA Mizuki at 2024-11-16T16:22:40-05:00 x86 NCG SIMD: Lower packFloatX4#, insertFloatX4# and broadcastFloatX4# to SSE1 instructions Fixes #25441 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 3936bf1b by sheaf at 2024-11-16T16:23:22-05:00 X86 NCG: allow VXOR at scalar floating-point types The NCG can emit VXOR instructions at scalar floating-point types, but the pretty-printer would panic instead of emitting the appropriate VXORPS/VXORPD instructions. This patch rectifies that oversight. Fixes #25455 - - - - - d9dff93a by Ben Gamari at 2024-11-16T16:23:58-05:00 rts: Fix platform-dependent pointer casts Previously we had unnecessary (and incorrect) platform-dependent casts to turn `OSThreadIds`s into a integer. We now just uniformly cast first to a `uintptr_t` (which is always safe, regardless of whether `OSThreadId` is a pointer), and then cast to the desired integral type. This fixes a warning on musl platforms. - - - - - 6d95cdb8 by Ben Gamari at 2024-11-16T16:24:34-05:00 testsuite: Mark encoding004 as broken on FreeBSD Due to #22003, CP936 fails to roundtrip: ```diff == CP936 +Failed to roundtrip given mutant byte at index 891 (251 /= 123 at index 891) +Failed to roundtrip given mutant byte at index 1605 (197 /= 69 at index 1605) +Failed to roundtrip given mutant byte at index 2411 (235 /= 107 at index 2411) +Failed to roundtrip given mutant byte at index 6480 (208 /= 80 at index 6480) +Failed to roundtrip given mutant byte at index 6482 (210 /= 82 at index 6482) +Failed to roundtrip given mutant byte at index 6484 (212 /= 84 at index 6484) +Failed to roundtrip given mutant byte at index 6496 (224 /= 96 at index 6496) +Failed to roundtrip given mutant byte at index 7243 (203 /= 75 at index 7243) +Failed to roundtrip given mutant byte at index 7277 (237 /= 109 at index 7277) +Failed to roundtrip given mutant byte at index 8027 (219 /= 91 at index 8027) +Failed to roundtrip given mutant byte at index 8801 (225 /= 97 at index 8801) ``` - - - - - 26e86984 by Ben Gamari at 2024-11-18T04:05:31-05:00 hadrian: Allow haddock options to be passed via key-value settings - - - - - 6e68b117 by Matthew Pickering at 2024-11-18T04:06:07-05:00 Exception rethrowing Basic changes: * Change `catch` function to propagate exceptions using the WhileHandling mechanism. * Introduce `catchNoPropagate`, which does the same as before, but passes an exception which can be rethrown. * Introduce `rethrowIO` combinator, which rethrows an exception with a context and doesn't add a new backtrace. * Introduce `tryWithContext` for a variant of `try` which can rethrow the exception with it's original context. * onException is modified to rethrow the original error rather than creating a new callstack. * Functions which rethrow in GHC.Internal.IO.Handle.FD, GHC.Internal.IO.Handle.Internals, GHC.Internal.IO.Handle.Text, and GHC.Internal.System.IO.Error are modified to not add a new callstack. Implements CLC proposal#202 <https://github.com/haskell/core-libraries-committee/issues/202> - - - - - a4e0d235 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 exceptions: Improve the message layout as per #285 This commit fixes the layout of the additional information included when displaying an exception, namely the type of the exception. It also fixes the default handler's heading message to work well together with the improved display message of SomeException. CLC proposal#285 - - - - - 284ffab3 by Rodrigo Mesquita at 2024-11-18T04:06:07-05:00 Display type and callstack of exception on handler This commit changes the Exception instance of SomeException to *simply* display the underlying exception in `displayException`. The augmented exception message that included the type and backtrace of the exception are now only printed on a call to `displayExceptionWithInfo`. At a surface level, existing programs should behave the same since the `uncaughtExceptionHandler`, which is responsible for printing out uncaught exceptions to the user, will use `displayExceptionWithInfo` by default. However, unlike the instance's `displayException` method, the `uncaughtExceptionHandler` can be overriden with `setUncaughtExceptionHandler`. This makes the extra information opt-in without fixing it the instance, which can be valuable if your program wants to display uncaught exceptions to users in a user-facing way (ie without backtraces). This is what was originally agreed for CLC#231 or CLC#261 with regard to the type of the exception information. The call stack also becoming part of the default handler rather than the Exception instance is an ammendment to CLC#164. Discussion of the ammendment is part of CLC#285. - - - - - 36cddd2c by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Remove redundant CallStack from exceptions Before the exception backtraces proposal was implemented, ErrorCall accumulated its own callstack via HasCallStack constraints, but ExceptionContext is now accumulated automatically. The original ErrorCall mechanism is now redundant and we get a duplicate CallStack Updates Cabal submodule to fix their usage of ErrorCallWithLocation to ErrorCall CLC proposal#285 Fixes #25283 - - - - - 7a74330b by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Freeze call stack in error throwing functions CLC proposal#285 - - - - - 3abf31a4 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 De-duplicate displayContext and displayExceptionContext The former was unused except for one module where it was essentially re-defining displayExceptionContext. Moreover, this commit extends the fix from bfe600f5bb3ecd2c8fa71c536c63d3c46984e3f8 to displayExceptionContext too, which was missing. - - - - - c0d783f8 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Re-export NoBacktrace from Control.Exception This was originally proposed and accepted in section "2.7 Capturing Backtraces on Exceptions" of the CLC proposal for exception backtraces. However, the implementation missed this re-export, which this commit now fixes. - - - - - 802b5c3e by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Fix exception backtraces from GHCi When running the program with `runhaskell`/`runghc` the backtrace should match the backtrace one would get by compiling and running the program. But currently, an exception thrown in a program interpreted with `runhaskell` will: * Not include the original exception backtrace at all * Include the backtrace from the internal GHCi/ghc rethrowing of the original exception This commit fixes this divergence by not annotating the ghc(i) backtrace (with NoBacktrace) and making sure that the backtrace of the original exception is serialized across the boundary and rethrown with the appropriate context. Fixes #25116 The !13301 MR (not this commit in particular) improves performance of MultiLayerModules. Unfortunately, T3294 regresses on aarch64-linux-deb12 by 1% allocations. Since this patch must be merged for 9.12 ASAP, we will not be able to investigate the slight regression on this platform in time. ------------------------- Metric Decrease: MultiLayerModulesRecomp MultiLayerModulesTH_OneShot Metric Increase: T3294 ------------------------- - - - - - 3e89eb65 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 base: Add to changelog.md CLC #285 - - - - - d9326a48 by Rodrigo Mesquita at 2024-11-18T04:06:08-05:00 Bump array and stm submodules for testsuite The testsuites of array and stm had to be updated according to !13301. Updates submodule array and stm. - - - - - 325fcb5d by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Clean up code style of Nativei386 adjustor - - - - - 39bb6e58 by Ben Gamari at 2024-11-18T04:06:45-05:00 rts/adjustor: Fix stack overrun error in Nativei386 adjustor We were reserving the wrong kind of adjustor context (the generic `AdjustorContext` used by other adjustor implementations, rather than the i386-specific `CCallContext`) to return the adjustor context while freeing, resulting in #25485. Fixes #25485. - - - - - 831aab22 by sheaf at 2024-11-18T21:22:36-05:00 Include diagnostic reason in -fdiagnostics-as-json This commit ensures that the -fdiagnostics-as-json output includes the diagnostic reason. This allows the full error message produced by GHC to be re-constructed from the JSON output. Fixes #25403 - - - - - 3e5bfdd3 by Ben Gamari at 2024-11-18T21:23:12-05:00 rts: Introduce printIPE This is a convenience utility for use in GDB. - - - - - 44d909a3 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Don't store boot locations in finder cache Partially reverts commit fff55592a7b Amends add(Home)ModuleToFinder so that locations for boot files are not stored in the finder cache. Removes InstalledModule field from InstalledFound constructor since it's the same as the key that was searched for. - - - - - 64c95292 by Sjoerd Visscher at 2024-11-19T14:38:24-05:00 Concentrate boot extension logic in Finder With new mkHomeModLocation that takes an extra HscSource to add boot extensions if required. - - - - - 11bad98d by ARATA Mizuki at 2024-11-19T14:39:08-05:00 Better documentation for floating-point min/max and SIMD primitives See #25350 for floating-point min/max Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 791a47b2 by Arnaud Spiwack at 2024-11-20T14:00:05+00:00 Add test for #25185 - - - - - 374e18e5 by Arnaud Spiwack at 2024-11-20T14:09:30+00:00 Quick look: emit the multiplicity of app heads in tcValArgs Otherwise it's not scaled properly by the context, allowing unsound expressions. Fixes #25185. - - - - - 1fc02399 by sheaf at 2024-11-20T18:11:03-05:00 x86 NCG: fix regUsageOfInstr for VMOVU & friends This commit fixes the implementation of 'regUsageOfInstr' for vector operations that take an 'Operand' as the destination, by ensuring that when the destination is an address then the address should be *READ*, and not *WRITTEN*. Getting this wrong is a disaster, as it means the register allocator has incorrect information, which can lead to it discard stores to registers, segfaults ensuing. Fixes #25486 - - - - - 7bd407a6 by Brandon Chinn at 2024-11-21T14:08:15-05:00 Fix CRLF in multiline strings (#25375) - - - - - 7575709b by Rodrigo Mesquita at 2024-11-21T14:08:52-05:00 Improve reachability queries on ModuleGraph Introduces `ReachabilityIndex`, an index constructed from a `GHC.Data.Graph.Directed` `Graph` that supports fast reachability queries (in $O(1)$). This abstract data structure is exposed from `GHC.Data.Graph.Directed.Reachability`. This index is constructed from the module graph nodes and cached in `ModuleGraph`, enabling efficient reachability queries on the module graph. Previously, we'd construct a Map of Set of ModuleGraph nodes which used a lot of memory (`O(n^2)` in the number of nodes) and cache that in the `ModuleGraph`. By using the reachability index we get rid of this space leak in the module graph -- even though the index is still quadratic in the number of modules, it is much, much more space efficient due to its representation using an IntMap of IntSet as opposed to the transitive closure we previously cached. In a memory profile of MultiLayerModules with 100x100 modules, memory usage improved from 6GB residency to 2.8GB, out of which roughly 1.8GB are caused by a second space leak related to ModuleGraph. On the same program, it brings compile time from 7.5s to 5.5s. Note how we simplify `checkHomeUnitsClosed` in terms of `isReachableMany` and by avoiding constructing a second graph with the full transitive closure -- it suffices to answer the reachability query on the full graph without collapsing the transitive closure completely into nodes. Unfortunately, solving this leak means we have to do a little bit more work since we can no longer cache the result of turning vertex indices into nodes. This results in a slight regression in MultiLayerModulesTH_Make, but results in large performance and memory wins when compiling large amounts of modules. ------------------------- Metric Decrease: mhu-perf Metric Increase: MultiLayerModulesTH_Make ------------------------- - - - - - bcbcdaaf by Cheng Shao at 2024-11-21T14:09:28-05:00 driver: fix hpc undefined symbol issue in TH with -fprefer-byte-code This commit fixes an undefined symbol error in RTS linker when attempting to compile home modules with -fhpc and -fbyte-code-and-object-code/-fprefer-byte-code, see #25510 for detailed description and analysis of the bug. Also adds T25510/T25510c regression tests to test make mode/oneshot mode of the bug. - - - - - 970ada5a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Bump ci-images For introduction of Alpine/i386 image. Thanks to Julian for the base image. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 8115abc2 by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Add release job for i386/Alpine As requested by Mikolaj and started by Julian. Co-Authored-By: Julian Ospald <hasufell at hasufell.de> - - - - - 639f0149 by Ben Gamari at 2024-11-22T23:32:06-05:00 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ - - - - - 490d4d0a by Ben Gamari at 2024-11-22T23:32:06-05:00 gitlab-ci: Mark i386 Alpine test breakages Marks the following tests as broken on i386/Alpine: * T22033 due to #25497 * simd009, T25062_V16, T25169, T22187_run due to #25498 - - - - - 536cdf09 by Cheng Shao at 2024-11-22T23:32:42-05:00 compiler: remove unused GHC.Linker.Loader.loadExpr This patch removes the unused `GHC.Linker.Loader.loadExpr` function. It was moved from `GHC.Runtime.Linker.linkExpr` in `ghc-9.0` to `GHC.Linker.Loader.loadExpr` in `ghc-9.2`, and remain completely unused and untested ever since. There's also no third party user of this function to my best knowledge, so let's remove this. Anyone who wants to write their own GHC API function to load bytecode can consult the source code in older release branches. - - - - - 6ee35024 by Drew Fenwick at 2024-11-22T23:33:26-05:00 Fix a non-compiling example in the type abstractions docs This patch adds a missing Show constraint to a code example in the User Guide's type abstractions docs to fix issue #25422. - - - - - d1172e20 by Rodrigo Mesquita at 2024-11-22T23:34:02-05:00 Re-introduce ErrorCallWithLocation with a deprecation pragma With the removal of the duplicate backtrace, part of CLC proposal #285, the constructor `ErrorCallWithLocation` was removed from base. This commit re-introduces it with a deprecation. - - - - - 1187a60a by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Skip tests requiring Hadrian deps in out-of-tree testsuite runs Some testsuite tests require specific tools (e.g. `check-ppr` and `check-exact`) beyond those shipped in the binary distribution. Skip these tests. Fixes #13897. - - - - - c37d7a2e by Ben Gamari at 2024-11-22T23:34:39-05:00 testsuite: Declare exactprint tests' dependency on check-exact - - - - - 454ce957 by Ben Gamari at 2024-11-22T23:35:15-05:00 ghc-internal: Fix a few cases of missing Haddock markup - - - - - a249649b by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/GHCiPrimCall : Add missing Makefile includes - - - - - a021a493 by Ben Gamari at 2024-11-22T23:35:51-05:00 testsuite/IpeStats: Use Make rather than shell interpolation - - - - - 6e1fbda7 by Ben Gamari at 2024-11-25T03:55:44-05:00 hadrian-ghci-multi: Pass -this-package-name in unit response files As noted in #25509, the `-this-package-name` must be passed for each package to ensure that GHC can response references to the packages' exposed modules via package-qualified imports. Fix this. Closes #25509. - - - - - a05e4a9b by Simon Hengel at 2024-11-25T03:56:33-05:00 Refactoring: Use `OnOff` more consistently for `Extension` - - - - - 7536181d by Matthew Pickering at 2024-11-25T14:00:07-05:00 driver: Always link against "base" package when one shot linking The default value for base-unit-id is stored in the settings file. At install time, this can be set by using the BASE_UNIT_ID environment variable. At runtime, the value can be set by `-base-unit-id` flag. For whether all this is a good idea, see #25382 Fixes #25382 - - - - - 7f90f319 by Andreas Klebinger at 2024-11-25T14:00:44-05:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 - - - - - 291388e1 by Cheng Shao at 2024-11-25T14:01:19-05:00 ci: minor nix-in-docker improvements This patch makes some minor improvements re nix-in-docker logic in the ci configuration: - Update `nixos/nix` to the latest version - Apply $CPUS to `cores`/`max-jobs` to avoid oversubscribing while allowing a reasonable degree of parallelism - Remove redundant `--extra-experimental-features nix-command` in later `nix shell` invocations, it's already configured in `/etc/nix/nix.conf` - - - - - e684c406 by Cheng Shao at 2024-11-25T14:01:57-05:00 ci: avoid depending on stack job for test-bootstrap jobs This patch makes test-bootstrap related ci jobs only depend on hadrian-ghc-in-ghci job to finish, consistent with other jobs in the full-build stage generated by gen_ci.hs. This allows the jobs to be spawned earlier and improve overall pipeline parallelism. - - - - - caaf5388 by Simon Hengel at 2024-11-25T14:02:41-05:00 Refactoring: Remove `pSupportedExts` from `ParserOpts` This is never used for lexing / parsing. It is only used by `GHC.Parser.Header.getOptions`. - - - - - 41f8365c by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Add test for #25515 - - - - - 9279619f by Arnaud Spiwack at 2024-11-25T14:03:23-05:00 Desugar record notation with correct multiplicities Simply uses the multiplicity as stored in the field. As I'm writing this commit, the only possible multiplicity is 1, but !13525 is changing this. It's actually easier to take !13525 into account. Fixes #25515. - - - - - fcc3ae6e by Andreas Klebinger at 2024-11-26T08:24:58-05:00 Clarify INLINE unfolding optimization docs. Fixes #24660 - - - - - 88c4fe1d by Cheng Shao at 2024-11-26T08:25:34-05:00 rts: remove -Wl,-U,___darwin_check_fd_set_overflow hack This patch bumps macOS minimum SDK version to 11.0 for x86_64-darwin to align it with aarch64-darwin. This allows us to get rid of the horrible -Wl,-U,___darwin_check_fd_set_overflow hack, which is causing linker warnings and testsuite failures on macOS 15. Fixes #25504. - - - - - 53f978c0 by doyougnu at 2024-11-26T16:07:26-05:00 ghc-experimental: expose GHC.RTS.Flags, GHC.Stats See this CLC proposal: - https://github.com/haskell/core-libraries-committee/issues/289 and this CLC proposal for background: - https://github.com/haskell/core-libraries-committee/issues/288 Metric Decrease: MultiLayerModulesTH_OneShot - - - - - e70d4140 by Wang Xin at 2024-11-26T16:08:10-05:00 Add -mcmodel=medium moduleflag to generated LLVM IR on LoongArch platform With the Medium code model, the jump range of the generated jump instruction is larger than that of the Small code model. It's a temporary fix of the problem descriped in https://gitlab.haskell .org/ghc/ghc/-/issues/25495. This commit requires that the LLVM used contains the code of commit 9dd1d451d9719aa91b3bdd59c0c6679 83e1baf05, i.e., version 8.0 and later. Actually we should not rely on LLVM, so the only way to solve this problem is to implement the LoongArch backend. Add new type for codemodel - - - - - df42ba16 by Andreas Klebinger at 2024-11-27T11:40:49-05:00 Cmm constant folding: Narrow results to operations bitwidth. When constant folding ensure the result is still within bounds for the given type by explicitly narrowing the results. Not doing so results in a lot of spurious assembler warnings especially when testing primops. - - - - - bf3db97e by Ben Gamari at 2024-11-27T11:41:26-05:00 ghc-toolchain: Introduce basic flag validation We verify that required flags (currently `--output` and `--triple`) are provided. The implementation is truly awful, but so is getopt. Begins to address #25500. - - - - - a104508d by Ben Gamari at 2024-11-27T11:42:03-05:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. - - - - - c3fc9b86 by Ben Gamari at 2024-11-27T11:42:39-05:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. - - - - - a362b943 by sheaf at 2024-11-27T23:44:28-05:00 Add checkExact to toolTargets This change means that the Hadrian multi target will include exactprint. In particular, this means that HLS will work on exactprint inside the GHC tree. - - - - - e6c957e4 by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Add test for #25428 - - - - - 52d97f4e by Arnaud Spiwack at 2024-11-27T23:45:09-05:00 Don't bypass MonoLocalBind in empty patterns Fixes #25428 - - - - - 7890f2d8 by Ben Gamari at 2024-11-28T10:26:46-05:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. - - - - - 0fd43ea6 by Adam Sandberg Ericsson at 2024-11-28T10:27:22-05:00 mention -Iw in +RTS -? - - - - - 6cf579b9 by Ben Gamari at 2024-11-28T10:27:59-05:00 gitlab-ci: Set GIT_SUBMODULE_FORCE_HTTPS GitLab recommends using `https://` to clone submodules and provides the `GIT_SUBMODULE_FORCE_HTTPS` variable to force this. Fixes #25528. - - - - - 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - b500e6a4 by Ben Gamari at 2025-01-23T11:41:58-05:00 CorePrep: Name `sat` binders more descriptively - - - - - 6 changed files: - .ghcid - .gitattributes - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/generate-ci/gen_ci.hs - .gitlab/hello.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/88566524713e17736a68999a0620044a27024921...b500e6a4c39f76473c7ac453128b6009f3033269 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/88566524713e17736a68999a0620044a27024921...b500e6a4c39f76473c7ac453128b6009f3033269 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 16:45:40 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 23 Jan 2025 11:45:40 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Rework built-in and punned names (#25174, #25179, #25180, #25182) Message-ID: <67927233f193d_3e7a8e13ab4b01062f5@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 51e3ec83 by Vladislav Zavialov at 2025-01-22T20:41:32+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 9ac6c521 by Brandon Chinn at 2025-01-23T11:45:16-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 8391cda0 by Brandon Chinn at 2025-01-23T11:45:16-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - 112eaa74 by Teo Camarasu at 2025-01-23T11:45:17-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Name/Cache.hs - compiler/GHC/Types/Name/Ppr.hs - compiler/ghc.cabal.in - docs/users_guide/conf.py - docs/users_guide/expected-undocumented-flags.txt - + docs/users_guide/exts/doandifthenelse.rst - docs/users_guide/exts/syntax.rst - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/ghc-api/T18522-dbg-ppr.hs - testsuite/tests/interface-stability/ghc-experimental-exports.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b21c689b4a257db011c6ddbe5c2c72db8fa375c1...112eaa748dfada399de82108c68646f806b522a9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b21c689b4a257db011c6ddbe5c2c72db8fa375c1...112eaa748dfada399de82108c68646f806b522a9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 16:46:39 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 11:46:39 -0500 Subject: [Git][ghc/ghc][wip/T18462] Unannotated multiplicity based on type Message-ID: <6792726f148b8_3e7a8e158395411313d@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 6e6533de by Sjoerd Visscher at 2025-01-23T17:46:14+01:00 Unannotated multiplicity based on type - - - - - 28 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr - testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr - testsuite/tests/parser/should_compile/DumpParsedAst.stderr - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/parser/should_compile/T14189.stderr - testsuite/tests/printer/T18791.stderr - utils/check-exact/ExactPrint.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/Rename.hs Changes: ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -539,11 +539,11 @@ deriving instance Data (HsTyLit GhcTc) -- deriving instance (Data mult, DataIdLR p p, Typeable on) => Data (HsMultAnnOn on mult p) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsType GhcPs)) GhcPs) -deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsType GhcPs)) GhcPs) +deriving instance Data (HsMultAnnOn OnConField (LocatedA (HsType GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsType GhcTc)) GhcTc) deriving instance Data (HsMultAnnOn OnArrow (LocatedA (HsExpr GhcPs)) GhcPs) -deriving instance Data (HsMultAnnOn OnRecField (LocatedA (HsExpr GhcPs)) GhcPs) +deriving instance Data (HsMultAnnOn OnConField (LocatedA (HsExpr GhcPs)) GhcPs) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcRn)) GhcRn) deriving instance Typeable on => Data (HsMultAnnOn on (LocatedA (HsExpr GhcTc)) GhcTc) @@ -559,7 +559,7 @@ deriving instance Data (ConDeclField GhcTc) -- deriving instance (DataIdLR p p, Typeable on) => Data (HsConFieldSpec on p) deriving instance Data (HsConFieldSpec OnArrow GhcPs) -deriving instance Data (HsConFieldSpec OnRecField GhcPs) +deriving instance Data (HsConFieldSpec OnConField GhcPs) deriving instance Typeable on => Data (HsConFieldSpec on GhcRn) deriving instance Typeable on => Data (HsConFieldSpec on GhcTc) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -26,9 +26,9 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( Mult, HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), - HsUnannotatedMult(..), pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, + pattern HsUnrestrictedArrow, multAnnToHsType, expandHsMultAnnOn, EpLinearArrow(..), - hsNoMultAnn, isUnrestricted, hsMultIsLinear, + hsNoMultAnn, isUnrestricted, pprHsArrow, HsType(..), HsCoreTy, LHsType, HsKind, LHsKind, @@ -129,7 +129,7 @@ import GHC.Utils.Outputable import GHC.Utils.Misc (count) import Data.Maybe -import Data.Data (Data) +import Data.Data (Data, Proxy (..)) import qualified Data.Semigroup as S import GHC.Data.Bag @@ -531,39 +531,46 @@ instance NoAnn EpLinearArrow where noAnn = EpPct1 noAnn noAnn type instance XUnannotated OnArrow _ GhcPs = TokRarrow -type instance XUnannotated OnRecField _ GhcPs = TokDcolon +type instance XUnannotated OnConField _ GhcPs = TokDcolon type instance XUnannotated _ _ GhcRn = NoExtField type instance XUnannotated _ _ GhcTc = NoExtField type instance XLinearAnn OnArrow _ GhcPs = EpLinearArrow -type instance XLinearAnn OnRecField _ GhcPs = (EpToken "%1", TokDcolon) +type instance XLinearAnn OnConField _ GhcPs = (EpToken "%1", TokDcolon) type instance XLinearAnn _ _ GhcRn = NoExtField type instance XLinearAnn _ _ GhcTc = NoExtField type instance XExplicitMult OnArrow _ GhcPs = (EpToken "%", TokRarrow) -type instance XExplicitMult OnRecField _ GhcPs = (EpToken "%", TokDcolon) +type instance XExplicitMult OnConField _ GhcPs = (EpToken "%", TokDcolon) type instance XExplicitMult _ _ GhcRn = NoExtField type instance XExplicitMult _ _ GhcTc = NoExtField type instance XXMultAnnOn _ _ (GhcPass _) = DataConCantHappen -hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => HsMultAnnOn on (LHsType GhcPs) GhcPs -hsNoMultAnn = HsUnannotated HsUnannOne noAnn +hsNoMultAnn :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) + => HsMultAnnOn on (LHsType GhcPs) GhcPs +hsNoMultAnn = HsUnannotated noAnn isUnrestricted :: HsArrow GhcRn -> Bool isUnrestricted (multAnnToHsType -> L _ (HsTyVar _ _ (L _ n))) = n == manyDataConName isUnrestricted _ = False -multAnnToHsType :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> LHsType GhcRn +multAnnToHsType :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> LHsType GhcRn multAnnToHsType = expandHsMultAnnOn (HsTyVar noAnn NotPromoted) -- | Convert an multiplicity annotation into its corresponding multiplicity. -- In essence this erases the information of whether the programmer wrote an explicit -- multiplicity or a shorthand. -- In this polymorphic function, `t` can be `HsType` or `HsExpr` -expandHsMultAnnOn :: (LocatedN Name -> t GhcRn) -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn -> LocatedA (t GhcRn) -expandHsMultAnnOn mk_var (HsUnannotated HsUnannOne _) = noLocA (mk_var (noLocA oneDataConName)) -expandHsMultAnnOn mk_var (HsUnannotated HsUnannMany _) = noLocA (mk_var (noLocA manyDataConName)) +expandHsMultAnnOn :: forall on t. IsHsMultAnnOnWhat on + => (LocatedN Name -> t GhcRn) + -> HsMultAnnOn on (LocatedA (t GhcRn)) GhcRn + -> LocatedA (t GhcRn) +expandHsMultAnnOn mk_var (HsUnannotated _) = noLocA (mk_var (noLocA mult)) + where + mult = case hsMultAnnOnWhat (Proxy :: Proxy on) of + OnArrow -> manyDataConName + OnConField -> oneDataConName expandHsMultAnnOn mk_var (HsLinearAnn _) = noLocA (mk_var (noLocA oneDataConName)) expandHsMultAnnOn _mk_var (HsExplicitMult _ p) = p @@ -574,7 +581,7 @@ instance -- See #18846 pprHsArrow :: (Outputable mult, OutputableBndrId pass) => HsArrowOf mult (GhcPass pass) -> SDoc -pprHsArrow (HsUnannotated _ _) = pprArrowWithMultiplicity visArgTypeLike (Left False) +pprHsArrow (HsUnannotated _) = pprArrowWithMultiplicity visArgTypeLike (Left False) pprHsArrow (HsLinearAnn _) = pprArrowWithMultiplicity visArgTypeLike (Left True) pprHsArrow (HsExplicitMult _ p) = pprArrowWithMultiplicity visArgTypeLike (Right (ppr p)) @@ -591,7 +598,7 @@ instance OutputableBndrId p ppr_mult :: HsMultAnnOn on (LHsType (GhcPass p)) (GhcPass p) -> SDoc -> SDoc ppr_mult mult tyDoc = case mult of - HsUnannotated _ _ -> dcolon <+> tyDoc + HsUnannotated _ -> dcolon <+> tyDoc HsLinearAnn _ -> text "%1" <+> dcolon <+> tyDoc HsExplicitMult _ p -> text "%" <> ppr p <+> dcolon <+> tyDoc @@ -1308,7 +1315,7 @@ pprHsConFieldSpecWith ppr_mult (CFS _ prag mark mult ty doc) = pprHsConFieldSpecNoMult :: (OutputableBndrId p) => HsConFieldSpec on (GhcPass p) -> SDoc pprHsConFieldSpecNoMult = pprHsConFieldSpecWith (\_ d -> d) -hsPlainTypeField :: LHsType GhcPs -> HsConFieldSpec OnArrow GhcPs +hsPlainTypeField :: NoAnn (XLinearAnn on (LHsType GhcPs) GhcPs) => LHsType GhcPs -> HsConFieldSpec on GhcPs hsPlainTypeField = mkConFieldSpec (HsLinearAnn noAnn) mkConFieldSpec :: HsMultAnnOn on (LHsType GhcPs) GhcPs -> LHsType GhcPs -> HsConFieldSpec on GhcPs ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -86,6 +86,7 @@ import GHC.Types.Name.Env import GHC.TypeLits import Data.Kind (Constraint) +import Data.Proxy import qualified GHC.LanguageExtensions as LangExt @@ -2861,14 +2862,22 @@ repGadtDataCons cons details res_ty -- TH currently only supports linear constructors. -- We also accept the (->) arrow when -XLinearTypes is off, because this -- denotes a linear field. -verifyLinearFields :: [HsConFieldSpec on GhcRn] -> MetaM () +verifyLinearFields :: forall on. IsHsMultAnnOnWhat on => [HsConFieldSpec on GhcRn] -> MetaM () verifyLinearFields ps = do linear <- lift $ xoptM LangExt.LinearTypes let allGood = all (hsMultIsLinear linear . cfs_multiplicity) ps unless allGood $ notHandled ThNonLinearDataCon + where + hsMultIsLinear linearTypesEnabled (HsUnannotated _) = + case hsMultAnnOnWhat (Proxy :: Proxy on) of + OnArrow -> not linearTypesEnabled + OnConField -> True + hsMultIsLinear _ HsLinearAnn{} = True + hsMultIsLinear _ _ = False -- Desugar the arguments in a data constructor declared with prefix syntax. -repPrefixConArgs :: [HsConFieldSpec OnArrow GhcRn] +repPrefixConArgs :: IsHsMultAnnOnWhat on + => [HsConFieldSpec on GhcRn] -> MetaM (Core [M TH.BangType]) repPrefixConArgs ps = do verifyLinearFields ps @@ -2885,7 +2894,7 @@ repRecConArgs lips = do where rep_ip ip = mapM (rep_one_ip (cd_fld_spec ip)) (cd_fld_names ip) - rep_one_ip :: HsConFieldSpec OnRecField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) + rep_one_ip :: HsConFieldSpec OnConField GhcRn -> LFieldOcc GhcRn -> MetaM (Core (M TH.VarBangType)) rep_one_ip t n = do { MkC v <- lookupOcc (unLoc . foLabel $ unLoc n) ; MkC ty <- repConFieldSpec t ; rep2 varBangTypeName [v,ty] } ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1795,7 +1795,7 @@ instance ToHie (LocatedL [LocatedA (ConDeclField GhcRn)]) where , toHie decls ] -instance ToHie (HsConFieldSpec on GhcRn) where +instance IsHsMultAnnOnWhat on => ToHie (HsConFieldSpec on GhcRn) where toHie (CFS _ _ _ w t doc) = concatM [ toHie (multAnnToHsType w) , toHie t ===================================== compiler/GHC/Parser.y ===================================== @@ -2601,7 +2601,7 @@ fielddecl :: { LConDeclField GhcPs } (ConDeclField noExtField (reverse (map (\ln@(L l n) -> L (fromTrailingN l) $ FieldOcc noExtField (L (noTrailingN l) n)) (unLoc $1))) - (mkConFieldSpec (HsUnannotated HsUnannOne (epUniTok $2)) $3)))} + (mkConFieldSpec (HsUnannotated (epUniTok $2)) $3)))} | sig_vars PREFIX_PERCENT atype '::' ctype {% amsA' (L (comb4 $1 $2 $3 $5) (ConDeclField noExtField ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -3520,7 +3520,7 @@ mkMultAnn pct t@(L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) pct1 = epTokenWidenR pct (locA (getLoc t)) mkMultAnn pct t = HsMultAnn pct t -mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnRecField GhcPs +mkMultField :: EpToken "%" -> LHsType GhcPs -> TokDcolon -> LHsType GhcPs -> HsConFieldSpec OnConField GhcPs mkMultField pct (L _ (HsTyLit _ (HsNumTy (SourceText (unpackFS -> "1")) 1))) col t -- See #18888 for the use of (SourceText "1") above = mkConFieldSpec (HsLinearAnn (pct1, col)) t ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -706,7 +706,7 @@ rnHsMultAnnOn env = rnHsMultAnnOnWith (rnLHsTyKi env) rnHsMultAnnOnWith :: (LocatedA (mult GhcPs) -> RnM (LocatedA (mult GhcRn), FreeVars)) -> HsMultAnnOn on (LocatedA (mult GhcPs)) GhcPs -> RnM (HsMultAnnOn on (LocatedA (mult GhcRn)) GhcRn, FreeVars) -rnHsMultAnnOnWith _rn (HsUnannotated mult _) = pure (HsUnannotated mult noExtField, emptyFVs) +rnHsMultAnnOnWith _rn (HsUnannotated _) = pure (HsUnannotated noExtField, emptyFVs) rnHsMultAnnOnWith _rn (HsLinearAnn _) = pure (HsLinearAnn noExtField, emptyFVs) rnHsMultAnnOnWith rn (HsExplicitMult _ p) = (\(mult, fvs) -> (HsExplicitMult noExtField mult, fvs)) <$> rn p ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1927,12 +1927,12 @@ rnDataDefn doc (HsDataDefn { dd_cType = cType, dd_ctxt = context, dd_cons = cond has_labelled_fields _ = False has_strictness_flags condecl - = any (isSrcStrict . cfs_bang) (con_args condecl) + = any isSrcStrict (con_arg_bangs condecl) - con_args (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = args - con_args (ConDeclH98 { con_args = PrefixCon _ args }) = args - con_args (ConDeclH98 { con_args = InfixCon arg1 arg2 }) = [arg1, arg2] - con_args _ = [] + con_arg_bangs (ConDeclGADT { con_g_args = PrefixConGADT _ args }) = map cfs_bang args + con_arg_bangs (ConDeclH98 { con_args = PrefixCon _ args }) = map cfs_bang args + con_arg_bangs (ConDeclH98 { con_args = InfixCon arg1 arg2 }) = [cfs_bang arg1, cfs_bang arg2] + con_arg_bangs _ = [] {- Note [Type data declarations] ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -1387,7 +1387,7 @@ rn_ty_pat ty@(XHsType{}) = do liftRnFV $ rnHsType ctxt ty rn_ty_pat_arrow :: HsArrow GhcPs -> TPRnM (HsArrow GhcRn) -rn_ty_pat_arrow (HsUnannotated mult _) = pure (HsUnannotated mult noExtField) +rn_ty_pat_arrow (HsUnannotated _) = pure (HsUnannotated noExtField) rn_ty_pat_arrow (HsLinearAnn _) = pure (HsLinearAnn noExtField) rn_ty_pat_arrow (HsExplicitMult _ p) = rn_lty_pat p <&> (\mult -> HsExplicitMult noExtField mult) ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -991,7 +991,7 @@ expr_to_type earg = ; return (L l (HsFunTy noExtField mult' arg' res'))} where go_arrow :: HsArrowOf (LHsExpr GhcRn) GhcRn -> TcM (HsArrow GhcRn) - go_arrow (HsUnannotated mult _) = pure (HsUnannotated mult noExtField) + go_arrow (HsUnannotated _) = pure (HsUnannotated noExtField) go_arrow (HsLinearAnn{}) = pure (HsLinearAnn noExtField) go_arrow (HsExplicitMult _ exp) = HsExplicitMult noExtField <$> go exp go (L l (HsForAll _ tele expr)) = ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -947,7 +947,7 @@ concern things that the renamer can't handle. -} -tcMult :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tcMult :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tcMult hc = tc_mult typeLevelMode hc -- | Info about the context in which we're checking a type. Currently, @@ -1364,7 +1364,7 @@ Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility] in "GHC.Core.TyCo -} ------------------------------------------ -tc_mult :: TcTyMode -> HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tc_mult :: IsHsMultAnnOnWhat on => TcTyMode -> HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tc_mult mode ty = tc_check_lhs_type mode (multAnnToHsType ty) multiplicityTy ------------------------------------------ tc_fun_type :: TcTyMode -> HsArrow GhcRn -> LHsType GhcRn -> LHsType GhcRn -> ExpKind ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -1806,7 +1806,8 @@ kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- This includes doing kind unification if the type is a newtype. -- See Note [Implementation of UnliftedNewtypes] for why we need -- the first two arguments. -kcConArgTys :: ConArgKind -- Expected kind of the argument(s) +kcConArgTys :: IsHsMultAnnOnWhat on + => ConArgKind -- Expected kind of the argument(s) -> [HsConFieldSpec on GhcRn] -- User-written argument types -> TcM () kcConArgTys exp_kind arg_tys @@ -3988,7 +3989,8 @@ tcConGADTArgs exp_kind (PrefixConGADT _ btys) tcConGADTArgs exp_kind (RecConGADT _ fields) = tcRecConDeclFields exp_kind fields -tcConArg :: ConArgKind -- expected kind for args; always OpenKind for datatypes, +tcConArg :: IsHsMultAnnOnWhat on + => ConArgKind -- expected kind for args; always OpenKind for datatypes, -- but might be an unlifted type with UnliftedNewtypes -> HsConFieldSpec on GhcRn -> TcM (Scaled TcType, HsSrcBang) tcConArg exp_kind (CFS (_, src) unp str w bty _) @@ -4011,7 +4013,7 @@ tcRecConDeclFields exp_kind fields exploded = concatMap explode combined (_,btys) = unzip exploded -tcDataConMult :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult +tcDataConMult :: IsHsMultAnnOnWhat on => HsMultAnnOn on (LHsType GhcRn) GhcRn -> TcM Mult tcDataConMult arr@(HsUnrestrictedArrow _) = do -- See Note [Function arrows in GADT constructors] linearEnabled <- xoptM LangExt.LinearTypes ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -776,7 +776,8 @@ cvtSrcStrictness NoSourceStrictness = NoSrcStrict cvtSrcStrictness SourceLazy = SrcLazy cvtSrcStrictness SourceStrict = SrcStrict -cvt_arg :: NoAnn (XUnannotated on (LHsType GhcPs) GhcPs) => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) +cvt_arg :: (NoAnn (XUnannotated on (LHsType GhcPs) GhcPs), IsHsMultAnnOnWhat on) + => (TH.Bang, TH.Type) -> CvtM (HsConFieldSpec on GhcPs) cvt_arg (Bang su ss, ty) = do { ty'' <- cvtType ty ; let ty' = parenthesizeHsType appPrec ty'' ===================================== compiler/Language/Haskell/Syntax/Decls.hs ===================================== @@ -1116,7 +1116,7 @@ or contexts in two parts: -- | The arguments in a Haskell98-style data constructor. type HsConDeclH98Details pass - = HsConDetails Void (HsConFieldSpec OnArrow pass) (XRec pass [LConDeclField pass]) + = HsConDetails Void (HsConFieldSpec OnConField pass) (XRec pass [LConDeclField pass]) -- The Void argument to HsConDetails here is a reflection of the fact that -- type applications are not allowed in data constructor declarations. ===================================== compiler/Language/Haskell/Syntax/Type.hs ===================================== @@ -22,10 +22,9 @@ GHC.Hs.Type: Abstract syntax: user-defined types -- See Note [Language.Haskell.Syntax.* Hierarchy] for why not GHC.Hs.* module Language.Haskell.Syntax.Type ( - HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), HsUnannotatedMult(..), + HsArrow, HsArrowOf, HsMultAnnOn(..), HsMultAnnOnWhat(..), IsHsMultAnnOnWhat(..), pattern HsUnrestrictedArrow, XUnannotated, XLinearAnn, XExplicitMult, XXMultAnnOn, - hsMultIsLinear, HsType(..), LHsType, HsKind, LHsKind, HsBndrVis(..), XBndrRequired, XBndrInvisible, XXBndrVis, @@ -919,28 +918,35 @@ data HsTyLit pass type HsArrow pass = HsArrowOf (LHsType pass) pass type HsArrowOf = HsMultAnnOn OnArrow --- HsMultAnnOn is used both to represent function arrows and multiplicity annotations --- in the record declaration syntax. But the default multiplicity is different --- between the two uses. In record syntax, the default is One, but on arrows, the --- default is Many. `HsUnannotatedMult` is used to distinguish between the two uses. -data HsUnannotatedMult = HsUnannOne | HsUnannMany - deriving (Eq, Ord, Data) - pattern HsUnrestrictedArrow :: XUnannotated on mult pass -> HsMultAnnOn on mult pass -pattern HsUnrestrictedArrow a = HsUnannotated HsUnannMany a - -data HsMultAnnOnWhat = OnArrow | OnRecField +pattern HsUnrestrictedArrow a = HsUnannotated a --- | Denotes the type of arrows in the surface language +-- HsMultAnnOn is used both to represent function arrows and multiplicity annotations +-- in the data declaration syntax. But the default multiplicity is different +-- between the two uses. In constructors, the default is One, but on arrows, the +-- default is Many. (But note that non-record GADT syntax follows the default of arrows.) +-- `HsMultAnnOnWhat` is used to distinguish between the two uses. +data HsMultAnnOnWhat = OnArrow | OnConField + +-- Get a value level representation of the `HsMultAnnOnWhat` kind. +class IsHsMultAnnOnWhat (on :: HsMultAnnOnWhat) where + hsMultAnnOnWhat :: proxy on -> HsMultAnnOnWhat +instance IsHsMultAnnOnWhat OnArrow where + hsMultAnnOnWhat _ = OnArrow +instance IsHsMultAnnOnWhat OnConField where + hsMultAnnOnWhat _ = OnConField + +-- | Denotes multiplicity annotations in the surface language data HsMultAnnOn (on :: HsMultAnnOnWhat) mult pass - = HsUnannotated HsUnannotatedMult !(XUnannotated on mult pass) - -- ^ a -> b or a → b + = HsUnannotated !(XUnannotated on mult pass) + -- ^ a -> b or a → b or { nm :: a } | HsLinearAnn !(XLinearAnn on mult pass) - -- ^ a %1 -> b or a %1 → b, or a ⊸ b + -- ^ a %1 -> b or a %1 → b, or a ⊸ b, or { nm %1 :: a } | HsExplicitMult !(XExplicitMult on mult pass) !mult - -- ^ a %m -> b or a %m → b (very much including `a %Many -> b`! + -- ^ a %m -> b or a %m → b or { nm %m :: a } + -- (very much including `a %Many -> b`! -- This is how the programmer wrote it). It is stored as an -- `HsType` so as to preserve the syntax as written in the -- program. @@ -952,12 +958,6 @@ type family XLinearAnn (on :: HsMultAnnOnWhat) mult p type family XExplicitMult (on :: HsMultAnnOnWhat) mult p type family XXMultAnnOn (on :: HsMultAnnOnWhat) mult p -hsMultIsLinear :: Bool -> HsMultAnnOn on mult pass -> Bool -hsMultIsLinear _ (HsUnannotated HsUnannOne _) = True -hsMultIsLinear linear (HsUnannotated HsUnannMany _) = not linear -hsMultIsLinear _ HsLinearAnn{} = True -hsMultIsLinear _ _ = False - {- Note [Unit tuples] ~~~~~~~~~~~~~~~~~~ @@ -1061,7 +1061,7 @@ data ConDeclField pass = ConDeclField { cd_fld_ext :: XConDeclField pass, cd_fld_names :: [LFieldOcc pass], -- ^ See Note [ConDeclField pass] - cd_fld_spec :: HsConFieldSpec OnRecField pass } + cd_fld_spec :: HsConFieldSpec OnConField pass } | XConDeclField !(XXConDeclField pass) {- Note [ConDeclField pass] ===================================== testsuite/tests/ghc-api/exactprint/Test20239.stderr ===================================== @@ -257,7 +257,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { Test20239.hs:7:62-63 }) (NormalSyntax))) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr ===================================== @@ -254,7 +254,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { T17544_kw.hs:19:21-22 }) (NormalSyntax))) ===================================== testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr ===================================== @@ -951,7 +951,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:28:15-16 }) (NormalSyntax))) @@ -1024,7 +1023,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:29:15-16 }) (NormalSyntax))) @@ -1184,7 +1182,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:33:10-11 }) (NormalSyntax))) @@ -1257,7 +1254,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:34:10-11 }) (NormalSyntax))) @@ -1429,7 +1425,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:40:8-9 }) (NormalSyntax))) @@ -1502,7 +1497,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (EpUniTok (EpaSpan { T24221.hs:42:8-9 }) (NormalSyntax))) ===================================== testsuite/tests/parser/should_compile/DumpParsedAst.stderr ===================================== @@ -254,7 +254,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:9:20-21 }) (NormalSyntax))) @@ -960,7 +959,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:14-15 }) (NormalSyntax))) @@ -993,7 +991,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:29-30 }) (NormalSyntax))) @@ -1020,7 +1017,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:17:20-21 }) (NormalSyntax))) @@ -1407,7 +1403,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:18:33-34 }) (NormalSyntax))) @@ -1540,7 +1535,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:21:22-23 }) (NormalSyntax))) @@ -1573,7 +1567,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:21:27-28 }) (NormalSyntax))) @@ -1699,7 +1692,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:30-31 }) (NormalSyntax))) @@ -1772,7 +1764,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:54-55 }) (NormalSyntax))) @@ -1799,7 +1790,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:22:45-46 }) (NormalSyntax))) @@ -1908,7 +1898,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:23:36-37 }) (NormalSyntax))) @@ -1980,7 +1969,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { DumpParsedAst.hs:23:27-28 }) (NormalSyntax))) ===================================== testsuite/tests/parser/should_compile/DumpRenamedAst.stderr ===================================== @@ -648,7 +648,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -757,7 +756,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -787,7 +785,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -906,7 +903,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -971,7 +967,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -994,7 +989,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1093,7 +1087,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1159,7 +1152,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1846,7 +1838,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1951,7 +1942,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -1981,7 +1971,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn @@ -2004,7 +1993,6 @@ (HsFunTy (NoExtField) (HsUnannotated - (HsUnannMany) (NoExtField)) (L (EpAnn ===================================== testsuite/tests/parser/should_compile/T14189.stderr ===================================== @@ -207,7 +207,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannOne) (NoExtField)) (L (EpAnn ===================================== testsuite/tests/printer/T18791.stderr ===================================== @@ -128,7 +128,6 @@ (NoSrcUnpack) (NoSrcStrict) (HsUnannotated - (HsUnannMany) (EpUniTok (EpaSpan { T18791.hs:5:14-15 }) (NormalSyntax))) ===================================== utils/check-exact/ExactPrint.hs ===================================== @@ -834,9 +834,9 @@ markEpUniToken (EpUniTok aa isUnicode) = do -- --------------------------------------------------------------------- markArrow :: (Monad m, Monoid w, ExactPrint a) => HsArrowOf a GhcPs -> EP w m (HsArrowOf a GhcPs) -markArrow (HsUnannotated t arr) = do +markArrow (HsUnannotated arr) = do arr' <- markEpUniToken arr - return (HsUnannotated t arr') + return (HsUnannotated arr') markArrow (HsLinearAnn (EpPct1 pct1 arr)) = do pct1' <- markEpToken pct1 arr' <- markEpUniToken arr @@ -850,11 +850,11 @@ markArrow (HsExplicitMult (pct, arr) t) = do arr' <- markEpUniToken arr return (HsExplicitMult (pct', arr') t') -markRecFieldMult :: (Monad m, Monoid w, ExactPrint a) => HsMultAnnOn OnRecField a GhcPs -> EP w m (HsMultAnnOn OnRecField a GhcPs) -markRecFieldMult (HsUnannotated t col) = do +markRecFieldMult :: (Monad m, Monoid w, ExactPrint a) => HsMultAnnOn OnConField a GhcPs -> EP w m (HsMultAnnOn OnConField a GhcPs) +markRecFieldMult (HsUnannotated col) = do traceM $ "markRecFieldMult:HsUnannotated" col' <- markEpUniToken col - return (HsUnannotated t col') + return (HsUnannotated col') markRecFieldMult (HsLinearAnn (pct1, col)) = do traceM $ "markRecFieldMult:HsLinearAnn" pct1' <- markEpToken pct1 @@ -4449,7 +4449,7 @@ instance ExactPrint (HsConFieldSpec OnArrow GhcPs) where arr' <- markArrow arr return (CFS an' unp str arr' t' doc) -instance ExactPrint (HsConFieldSpec OnRecField GhcPs) where +instance ExactPrint (HsConFieldSpec OnConField GhcPs) where getAnnotationEntry = const NoEntryVal setAnnotationAnchor a _ _ _ = a exact (CFS an unp str mult t doc) = do ===================================== utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs ===================================== @@ -1049,7 +1049,7 @@ ppSideBySideField subdocs unicode (ConDeclField _ names ltype) = -- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Bool -> HsConFieldSpec on DocNameI -> LaTeX -> LaTeX ppRecFieldMultAnn unicode (CFS _ _ _ arr _ _) following = case arr of - HsUnannotated _ _ -> following + HsUnannotated _ -> following HsLinearAnn _ -> text "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode <+> following @@ -1318,7 +1318,7 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u = where arr = case mult of HsLinearAnn _ -> lollipop u - HsUnannotated _ _ -> arrow u + HsUnannotated _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u <+> arrow u ppr_mono_ty (HsTyVar _ NotPromoted (L _ name)) _ = ppDocName name ppr_mono_ty (HsTyVar _ IsPromoted (L _ name)) _ = char '\'' <> ppDocName name ===================================== utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs ===================================== @@ -1480,6 +1480,7 @@ ppSideBySideConstr subdocs fixities unicode pkg qual (L _ con) = qual (map (ppSideBySideField subdocs unicode qual) (map unLoc fields)) + doConstrArgsWithDocs :: [HsConFieldSpec on DocNameI] -> Html doConstrArgsWithDocs args = subFields pkg qual $ case con of ConDeclH98{} -> [ (ppLParendType unicode qual HideEmptyContexts arg, mdoc, []) @@ -1557,7 +1558,7 @@ ppSideBySideField subdocs unicode qual (ConDeclField _ names ltype) = -- Where there is more than one name, they all have the same documentation ppRecFieldMultAnn :: Unicode -> Qualification -> HsConFieldSpec on DocNameI -> Html -> Html ppRecFieldMultAnn unicode qual (CFS _ _ _ arr _ _) following = case arr of - HsUnannotated _ _ -> following + HsUnannotated _ -> following HsLinearAnn _ -> toHtml "%1" <+> following HsExplicitMult _ mult -> multAnnotation <> ppr_mono_lty mult unicode qual HideEmptyContexts <+> following @@ -1821,7 +1822,7 @@ ppr_mono_ty (HsFunTy _ mult ty1 ty2) u q e = where arr = case mult of HsLinearAnn _ -> lollipop u - HsUnannotated _ _ -> arrow u + HsUnannotated _ -> arrow u HsExplicitMult _ m -> multAnnotation <> ppr_mono_lty m u q e <+> arrow u ppr_mono_ty (HsTupleTy _ con tys) u q _ = tupleParens con (map (ppLType u q HideEmptyContexts) tys) ===================================== utils/haddock/haddock-api/src/Haddock/Convert.hs ===================================== @@ -990,9 +990,9 @@ synifyMult vs t = case t of ManyTy -> HsUnrestrictedArrow noExtField ty -> HsExplicitMult noExtField (synifyType WithinType vs ty) -synifyMultRec :: [TyVar] -> Mult -> HsMultAnnOn OnRecField (LHsType GhcRn) GhcRn +synifyMultRec :: [TyVar] -> Mult -> HsMultAnnOn OnConField (LHsType GhcRn) GhcRn synifyMultRec vs t = case t of - OneTy -> HsUnannotated HsUnannOne noExtField + OneTy -> HsUnannotated noExtField ty -> HsExplicitMult noExtField (synifyType WithinType vs ty) synifyPatSynType :: PatSyn -> LHsType GhcRn ===================================== utils/haddock/haddock-api/src/Haddock/GhcUtils.hs ===================================== @@ -358,7 +358,7 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] PrefixCon{} -> Just d RecCon fields | all field_avail (unLoc fields) -> Just d - | otherwise -> Just (d{con_args = PrefixCon [] (field_types $ unLoc fields)}) + | otherwise -> Just (d{con_args = field_types (unLoc fields) (PrefixCon [])}) -- if we have *all* the field names available, then -- keep the record declaration. Otherwise degrade to -- a constructor declaration. This isn't quite right, but @@ -368,7 +368,7 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] PrefixConGADT{} -> Just d RecConGADT _ fields | all field_avail (unLoc fields) -> Just d - | otherwise -> Just (d{con_g_args = PrefixConGADT noExtField (field_types $ unLoc fields)}) + | otherwise -> Just (d{con_g_args = field_types (unLoc fields) (PrefixConGADT noExtField)}) where -- see above @@ -376,8 +376,8 @@ restrictCons names decls = [L p d | L p (Just d) <- fmap keep <$> decls] field_avail (L _ (ConDeclField _ fs _)) = all (\f -> (unLoc . foLabel . unLoc $ f) `elem` names) fs - field_types :: [LConDeclField GhcRn] -> [HsConFieldSpec OnArrow GhcRn] - field_types flds = [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t) <- flds] + field_types :: [LConDeclField GhcRn] -> ([HsConFieldSpec on GhcRn] -> r) -> r + field_types flds f = f [hsConFieldSpecGeneralize t | L _ (ConDeclField _ _ t) <- flds] keep _ = Nothing restrictDecls :: [Name] -> [LSig GhcRn] -> [LSig GhcRn] ===================================== utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs ===================================== @@ -341,7 +341,7 @@ renameMaybeInjectivityAnn renameMaybeInjectivityAnn = traverse renameInjectivityAnn renameMultAnnOn :: HsMultAnnOn on (LHsType GhcRn) GhcRn -> RnM (HsMultAnnOn on (LHsType DocNameI) DocNameI) -renameMultAnnOn (HsUnannotated mult _) = return (HsUnannotated mult noExtField) +renameMultAnnOn (HsUnannotated _) = return (HsUnannotated noExtField) renameMultAnnOn (HsLinearAnn _) = return (HsLinearAnn noExtField) renameMultAnnOn (HsExplicitMult _ p) = HsExplicitMult noExtField <$> renameLType p View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e6533dec8bebc63109379a1a742906668bd8271 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e6533dec8bebc63109379a1a742906668bd8271 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 16:47:11 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 11:47:11 -0500 Subject: [Git][ghc/ghc][wip/T18462] Unannotated multiplicity based on type Message-ID: <6792728f91dd5_3e7a8e156489c1136f4@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 00902cd8 by Sjoerd Visscher at 2025-01-23T17:47:00+01:00 Unannotated multiplicity based on type - - - - - 30 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - 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/parser/should_compile/DumpParsedAst.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/printer/T18791.stderr - utils/check-exact/ExactPrint.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00902cd80ae53793a1bf945f29cff154427e28c6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00902cd80ae53793a1bf945f29cff154427e28c6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 17:21:45 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 23 Jan 2025 12:21:45 -0500 Subject: [Git][ghc/ghc][wip/coreprep-sat-name] CorePrep: Name `sat` binders more descriptively Message-ID: <67927aa969433_23e3f3eced411014@gitlab.mail> Ben Gamari pushed to branch wip/coreprep-sat-name at Glasgow Haskell Compiler / GHC Commits: 5f2019ab by Ben Gamari at 2025-01-23T12:21:31-05:00 CorePrep: Name `sat` binders more descriptively - - - - - 1 changed file: - compiler/GHC/CoreToStg/Prep.hs Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -61,7 +61,8 @@ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Id.Make ( realWorldPrimId ) import GHC.Types.Basic -import GHC.Types.Name ( NamedThing(..), nameSrcSpan, isInternalName ) +import GHC.Types.Name ( NamedThing(..), nameSrcSpan, isInternalName, OccName ) +import GHC.Types.Name.Occurrence (occNameString) import GHC.Types.SrcLoc ( SrcSpan(..), realSrcLocSpan, mkRealSrcLoc ) import GHC.Types.Literal import GHC.Types.Tickish @@ -72,6 +73,7 @@ import qualified Data.ByteString.Builder as BB import Data.ByteString.Builder.Prim import Control.Monad +import Data.List (intercalate) {- Note [CorePrep Overview] @@ -249,11 +251,11 @@ corePrepPgm logger cp_cfg pgm_cfg withTiming logger (text "CorePrep"<+>brackets (ppr this_mod)) (\a -> a `seqList` ()) $ do - us <- mkSplitUniqSupply 's' let initialCorePrepEnv = mkInitialCorePrepEnv cp_cfg - let - implicit_binds = mkDataConWorkers + us <- mkSplitUniqSupply 's' + + let implicit_binds = mkDataConWorkers (cpPgm_generateDebugInfo pgm_cfg) mod_loc data_tycons -- NB: we must feed mkImplicitBinds through corePrep too @@ -713,13 +715,13 @@ cpePair :: TopLevelFlag -> RecFlag -> Demand -> Levity -> UniqSM (Floats, CpeRhs) -- Used for all bindings -- The binder is already cloned, hence an OutId -cpePair top_lvl is_rec dmd lev env bndr rhs +cpePair top_lvl is_rec dmd lev env0 bndr rhs = assert (not (isJoinId bndr)) $ -- those should use cpeJoinPair do { (floats1, rhs1) <- cpeRhsE env rhs -- See if we are allowed to float this stuff out of the RHS ; let dec = want_float_from_rhs floats1 rhs1 - ; (floats2, rhs2) <- executeFloatDecision dec floats1 rhs1 + ; (floats2, rhs2) <- executeFloatDecision env dec floats1 rhs1 -- Make the arity match up ; (floats3, rhs3) @@ -727,7 +729,7 @@ cpePair top_lvl is_rec dmd lev env bndr rhs then return (floats2, cpeEtaExpand arity rhs2) else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] - (do { v <- newVar (idType bndr) + (do { v <- newVar env (idType bndr) ; let (float, v') = mkNonRecFloat env Lifted v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v')) }) @@ -737,6 +739,8 @@ cpePair top_lvl is_rec dmd lev env bndr rhs ; return (floats4, rhs4) } where + env = pushBinderContext bndr env0 + arity = idArity bndr -- We must match this arity want_float_from_rhs floats rhs @@ -967,36 +971,36 @@ cpeBodyNF env expr cpeBody :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeBody) cpeBody env expr = do { (floats1, rhs) <- cpeRhsE env expr - ; (floats2, body) <- rhsToBody rhs + ; (floats2, body) <- rhsToBody env rhs ; return (floats1 `appFloats` floats2, body) } -------- -rhsToBody :: CpeRhs -> UniqSM (Floats, CpeBody) +rhsToBody :: CorePrepEnv -> CpeRhs -> UniqSM (Floats, CpeBody) -- Remove top level lambdas by let-binding -rhsToBody (Tick t expr) +rhsToBody env (Tick t expr) | tickishScoped t == NoScope -- only float out of non-scoped annotations - = do { (floats, expr') <- rhsToBody expr + = do { (floats, expr') <- rhsToBody env expr ; return (floats, mkTick t expr') } -rhsToBody (Cast e co) +rhsToBody env (Cast e co) -- You can get things like -- case e of { p -> coerce t (\s -> ...) } - = do { (floats, e') <- rhsToBody e + = do { (floats, e') <- rhsToBody env e ; return (floats, Cast e' co) } -rhsToBody expr@(Lam {}) -- See Note [No eta reduction needed in rhsToBody] +rhsToBody env expr@(Lam {}) -- See Note [No eta reduction needed in rhsToBody] | all isTyVar bndrs -- Type lambdas are ok = return (emptyFloats, expr) | otherwise -- Some value lambdas = do { let rhs = cpeEtaExpand (exprArity expr) expr - ; fn <- newVar (exprType rhs) + ; fn <- newVar env (exprType rhs) ; let float = Float (NonRec fn rhs) LetBound TopLvlFloatable ; return (unitFloat float, Var fn) } where (bndrs,_) = collectBinders expr -rhsToBody expr = return (emptyFloats, expr) +rhsToBody _env expr = return (emptyFloats, expr) {- Note [No eta reduction needed in rhsToBody] @@ -1168,7 +1172,7 @@ cpeApp top_env expr -- allocating CaseBound Floats for token and thing as needed = do { (floats1, token) <- cpeArg env topDmd token ; (floats2, thing) <- cpeBody env thing - ; case_bndr <- (`setIdUnfolding` evaldUnfolding) <$> newVar ty + ; case_bndr <- (`setIdUnfolding` evaldUnfolding) <$> newVar env ty ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] ; let float = mkCaseFloat case_bndr thing ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } @@ -1577,7 +1581,7 @@ cpeArg env dmd arg ; let arg_ty = exprType arg1 lev = typeLevity arg_ty dec = wantFloatLocal NonRecursive dmd lev floats1 arg1 - ; (floats2, arg2) <- executeFloatDecision dec floats1 arg1 + ; (floats2, arg2) <- executeFloatDecision env dec floats1 arg1 -- Else case: arg1 might have lambdas, and we can't -- put them inside a wrapBinds @@ -1586,7 +1590,7 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + else do { v <- (`setIdDemandInfo` dmd) <$> newVar env arg_ty -- See Note [Pin demand info on floats] ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 @@ -2424,13 +2428,13 @@ instance Outputable FloatDecision where ppr FloatNone = text "none" ppr FloatAll = text "all" -executeFloatDecision :: FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) -executeFloatDecision dec floats rhs +executeFloatDecision :: CorePrepEnv -> FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) +executeFloatDecision env dec floats rhs = case dec of FloatAll -> return (floats, rhs) FloatNone | isEmptyFloats floats -> return (emptyFloats, rhs) - | otherwise -> do { (floats', body) <- rhsToBody rhs + | otherwise -> do { (floats', body) <- rhsToBody env rhs ; return (emptyFloats, wrapBinds floats $ wrapBinds floats' body) } -- FloatNone case: `rhs` might have lambdas, and we can't @@ -2569,6 +2573,8 @@ data CorePrepEnv , cpe_subst :: Subst -- ^ See Note [CorePrepEnv: cpe_subst] , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] + + , cpe_context :: [OccName] -- ^ See Note [Binder context] } mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv @@ -2616,6 +2622,14 @@ cpSubstCo :: CorePrepEnv -> Coercion -> Coercion cpSubstCo (CPE { cpe_subst = subst }) co = substCo subst co -- substCo has a short-cut if the TCvSubst is empty +-- | See Note [Binder context] +pushBinderContext :: Id -> CorePrepEnv -> CorePrepEnv +pushBinderContext ident env + | lengthAtLeast (cpe_context env) 2 + = env + | otherwise + = env { cpe_context = getOccName ident : cpe_context env} + ------------------------------------------------------------------------------ -- Cloning binders -- --------------------------------------------------------------------------- @@ -2704,10 +2718,20 @@ fiddleCCall id -- Generating new binders -- --------------------------------------------------------------------------- -newVar :: Type -> UniqSM Id -newVar ty - = seqType ty `seq` mkSysLocalOrCoVarM (fsLit "sat") ManyTy ty - +newVar :: CorePrepEnv -> Type -> UniqSM Id +newVar env ty + -- See Note [Binder context] + = seqType ty `seq` mkSysLocalOrCoVarM (fsLit occ) ManyTy ty + where occ = intercalate "_" (map occNameString $ cpe_context env) ++ "_sat" + +{- Note [Binder context] + ~~~~~~~~~~~~~~~~~~~~~ + To ensure that the compiled program (specifically symbol names) + remains understandable to the user we maintain a context + of binders that we are current under. This allows us to give + identifiers conjured during CorePrep more contextually-meaningful + names. This is done in `newVar`. + -} ------------------------------------------------------------------------------ -- Floating ticks View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f2019ab399bafc44b23f343365be8aaaa047d67 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f2019ab399bafc44b23f343365be8aaaa047d67 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 17:22:29 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 23 Jan 2025 12:22:29 -0500 Subject: [Git][ghc/ghc][wip/coreprep-sat-name] CorePrep: Name `sat` binders more descriptively Message-ID: <67927ad54b0b9_23e3f4646141143a@gitlab.mail> Ben Gamari pushed to branch wip/coreprep-sat-name at Glasgow Haskell Compiler / GHC Commits: e1c1f0c0 by Ben Gamari at 2025-01-23T12:22:19-05:00 CorePrep: Name `sat` binders more descriptively - - - - - 1 changed file: - compiler/GHC/CoreToStg/Prep.hs Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -61,7 +61,8 @@ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Id.Make ( realWorldPrimId ) import GHC.Types.Basic -import GHC.Types.Name ( NamedThing(..), nameSrcSpan, isInternalName ) +import GHC.Types.Name ( NamedThing(..), nameSrcSpan, isInternalName, OccName ) +import GHC.Types.Name.Occurrence (occNameString) import GHC.Types.SrcLoc ( SrcSpan(..), realSrcLocSpan, mkRealSrcLoc ) import GHC.Types.Literal import GHC.Types.Tickish @@ -72,6 +73,7 @@ import qualified Data.ByteString.Builder as BB import Data.ByteString.Builder.Prim import Control.Monad +import Data.List (intercalate) {- Note [CorePrep Overview] @@ -249,11 +251,11 @@ corePrepPgm logger cp_cfg pgm_cfg withTiming logger (text "CorePrep"<+>brackets (ppr this_mod)) (\a -> a `seqList` ()) $ do - us <- mkSplitUniqSupply 's' let initialCorePrepEnv = mkInitialCorePrepEnv cp_cfg - let - implicit_binds = mkDataConWorkers + us <- mkSplitUniqSupply 's' + + let implicit_binds = mkDataConWorkers (cpPgm_generateDebugInfo pgm_cfg) mod_loc data_tycons -- NB: we must feed mkImplicitBinds through corePrep too @@ -713,13 +715,13 @@ cpePair :: TopLevelFlag -> RecFlag -> Demand -> Levity -> UniqSM (Floats, CpeRhs) -- Used for all bindings -- The binder is already cloned, hence an OutId -cpePair top_lvl is_rec dmd lev env bndr rhs +cpePair top_lvl is_rec dmd lev env0 bndr rhs = assert (not (isJoinId bndr)) $ -- those should use cpeJoinPair do { (floats1, rhs1) <- cpeRhsE env rhs -- See if we are allowed to float this stuff out of the RHS ; let dec = want_float_from_rhs floats1 rhs1 - ; (floats2, rhs2) <- executeFloatDecision dec floats1 rhs1 + ; (floats2, rhs2) <- executeFloatDecision env dec floats1 rhs1 -- Make the arity match up ; (floats3, rhs3) @@ -727,7 +729,7 @@ cpePair top_lvl is_rec dmd lev env bndr rhs then return (floats2, cpeEtaExpand arity rhs2) else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] - (do { v <- newVar (idType bndr) + (do { v <- newVar env (idType bndr) ; let (float, v') = mkNonRecFloat env Lifted v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v')) }) @@ -737,6 +739,8 @@ cpePair top_lvl is_rec dmd lev env bndr rhs ; return (floats4, rhs4) } where + env = pushBinderContext bndr env0 + arity = idArity bndr -- We must match this arity want_float_from_rhs floats rhs @@ -967,36 +971,36 @@ cpeBodyNF env expr cpeBody :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeBody) cpeBody env expr = do { (floats1, rhs) <- cpeRhsE env expr - ; (floats2, body) <- rhsToBody rhs + ; (floats2, body) <- rhsToBody env rhs ; return (floats1 `appFloats` floats2, body) } -------- -rhsToBody :: CpeRhs -> UniqSM (Floats, CpeBody) +rhsToBody :: CorePrepEnv -> CpeRhs -> UniqSM (Floats, CpeBody) -- Remove top level lambdas by let-binding -rhsToBody (Tick t expr) +rhsToBody env (Tick t expr) | tickishScoped t == NoScope -- only float out of non-scoped annotations - = do { (floats, expr') <- rhsToBody expr + = do { (floats, expr') <- rhsToBody env expr ; return (floats, mkTick t expr') } -rhsToBody (Cast e co) +rhsToBody env (Cast e co) -- You can get things like -- case e of { p -> coerce t (\s -> ...) } - = do { (floats, e') <- rhsToBody e + = do { (floats, e') <- rhsToBody env e ; return (floats, Cast e' co) } -rhsToBody expr@(Lam {}) -- See Note [No eta reduction needed in rhsToBody] +rhsToBody env expr@(Lam {}) -- See Note [No eta reduction needed in rhsToBody] | all isTyVar bndrs -- Type lambdas are ok = return (emptyFloats, expr) | otherwise -- Some value lambdas = do { let rhs = cpeEtaExpand (exprArity expr) expr - ; fn <- newVar (exprType rhs) + ; fn <- newVar env (exprType rhs) ; let float = Float (NonRec fn rhs) LetBound TopLvlFloatable ; return (unitFloat float, Var fn) } where (bndrs,_) = collectBinders expr -rhsToBody expr = return (emptyFloats, expr) +rhsToBody _env expr = return (emptyFloats, expr) {- Note [No eta reduction needed in rhsToBody] @@ -1168,7 +1172,7 @@ cpeApp top_env expr -- allocating CaseBound Floats for token and thing as needed = do { (floats1, token) <- cpeArg env topDmd token ; (floats2, thing) <- cpeBody env thing - ; case_bndr <- (`setIdUnfolding` evaldUnfolding) <$> newVar ty + ; case_bndr <- (`setIdUnfolding` evaldUnfolding) <$> newVar env ty ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] ; let float = mkCaseFloat case_bndr thing ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } @@ -1577,7 +1581,7 @@ cpeArg env dmd arg ; let arg_ty = exprType arg1 lev = typeLevity arg_ty dec = wantFloatLocal NonRecursive dmd lev floats1 arg1 - ; (floats2, arg2) <- executeFloatDecision dec floats1 arg1 + ; (floats2, arg2) <- executeFloatDecision env dec floats1 arg1 -- Else case: arg1 might have lambdas, and we can't -- put them inside a wrapBinds @@ -1586,7 +1590,7 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + else do { v <- (`setIdDemandInfo` dmd) <$> newVar env arg_ty -- See Note [Pin demand info on floats] ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 @@ -2424,13 +2428,13 @@ instance Outputable FloatDecision where ppr FloatNone = text "none" ppr FloatAll = text "all" -executeFloatDecision :: FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) -executeFloatDecision dec floats rhs +executeFloatDecision :: CorePrepEnv -> FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) +executeFloatDecision env dec floats rhs = case dec of FloatAll -> return (floats, rhs) FloatNone | isEmptyFloats floats -> return (emptyFloats, rhs) - | otherwise -> do { (floats', body) <- rhsToBody rhs + | otherwise -> do { (floats', body) <- rhsToBody env rhs ; return (emptyFloats, wrapBinds floats $ wrapBinds floats' body) } -- FloatNone case: `rhs` might have lambdas, and we can't @@ -2569,6 +2573,8 @@ data CorePrepEnv , cpe_subst :: Subst -- ^ See Note [CorePrepEnv: cpe_subst] , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] + + , cpe_context :: [OccName] -- ^ See Note [Binder context] } mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv @@ -2576,6 +2582,7 @@ mkInitialCorePrepEnv cfg = CPE { cpe_config = cfg , cpe_subst = emptySubst , cpe_rec_ids = emptyUnVarSet + , cpe_context = [] } extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv @@ -2616,6 +2623,14 @@ cpSubstCo :: CorePrepEnv -> Coercion -> Coercion cpSubstCo (CPE { cpe_subst = subst }) co = substCo subst co -- substCo has a short-cut if the TCvSubst is empty +-- | See Note [Binder context] +pushBinderContext :: Id -> CorePrepEnv -> CorePrepEnv +pushBinderContext ident env + | lengthAtLeast (cpe_context env) 2 + = env + | otherwise + = env { cpe_context = getOccName ident : cpe_context env} + ------------------------------------------------------------------------------ -- Cloning binders -- --------------------------------------------------------------------------- @@ -2704,10 +2719,20 @@ fiddleCCall id -- Generating new binders -- --------------------------------------------------------------------------- -newVar :: Type -> UniqSM Id -newVar ty - = seqType ty `seq` mkSysLocalOrCoVarM (fsLit "sat") ManyTy ty - +newVar :: CorePrepEnv -> Type -> UniqSM Id +newVar env ty + -- See Note [Binder context] + = seqType ty `seq` mkSysLocalOrCoVarM (fsLit occ) ManyTy ty + where occ = intercalate "_" (map occNameString $ cpe_context env) ++ "_sat" + +{- Note [Binder context] + ~~~~~~~~~~~~~~~~~~~~~ + To ensure that the compiled program (specifically symbol names) + remains understandable to the user we maintain a context + of binders that we are current under. This allows us to give + identifiers conjured during CorePrep more contextually-meaningful + names. This is done in `newVar`. + -} ------------------------------------------------------------------------------ -- Floating ticks View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1c1f0c04a885a372c927874d75f48ab1388f7c6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1c1f0c04a885a372c927874d75f48ab1388f7c6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 17:48:42 2025 From: gitlab at gitlab.haskell.org (Teo Camarasu (@teo)) Date: Thu, 23 Jan 2025 12:48:42 -0500 Subject: [Git][ghc/ghc][wip/T25262] 128 commits: Remove TcRnDeprecatedInvisTyArgInConPat mechanism Message-ID: <679280fa93ce5_3852f2e787c44237@gitlab.mail> Teo Camarasu pushed to branch wip/T25262 at Glasgow Haskell Compiler / GHC Commits: 5b4774f9 by sheaf at 2024-12-03T15:22:07+01:00 Remove TcRnDeprecatedInvisTyArgInConPat mechanism The combination of ScopedTypeVariables + TypeApplications now no longer enables the use of type applications in constructor patterns, as per GHC proposal #448. This completes the deprecation that begun with GHC 9.8. We also remove the -Wdeprecated-type-abstractions flag, which was introduced in GHC 9.10. - - - - - f813c8d7 by sheaf at 2024-12-03T17:10:15-05:00 Hadrian: use / when making filepaths absolute In Hadrian, we are careful to use -/- rather than </>, in order to use / instead of \ in filepaths. However, this gets ruined by the use of makeAbsolute from System.Directory, which, on Windows, changes back forward slashes to backslashes. - - - - - 292ed74e by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. - - - - - 20912f5b by Ben Gamari at 2024-12-03T17:10:52-05:00 rts/linker: Clarify debug output - - - - - f98b3ac0 by Simon Hengel at 2024-12-03T17:11:30-05:00 SysTools: Avoid race conditions when processing output (fixes #16450) - - - - - 03851b64 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 mg: Drop unnecessary HasCallStack This HasCallStack was a debugging artifact from a previous commit. - - - - - 01d213b5 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Improve haddock of graphReachabilityCyclic - - - - - f7cbffe2 by Rodrigo Mesquita at 2024-12-03T17:12:06-05:00 Refactor ModuleGraph interface The 'ModuleGraph' abstraction represents the relationship and strucutre of the modules being compiled. This structure is meant to be constructed once at the start of compilation, and never changed again. However, it's exposed interface was confusing and exposed too many footguns which led to inneficient usages of the ModuleGraph. This commit improves significantly the exported interface of ModuleGraph, taking into consideration the recent improvements around reachability queries. Since the ModuleGraph graphs and related structures (HPT, EPS) are performance critical in the sense that somewhat simple mistakes can cause bad leaks and non-linear memory usage, we want to have proper APIs that guide efficient usage. This is a good step in that direction. - - - - - b69a7f3c by David Binder at 2024-12-04T18:37:42-05:00 Use consistent capitalization for "GHC Proposal" in user guide - - - - - 18d9500d by David Binder at 2024-12-04T18:37:42-05:00 Fix reference to GHC proposal 193 in user guide - - - - - dd959406 by Ben Gamari at 2024-12-04T18:38:18-05:00 Revert "rts/Interpreter: Assert that TEST*_P discriminators are valid" This assertion was based on the misconception that `GET_TAG` was returning the pointer tag whereas it is actually returning the constructor tag. This reverts commit 9bf3663b9970851e7b5701d68147450272823197. Fixes #25527. - - - - - cad6fede by Ben Gamari at 2024-12-04T18:38:54-05:00 rts/IOManager: Drop dead code This assignment is dead code as it occurs after all branches have returned. Moreover, it can't possibly be relevant since the "available" branch already sets `flag`. Potentially fixes #25542. - - - - - 55d8304e by Ben Gamari at 2024-12-06T16:56:00-05:00 ghc-internal: Drop GHC.Internal.Data.Enum This module consists only of reexports and consequently there is no reason for it to exist. - - - - - 56b9f484 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Introduce Data.Bounded As proposed in [CLC#208] but unfortunately `Data.Enum` was already incorrectly introduced in the `ghc-internal` refactor. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - 336d392e by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Deprecate export of Bounded from Data.Enum This begins the process of bringing us into compliance with [CLC#208]. [CLC#208]: https://github.com/haskell/core-libraries-committee/issues/208 - - - - - dd7ca939 by Ben Gamari at 2024-12-06T16:56:00-05:00 base: Mention incorrect Data.Enum addition in changelog - - - - - dfd1db48 by Ben Gamari at 2024-12-06T16:56:36-05:00 base: Reintroduce {Show,Enum} IoSubSystem These instances were dropped in !9676 but not approved by the CLC. Addresses #25549. - - - - - 090fc7c1 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements on T25240 T25240 doesn't need RTS linker, GHCi is sufficient and GHCi can also be dynamically linked. - - - - - 3fb5d399 by Peter Trommler at 2024-12-07T03:41:21-05:00 Fix requirements for T25155 Loading C objects requires RTS linker. - - - - - 4c58bdf6 by Leary at 2024-12-07T03:42:07-05:00 TH: Add typed variants of dataToExpQ and liftData This commit introduces to template-haskell (via ghc-internal) two functions `dataToCodeQ` and `liftDataTyped`, typed variants of `dataToExpQ` and `liftData` respectively. Tested in: `dataToCodeQUnit`. - - - - - 63027593 by Serge S. Gulin at 2024-12-08T13:52:05+03:00 JS: Basic cleanup for unused stuff to simplify things. 1. Make `staticInitStat`, `staticDeclStat`, `allocUnboxedConStatic`, `allocateStaticList`, `jsStaticArg` local to modules. 2. Remove unused `hdRawStr`, `hdStrStr` from Haskell and JavaScript (`h$pstr`, `h$rstr`, `h$str`). 3. Introduce a special type `StaticAppKind` enumeration and `StaticApp` to represent boxed scalar static applications. Originally, StaticThunk supported to pass Maybe when it became Nothing for initializied thunks in an alternatie way but it is not used anymore. - - - - - a9f8f1fb by Serge S. Gulin at 2024-12-08T14:10:45+03:00 JS: Add trivial optimizations for `unpackCString` and `unpackCStringUtf8`. It became possible due of introduction strings unfloating at Sinker pass (#13185). Earns few more bytes at optimizations. - - - - - b519c06b by Serge S. Gulin at 2024-12-08T15:50:26+03:00 JS: Specialize unpackCString# CAFs (fixes #24744) Code analysis shown that such optimization would be possible out of the box if `cachedIdentForId` allowed to do that for Haskell `Id`s which are represented by few JavaScript `Ident`s. It is a usual for strings which are represented at JavaScript as a pair of 2 values: the string content and the offset where to start reading actual string from the full content. Usually offset is 0 but technically we need to allow such complex structures to be treated as "global". Enabling it there shown that `genToplevelRhs` and `globalOccs` had inaccuracies in their implementations: 1. `globalOccs` operated over JavaScript's `Ident`s but for complex structures it didn't pay attention to the fact that different Idents actually could be pointed to same Id. Now the algo is changed to calculate occurencies for Ids. 2. `genToplevelRhs` didn't assume that different Idents pointed to same Id can have mixed order of occurence. But actually the order is important. Strings are encoded into 2 variables where first is content and second is offset and their order are not interchangeable. It is fixed by regeneration Idents from collected Ids which is fine because all Idents generation is passed through the Cache and they are quasi-stable. - - - - - a8ceccf3 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Fix panic in multiline string with unterminated gap (#25530) - - - - - 9e464ad0 by Brandon Chinn at 2024-12-09T16:25:43-05:00 Add test case for unterminated multiline string - - - - - ed1ed5c6 by Rodrigo Mesquita at 2024-12-09T16:26:19-05:00 Revert mapMG renaming We had previously renamed this function for consistency, but that caused unnecessary breakage - - - - - 158261f7 by Sylvain Henry at 2024-12-09T16:27:01-05:00 RTS: make Cabal flags manual Cabal shouldn't automatically try to set them. We set them explicitly. - - - - - a83b7ed6 by Matthew Stephenson at 2024-12-10T14:01:22-05:00 Add missing @since documentation for (!?) function - - - - - e745e3a3 by Ben Gamari at 2024-12-10T14:01:59-05:00 compiler: Don't attempt to TSAN-instrument SIMD operations TSAN only provides instrumentation for 8, 16, 32, and 64-bit memory loads/stores. Don't attempt to instrument wider operations. Fixes #25563. - - - - - 684c0018 by Ben Gamari at 2024-12-10T14:02:35-05:00 gitlab/ci: Don't clobber RUNTEST_ARGS Previously the logic handling `IGNORE_PERF_FAILURES` clobbered the user's `RUNTEST_ARGS`. Fix this. - - - - - 41dae5b8 by Ben Gamari at 2024-12-10T14:03:11-05:00 hadrian: Mitigate mktexfmt race At least some versions of Texlive's `mktexfmt` utility cannot be invoked concurrently in their initial run since they fail to handle failure of `mkdir` due to racing. Specifically, we see ``` | Run Xelatex: users_guide.tex => /tmp/extra-dir-9616886274866 | Run Xelatex: Haddock.tex => /tmp/extra-dir-9616886274869 This is XeTeX, Version 3.14159265-2.6-0.999992 (TeX Live 2020) (preloaded format=xelatex) restricted \write18 enabled. kpathsea: Running mktexfmt xelatex.fmt mktexfmt: mktexfmt is using the following fmtutil.cnf files (in precedence order): mktexfmt: /usr/share/texlive/texmf-dist/web2c/fmtutil.cnf mktexfmt: mktexfmt is using the following fmtutil.cnf file for writing changes: mktexfmt: /builds/ghc/ghc/tmp-home/.texlive2020/texmf-config/web2c/fmtutil.cnf /usr/bin/mktexfmt: mkdir(/builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c/) failed for tree /builds/ghc/ghc/tmp-home/.texlive2020/texmf-var/web2c: File exists at /usr/share/texlive/tlpkg/TeXLive/TLUtils.pm line 937. I can't find the format file `xelatex.fmt'! ``` That is two `mktexfmt` invocations (for the user's guide and haddock builds) attempted to create `$HOME/texlive2020/texmf-var/web2c` and raced. One of the two `mkdir`'s consequently failed, bringing down the entire build. We avoid this by ensuring that the first `xelatex` invocation is always performed serially. Fixes #25564. - - - - - 9efbc51f by Ben Gamari at 2024-12-10T14:03:48-05:00 rts/CheckUnload: Reset old_objects if unload is skipped Previously `checkUnload` failed to reset `old_objects` when it decided not to unload (e.g. due to heap profiling being enabled). Fixes #24935. - - - - - 5192a75f by Ben Gamari at 2024-12-11T04:28:11-05:00 rts: Annotate BCOs with their Name This introduces a new bytecode instruction, `BCO_NAME`, to aid in debugging bytecode execution. This instruction is injected by `mkProtoBCO` and captures the Haskell name of the BCO. It is then printed by the disassembler, allowing ready correlation with STG dumps. - - - - - 99225996 by Ben Gamari at 2024-12-11T04:28:48-05:00 configure: Implement ld override whitelist Bring `configure` into alignment with `ghc-toolchain`, ensuring that the ld-override logic will only take effect on Linux and Windows. Fixes #25501. - - - - - 4a8fc928 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Unmark T14028 as broken on FreeBSD This now appears to pass on FreeBSD 14. Closes #19723. - - - - - d7c0eb5a by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Migrate FreeBSD runner tag to FreeBSD 14 - - - - - 7246dacc by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Reintroduce FreeBSD 14 job - - - - - 4af936da by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Allow use of newer cabal-install bindists Newer cabal-install bindists have internal directory structure. Here we detect and account for the presence of such structure. - - - - - cbf38c1b by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Enable documentation build on FreeBSD 14 - - - - - d68107fb by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Use system libffi on FreeBSD - - - - - fea3b590 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark linker_unload as broken on FreeeBSD Due to #25491. - - - - - ccf171ee by Ben Gamari at 2024-12-11T12:33:42+00:00 gitlab-ci: Prefer system toolchain on FreeBSD It's not uncommon to find machines with gcc installed via ports. We should be using the system's default clang-based toolchain instead. - - - - - cfb34738 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T21969 as broken on FreeBSD Due to #25512. - - - - - 0b64e37c by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark RestartEventLogging as broken on FreeBSD I am seeing this fail quite reproducibly. Due to #19724. - - - - - 3b412019 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Mark T16180 as "broken" on FreeBSD Sadly we in fact need to skip it as it merely times out during compilation. See #14012. - - - - - 57e3cab5 by Ben Gamari at 2024-12-11T12:33:42+00:00 testsuite: Skip T16992 unless in slow speed This test has extraordinary memory requirements and tests a rather niche aspect of the compact region mechanism. It has been suggested multiple times that we shouldn't run it in the default testsuite configuration. Finally implement this. See #21890. See #21892. - - - - - f08a72eb by Ben Gamari at 2024-12-11T19:30:54-05:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. - - - - - e10d31ad by Ben Gamari at 2024-12-11T19:30:55-05:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. - - - - - 06265655 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Mention maximum capability count in users guide Addresses #25560. - - - - - d488470b by Ben Gamari at 2024-12-11T19:30:55-05:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. - - - - - 71f050b7 by Ben Gamari at 2024-12-11T19:30:55-05:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. - - - - - 1e84b411 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. - - - - - 683115a4 by Ben Gamari at 2024-12-11T19:30:55-05:00 testsuite: Add test for #25560 - - - - - ef2052a8 by Ben Gamari at 2024-12-12T04:42:32-05:00 testsuite: Only run T14497_compact in normal way This test targets the compacting GC so it makes little sense to run it across all ways. Moreover, it outright conflicts with the `nonmoving` way. - - - - - 34d3e8e6 by Ben Gamari at 2024-12-12T04:43:08-05:00 rts/CheckUnload: Don't prepare to unload if we can't unload Previously `prepareUnloadCheck` would move the `objects` list to `old_objects` even when profiling (where we cannot unload). This caused us to vacate the `objects` list during major GCs, losing track of loaded objects. Fix this by ensuring that `prepareUnloadCheck` and `checkUnload` both use the same short-cutting logic. - - - - - 9c53489d by Andrei Borzenkov at 2024-12-12T15:06:42-05:00 Update GHCi :info type declaration printing (#24459) - Do not print result's kind in type families because we have full kind in SAKS and we display invisible arity using @-binders - Do not suppress significant invisible binders An invisible binder is considered significant when it meets at least one of the following two criteria: - It visibly occurs in the declaration's body - It is followed by a significant binder, so it affects positioning For non-generative type declarations (type synonyms and type families) there is one additional criterion: - It is not followed by a visible binder, so it affects the arity of a type synonym See Note [Print invisible binders in interface declarations] for more information about what is "visibly occurs" - - - - - 13fe48d4 by Matthew Pickering at 2024-12-12T15:07:19-05:00 typechecker: Perform type family consistency checks in topological order Consider a module M importing modules A, B and C. We can waste a lot of work depending on the order that the modules are checked for family consistency. Consider that C imports A and B. When compiling C we must have already checked A and B for consistency, therefore if C is processed first then A and B will not need to be checked for consistency again. If A and B are compared first, then the consistency checks will be performed against (wasted as we already performed them for C). At the moment the order which modules are checked is non-deterministic. Clearly we should engineer that C is checked before B and A, but by what scheme? A simple one is to observe that if a module M is in the transitive closure of X then the size of the consistent family set of M is less than or equal to size of the consistent family set of X. Therefore by sorting the imports by the size of the consistent family set and processing the largest first, you make sure to process modules in topological order. In practice we have observed that this strategy has reduced the amount of consistency checks performed. One solution to #25554 - - - - - 62a2b25f by Sylvain Henry at 2024-12-14T04:31:09-05:00 TNTC: set CmmProc entry_label properly (#25565) Before this patch we were renaming the entry label of a CmmProc late in the CmmToAsm pass. It led to inconsistencies and to some labels being used in info tables but not being emitted (#25565). Now we set the CmmProc entry label earlier in the StgToCmm monad and we don't renamed it afterwards. - - - - - b339e7c3 by Simon Hengel at 2024-12-14T04:31:47-05:00 Make filter functionality for system tools line-based This is more efficient as: - All existing filter functions were line-based anyway. They broke up the input into lines and then joined it back together. - We already break up the output from system tools into lines when processing it. Splitting up the output of system tools once and then filtering and processing it reduces both code and runtime complexity. - - - - - 39669077 by Simon Hengel at 2024-12-14T04:31:47-05:00 Refactoring: Don't use a `Chan` when parsing SysTools output - - - - - 64756530 by Simon Peyton Jones at 2024-12-14T22:28:04-05:00 Tidy up the handling of `assert` Fixes #25493 - - - - - 8658fbc1 by Rodrigo Mesquita at 2024-12-14T22:28:41-05:00 base: displayException for SomeAsyncException Provide a better implementation of `SomeException` for `SomeAsyncException`. The previous, implicit, implementation, would not use the `displayException` of the exception wrapped by `SomeAsyncException`. Implements CLC-Proposal#309 Closes #25513 - - - - - 2d3a0a70 by ARATA Mizuki at 2024-12-15T18:35:30-05:00 LLVM: When emitting a vector literal with ppTypeLit, include the type information Fixes #25561 - - - - - bfacc086 by Simon Peyton Jones at 2024-12-15T18:36:05-05:00 Fix signature lookup in instance declarations This fixes a bug introduced by the fix to #16610 - - - - - 80f0e02d by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Improve GHC build times Two small changes * In GHC.Data.Unboxed, never omit interface pragmas. In "fast builds" one might omit them generally, but doing so gives very bad performance for code that imports this module. * In GHC.Hs.Dump don't do type-class specialisation. For some reason it goes mad and generates vast amounts of useless code. See #25463. - - - - - 175a1355 by Simon Peyton Jones at 2024-12-16T17:13:52+00:00 Refactor Lint Refactor Lint for two reasons: * To improve performance * To prepare for type-lets The big changes are all in GHC.Core.Lint: * Change the main APIs: * `lintType` returns nothing rather than returning a `LintedType`; * `lintCoercion` return nothing rather than returning a `LintedCoercion` Reason: these functions did a lot of allocation to return a substituted type/coercion that was often discarded, or used only to extract its kind. Instead we now return nothing, and, when needed, extract the kind and substitute. * Applications are treated as a whole, by `lintApp`. By treating multiple arguments all at once we avoid performing multiple substitutions, each substituting a single type variable. This can make an absolutely huge difference. Overall this led to a pretty massive rewrite of Lint, with many smaller changes. Smaller chnages elsewhere * Rename `GHC.Core.TyCo.Subst.getSubstInScope` to `substInScopeSet` for consistency * Define and use `GHC.Core.Type.liftedTypeOrConstraintKind` Performance. This MR someimtes gives gives a very large improvement in compile time, when Lint is on. here is a selection of changes over 5% in perf/compiler (with -dcore-lint) T25196 -97.0% T14766 -89.7% T14683 -74.4% T5631 -60.9% T20261 -56.7% T18923 -17.6% T13035 -15.8% T6048 -15.8% CoOpt_Read -14.4% T9630 -10.9% T5642 -7.3% Eliminating the egregious offenders is a big win. However, in some cases the compiler allocation /increases/. Here ae the changes over 1%: T9961 1.5% T8095 2.8% T14052 3.9% T12545 4.5% T14052Type 5.5% T5030 8.0% T5321Fun 8.3% T3064 12.7% CoOpt_Singletons 15.6% T9198 16.0% LargeRecord 18.1% I looked at the two biggest increases in compile-time bytes allocated. Interestingly, they both show substantial *decreases* in actual compile time, due to much smaller GC times. I'm honestly not sure either why the allocation increases, or why the GC time decreases; but I'm going to take the win! T9198 Baseline With patch No Lint Alloc 44.6M 44.6M Mut time 0.23s 0.22s GC time 0.21s 0.21s With Lint Alloc 309M 360M Mut time 1.51s 0.85s GC time 2.97s 0.25s ------------------- LargeRecord Baseline With patch No Lint Alloc 1.37G 1.37G Mut time 2.33s 2.33s GC time 2.40s 2.42s With Lint Alloc 3.4G 4.0G Mut time 6.02s 5.68s GC time 3.67s 3.03s IMPORTANT NOTE: These changes don't show up in CI because in CI the tests in perf/compiler are all run with -dcore-lint switched off. I gathered this data with some manual runs. - - - - - 8ef2dad6 by Simon Peyton Jones at 2024-12-17T02:48:09-05:00 Add Note [Typechecking overloaded literals] See #25494. - - - - - e86b1b20 by Ben Gamari at 2024-12-17T13:51:39-05:00 testsuite: Use math.inf instead of division-by-zero This both more directly captures the intent and also fixes #25580. - - - - - 430d965a by Ben Gamari at 2024-12-17T13:52:15-05:00 rts: Fix incorrect format specifiers in era profiling Fixes #25581. - - - - - 267098ad by Andreas Klebinger at 2024-12-18T23:43:13-05:00 Document `-prof` and non `-prof` code being incompatible. Fixes #25518. - - - - - 04433916 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - 7c78804e by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - 1d72cfb2 by Zubin Duggal at 2024-12-18T23:43:50-05:00 ghcup metadata: still use centos for redhat <9 - - - - - 3f7ebc58 by Sylvain Henry at 2024-12-19T20:40:14-05:00 Merge ghc-bignum into ghc-internal (#24453) First step towards merging ghc-bignum and ghc-prim into ghc-internal. After this patch, ghc-bignum is deprecated and is just a shallow package reexporting modules from ghc-internal and base. Use those directly instead. Move `gmp` submodule into ghc-internal directory. - - - - - ee0150c2 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Improve performance of deriving Show Significantly improves performance of deriving Show instances by avoiding using the very polymorphic `.` operator in favour of inlining its definition. We were generating tons of applications of it, each which had 3 type arguments! Improves on #9557 ------------------------- Metric Decrease: InstanceMatching T12707 T3294 ------------------------ - - - - - 8b266671 by Rodrigo Mesquita at 2024-12-19T20:40:51-05:00 Don't eta expand cons when deriving Data This eta expansion was introduced with the initial commit for Linear types. I believe this isn't needed any longer. My guess is it is an artifact from the initial linear types implementation: data constructors are linear, but they shouldn't need to be eta expanded to be used as higher order functions. I suppose in the early days this wasn't true. For instance, this works now: data T x = T x f = \(x :: forall y. y -> T y) -> x True f T -- ok! T is linear, but can be passed where an unrestricted higher order function is expected. I recall there being some magic around to make this work for data constructors... Since this works, there's no need to eta_expand the data constructors in the derived Data instances. - - - - - 1f67ad21 by Andrei Borzenkov at 2024-12-25T01:42:31-05:00 Flip the order of arguments of setField (#24668) GHC Proposal 583 "HasField redesign" specifies the following order of a setField function arguments as this: setField :: forall fld a b. SetField fld a b. b -> a -> a This patch flips the application order to match the spec. - - - - - 3e0c948d by Ben Gamari at 2024-12-25T01:43:08-05:00 rel-eng/upload: Add set_symlink mode This slightly eases updating of the `latest` symlinks. - - - - - 63d63f9d by Simon Peyton Jones at 2024-12-25T01:43:45-05:00 Preserve orientation when unifying kinds This MR fixes yet another manifestation of the trickiness caused by Note [Fundeps with instances, and equality orientation]. I wish there was a more robust way to do this, but this fix is a definite improvement. Fixes #25597 - - - - - 94ba9a6a by ARATA Mizuki at 2024-12-26T10:47:57-05:00 x86 NCG SIMD: Support pack/insert/broadcast/unpack of 128-bit integer vectors - - - - - 6bf0d587 by Andrew Lelechenko at 2024-12-26T10:48:33-05:00 docs: fix haddock formatting in Control.Monad.Fix - - - - - feb14af1 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Remove unnecessary irrefutable patterns from NonEmpty functions Implementation of https://github.com/haskell/core-libraries-committee/issues/107 - - - - - 6a0d91b4 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Make cons, Semigroup, IsList, and Monad instances stricter - - - - - 1249e597 by Sergey Vinokurov at 2024-12-27T15:06:28+00:00 Restore some laziness in <| and Semigroup instance, improve Monad instance The Monad instance shouldn't produce the outer :| unless f a reduces to WHNF. (Notice that the b :| bs match is implicitly lazy.) - - - - - 8699d826 by Sergey Vinokurov at 2024-12-27T15:12:30+00:00 Add comment outlining Data.List.NonEmpty implementation guiding principles - - - - - 7febe00e by Sergey Vinokurov at 2024-12-27T22:24:43+00:00 Fix tests since location of ‘>>=’ changed - - - - - a928c326 by ARATA Mizuki at 2024-12-28T03:06:14-05:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 - - - - - 7f79257a by Zubin Duggal at 2024-12-29T13:04:35+00:00 Bump base, ghc-prim and template-haskell versions for 9.12 Also bump various submodules. (cherry picked from commit 6fc1fa3bdc8f53acdb19e47145789274060e498f) Bump base bound to 4.21 for GHC 9.12 (cherry picked from commit 473a201c6b55aea5bf9c9db0836a66ea1b657e04) Bump binary submodule to 0.8.9.2 (cherry picked from commit 7199869a52ab45e8856658248bf807954d58cc20) (cherry picked from commit ec2f40b45c1a3d82d17a2fc07e9ddb9218bc3940) Bump exceptions submodule to 0.10.9 (cherry picked from commit f5b5d1dc2d326368e5b173d622630d77f019b629) Bump file-io submodule to 0.1.4 (cherry picked from commit ba786681de6ac5fa49938e2cd71a5988f0f40d1f) bump os-string submodule to 2.0.6 (cherry picked from commit 3a7ffdbb832c045a55fd1ef24f546abdd9d9e30f) bump transformers submodule to 0.6.1.2 (cherry picked from commit 53b46fd437421b9e5a001edc6d1c427439d7714f) Bump directory submodule to v1.3.9.0 (cherry picked from commit 27dc2664c5404bb462092bb216c2c37b418fd1f8) Bump Win32 submodule to v2.14.1.0 (cherry picked from commit 80df88086180f5e39212b2feacf70a9d2b263c6c) Bump filepath submodule to 1.5.3.0 (cherry picked from commit 29bfae2c58a7303a081a6e7956b9f55e5faf3eeb) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 97b0dff223a6c4cc003adec448104c277f214645) Bump unix submodule to 2.8.6.0 (cherry picked from commit a1f56d6d6a99c100f88ef0a8b4d51298cf24a42d) Bump os-string submodule to 2.0.8 (cherry picked from commit 0121b76fd52ea0c0ce5d07085bc195666b63c625) Bump file-io submodule to avoid usage of QuasiQuotes (cherry picked from commit 962ceb50c8a6fc370e1c0a267f5cd5562a8cf759) Bump filepath submodule to 1.5.4.0 (cherry picked from commit 7bc6877fd5d41c6d5900678ad5e73ed30f366569) Bump file-io submodule to 0.1.5 (cherry picked from commit 9478b5aefe2877d58baf527edcf936dddbb955b7) Bump Cabal submodule to 3.14.1.0 (cherry picked from commit 5c9c3e3f79a79bb6d9a77a17c716dc3a0bcbd2aa) Bump directory submodule to 0.12.2.0 (cherry picked from commit 897906265db37af34ae2aaa016cec417f263407b) Bump array submodule for base bump Bump stm submodule for base bump Bump process submodule for base bump - - - - - f6079408 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix ghc-e005 after HasCallstack changes (cherry picked from commit 77f340a24561cea8a6f2ada296b3ea356ab1823c) - - - - - 3e10fa75 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Add haskeline to stage0Packages Otherwise we link against boot inplace and boot unix as boot haskeline depends on boot unix. (cherry picked from commit 90b493769ebdf3cd7be404d18462dc20ac1044df) - - - - - 4ad6aec4 by Zubin Duggal at 2024-12-29T13:04:35+00:00 Fix TH changelog - - - - - ea3f7fd5 by Zubin Duggal at 2024-12-29T13:04:35+00:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - fafb70db by Zubin Duggal at 2024-12-29T13:04:35+00:00 hadrian-multi: warn on unused imports os-string has redundant imports (cherry picked from commit dde3796be689ea57543936e22aa5ea4ef7ed995e) - - - - - c02b1e46 by Simon Peyton Jones at 2024-12-29T17:04:30-05:00 Fix in-scope set for CSE Ticket #25468 showed an assertion failure in CSE because a top-level Id was being used before it was defined. Reason: Note [Glomming] in GHC.Core.Opt.OccurAnal. Solution (used in many places): just put all the top-level bindings in scope at the beginning of CSE. Compile-time allocation wobbles up and down a tiny bit; geo mean is zero. But MultiLayerModulesTH_OneShot and hard_hole_fits increase (on some architectures only) by a bit oever 2% . I think these are just a random fluctuations. Metric Increase: MultiLayerModulesTH_OneShot hard_hole_fits - - - - - 559d4f84 by Krzysztof Gogolewski at 2024-12-30T11:53:19-05:00 Add tests for #23883 The issue has been fixed by commit f5d3e03c56ffc63. Only T23883a is the actual regression test, the remaining ones are tricky cases found during development of an independent fix !11313. - - - - - 278a53ee by Sergey Vinokurov at 2024-12-30T11:53:59-05:00 Update changelog for CLC proposal #107 (NonEmpty laziness) - - - - - f56558be by Matthew Pickering at 2025-01-07T13:53:03-05:00 warnings: Find out if a qualified name is in the interactive scope directly There were two ad-hoc mechanisms used to determine which modules were in the interactive scope. 1. Look at everything in the GRE, to see what is imported qualified. 2. Look at the last loaded module in the HPT. (1) Is very inefficient, GlobalRdrEnvs can be very big. (2) is incorrect, there is no reason to assume the "last" thing added to the HPT has any relevance to module loading order. Happily, the same checks can be implemented directly by looking at the interactive imports from the interactive context. This mirrors what happens for normal imports. Arguably, the error reporting code shouldn't be doing this kind of processing and it should be an option is set when rendering the error message. However, this just improves the situation and doesn't block progress on that front in future. See #14225 and #15611 Fixes #25600 - - - - - 84155cdb by Simon Peyton Jones at 2025-01-07T13:53:40-05:00 Tidy up kcConDecls Addresses #25630 In particular, * Introduce ConArgKind and use it. * Make kcConDecls and tcConDecls work the same way concerning the kind of argument types - - - - - 6c12b6cf by Bryan Richter at 2025-01-07T18:15:02-05:00 Remove tmp files after toolchain check Fixes #25620 - - - - - 42826a89 by Cheng Shao at 2025-01-07T18:15:39-05:00 xxhash: bump to v0.8.3 - - - - - 185f17e4 by sheaf at 2025-01-07T18:16:15-05:00 Fix typo in GHC.Tc.Solver.Solve.runTcPluginsWanted - - - - - 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - a707e521 by Teo Camarasu at 2025-01-23T17:36:52+00:00 Add template-haskell-lift and template-haskell-quasiquoter - - - - - 591e2c7e by Teo Camarasu at 2025-01-23T17:48:23+00:00 Use th-lift and th-quasiquoter in boot libs - - - - - 24 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .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 - .gitlab/rel_eng/upload.sh - .gitmodules - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5caf1dd6af76fb9b99a15c873cc9df88408060a1...591e2c7e4c3041f7bd818e9843135be4ee9023b9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5caf1dd6af76fb9b99a15c873cc9df88408060a1...591e2c7e4c3041f7bd818e9843135be4ee9023b9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 18:03:22 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 23 Jan 2025 13:03:22 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/backports-9.12 Message-ID: <6792846a87e8e_3852f2e787c499e4@gitlab.mail> Ben Gamari deleted branch wip/backports-9.12 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 18:03:26 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 23 Jan 2025 13:03:26 -0500 Subject: [Git][ghc/ghc][ghc-9.12] 3 commits: Cmm/Parser: Add surface syntax for Mul2 MachOps Message-ID: <6792846eb66b9_3852f64462850169@gitlab.mail> Ben Gamari pushed to branch ghc-9.12 at Glasgow Haskell Compiler / GHC Commits: f6aa9f65 by Ben Gamari at 2025-01-22T13:17:55-05:00 Cmm/Parser: Add surface syntax for Mul2 MachOps These are otherwise very hard to test in isolation. - - - - - 33a74ef5 by Ben Gamari at 2025-01-22T15:02:48-05:00 Add release notes for 9.12.2 - - - - - a6f47532 by Ben Gamari at 2025-01-22T15:02:59-05:00 configure: Set RELEASE=NO - - - - - 4 changed files: - compiler/GHC/Cmm/Parser.y - configure.ac - + docs/users_guide/9.12.2-notes.rst - docs/users_guide/release-notes.rst Changes: ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1194,6 +1194,8 @@ callishMachOps platform = listToUFM $ , allWidths "fetch_nand" (\w -> MO_AtomicRMW w AMO_Nand) , allWidths "fetch_or" (\w -> MO_AtomicRMW w AMO_Or) , allWidths "fetch_xor" (\w -> MO_AtomicRMW w AMO_Xor) + , allWidths "mul2_" (\w -> MO_S_Mul2 w) + , allWidths "mul2u_" (\w -> MO_U_Mul2 w) ] where allWidths ===================================== configure.ac ===================================== @@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.12.1], [glasgow-ha AC_CONFIG_MACRO_DIRS([m4]) # Set this to YES for a released version, otherwise NO -: ${RELEASE=YES} +: ${RELEASE=NO} # The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line # above. If this is not a released version, then we will append the ===================================== docs/users_guide/9.12.2-notes.rst ===================================== @@ -0,0 +1,67 @@ +.. _release-9-12-2: + +Version 9.12.2 +============== + +The significant changes to the various parts of the compiler are listed in the +following sections. See the `migration guide +`_ on the GHC Wiki +for specific guidance on migrating programs to this release. + +Compiler +~~~~~~~~ + +- Fixed miscompilation of certain division operations (:ghc-ticket:`25653`) + +Included libraries +~~~~~~~~~~~~~~~~~~ + +The package database provided with this distribution also contains a number of +packages other than GHC itself. See the changelogs provided with these packages +for further change information. + +.. ghc-package-list:: + + compiler/ghc.cabal: The compiler itself + libraries/array/array.cabal: Dependency of ``ghc`` library + libraries/base/base.cabal: Core library + libraries/binary/binary.cabal: Dependency of ``ghc`` library + libraries/bytestring/bytestring.cabal: Dependency of ``ghc`` library + libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility + libraries/Cabal/Cabal-syntax/Cabal-syntax.cabal: Dependency of ``ghc-pkg`` utility + libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library + libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library + libraries/directory/directory.cabal: Dependency of ``ghc`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library + libraries/file-io/file-io.cabal: Dependency of ``directory`` library + libraries/filepath/filepath.cabal: Dependency of ``ghc`` library + libraries/ghc-boot/ghc-boot.cabal: Internal compiler library + libraries/ghc-boot-th/ghc-boot-th.cabal: Internal compiler library + libraries/ghc-compact/ghc-compact.cabal: Core library + libraries/ghc-experimental/ghc-experimental.cabal: Core library + libraries/ghc-heap/ghc-heap.cabal: GHC heap-walking library + libraries/ghci/ghci.cabal: The REPL interface + libraries/ghc-internal/ghc-internal.cabal: Core library + libraries/ghc-platform/ghc-platform.cabal: Internal library + libraries/ghc-prim/ghc-prim.cabal: Core library + libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable + libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable + libraries/integer-gmp/integer-gmp.cabal: Core library + libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library + libraries/os-string/os-string.cabal: Dependency of ``filepath`` library + libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library + libraries/pretty/pretty.cabal: Dependency of ``ghc`` library + libraries/process/process.cabal: Dependency of ``ghc`` library + libraries/semaphore-compat/semaphore-compat.cabal: Dependency of ``ghc`` library + libraries/stm/stm.cabal: Dependency of ``haskeline`` library + libraries/template-haskell/template-haskell.cabal: Core library + libraries/terminfo/terminfo.cabal: Dependency of ``haskeline`` library + libraries/text/text.cabal: Dependency of ``Cabal`` library + libraries/time/time.cabal: Dependency of ``ghc`` library + libraries/transformers/transformers.cabal: Dependency of ``ghc`` library + libraries/unix/unix.cabal: Dependency of ``ghc`` library + libraries/Win32/Win32.cabal: Dependency of ``ghc`` library + libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable + utils/haddock/haddock-api/haddock-api.cabal: Dependency of ``haddock`` executable + utils/haddock/haddock-library/haddock-library.cabal: Dependency of ``haddock`` executable + ===================================== docs/users_guide/release-notes.rst ===================================== @@ -5,3 +5,4 @@ Release notes :maxdepth: 1 9.12.1-notes + 9.12.2-notes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a48b7b51af4f31d0569ad614932facd5db2136b...a6f47532aa7c5e08f9d7549e72839b400d932cb8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a48b7b51af4f31d0569ad614932facd5db2136b...a6f47532aa7c5e08f9d7549e72839b400d932cb8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 18:09:35 2025 From: gitlab at gitlab.haskell.org (Sjoerd Visscher (@trac-sjoerd_visscher)) Date: Thu, 23 Jan 2025 13:09:35 -0500 Subject: [Git][ghc/ghc][wip/T18462] Unannotated multiplicity based on type Message-ID: <679285df5202_3852f557f8050343@gitlab.mail> Sjoerd Visscher pushed to branch wip/T18462 at Glasgow Haskell Compiler / GHC Commits: 227157fa by Sjoerd Visscher at 2025-01-23T19:09:28+01:00 Unannotated multiplicity based on type - - - - - 30 changed files: - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/Language/Haskell/Syntax/Decls.hs - compiler/Language/Haskell/Syntax/Type.hs - testsuite/tests/ghc-api/exactprint/Test20239.stderr - 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/parser/should_compile/DumpParsedAst.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/printer/T18791.stderr - utils/check-exact/ExactPrint.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/227157fa5f63b1e1fa96780850a05a00ff76f7a1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/227157fa5f63b1e1fa96780850a05a00ff76f7a1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 19:15:43 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 23 Jan 2025 14:15:43 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] doc: Add documentation for -XDoAndIfThenElse Message-ID: <6792955f5f949_3852f1528b306805a@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 1c6992fb by Teo Camarasu at 2025-01-23T14:15:38-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4 changed files: - docs/users_guide/conf.py - docs/users_guide/expected-undocumented-flags.txt - + docs/users_guide/exts/doandifthenelse.rst - docs/users_guide/exts/syntax.rst Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -36,7 +36,6 @@ nitpick_ignore = [ ("c:type", "bool"), - ("extension", "DoAndIfThenElse"), ("extension", "RelaxedPolyRec"), ] ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -7,7 +7,6 @@ -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional -XAutoDeriveTypeable --XDoAndIfThenElse -XDoRec -XJavaScriptFFI -XParallelArrays ===================================== docs/users_guide/exts/doandifthenelse.rst ===================================== @@ -0,0 +1,30 @@ +.. _doandifthenelse: + +Do And If Then Else +============ + +.. extension:: DoAndIfThenElse + :shortdesc: Allow semicolons in ``if`` expressions. + + :since: 7.0.1 + + :status: Included in :extension:`Haskell2010` + + Allow semicolons in ``if`` expressions. + +Normally, a conditional is written like this: ``if cond then expr1 else expr2``. With the extension +:extension:`DoAndIfThenElse`, semicolons are allowed before the ``then`` and also before the ``else``, allowing +``if cond; then expr1; else expr2``. (You can also include either semicolon on its own.) + +Allowing semicolons in the middle of a conditional is useful in connection with layout-controlled +blocks, like ``do``\ -blocks. This is because GHC invisibly inserts a semicolon between each line of a +layout-controlled block. Accordingly, with :extension:`DoAndIfThenElse`, we can write code like this :: + + f mb x y = do + b <- mb + if b + then x + else y + +Without :extension:`DoAndIfThenElse`, the ``then`` and ``else`` lines would have to be indented with respect +to the rest of the lines in the ``do``\ -block. ===================================== docs/users_guide/exts/syntax.rst ===================================== @@ -20,6 +20,7 @@ Syntax lambda_case empty_case multiway_if + doandifthenelse local_fixity_decls block_arguments typed_holes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c6992fbd5e50a8ffdc90a2d3707d3ae169441bb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c6992fbd5e50a8ffdc90a2d3707d3ae169441bb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 23:06:12 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 23 Jan 2025 18:06:12 -0500 Subject: [Git][ghc/ghc][master] Rework built-in and punned names (#25174, #25179, #25180, #25182) Message-ID: <6792cb64b4024_e98344d3bcc638c@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 51e3ec83 by Vladislav Zavialov at 2025-01-22T20:41:32+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Types/Name/Cache.hs - compiler/GHC/Types/Name/Ppr.hs - libraries/base/src/GHC/Base.hs - libraries/base/src/GHC/Exts.hs - testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/ghc-api/T18522-dbg-ppr.hs - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32 - + testsuite/tests/rename/should_compile/ReExportTuples.hs - + testsuite/tests/rename/should_compile/T25182.hs - testsuite/tests/rename/should_compile/all.T - testsuite/tests/simplStg/should_compile/T15226b.stderr - + testsuite/tests/th/FunNameTH.hs - testsuite/tests/th/T13776.hs - testsuite/tests/th/T13776.stderr - testsuite/tests/th/T17380.stderr - + testsuite/tests/th/T25174.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51e3ec839c378f0da7052278a56482f0349e9bc7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51e3ec839c378f0da7052278a56482f0349e9bc7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 23 23:06:49 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Thu, 23 Jan 2025 18:06:49 -0500 Subject: [Git][ghc/ghc][master] doc: Add documentation for -XDoAndIfThenElse Message-ID: <6792cb89b50b0_e98343bdbac68470@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 85c60aea by Teo Camarasu at 2025-01-23T18:06:21-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4 changed files: - docs/users_guide/conf.py - docs/users_guide/expected-undocumented-flags.txt - + docs/users_guide/exts/doandifthenelse.rst - docs/users_guide/exts/syntax.rst Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -36,7 +36,6 @@ nitpick_ignore = [ ("c:type", "bool"), - ("extension", "DoAndIfThenElse"), ("extension", "RelaxedPolyRec"), ] ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -7,7 +7,6 @@ -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional -XAutoDeriveTypeable --XDoAndIfThenElse -XDoRec -XJavaScriptFFI -XParallelArrays ===================================== docs/users_guide/exts/doandifthenelse.rst ===================================== @@ -0,0 +1,30 @@ +.. _doandifthenelse: + +Do And If Then Else +============ + +.. extension:: DoAndIfThenElse + :shortdesc: Allow semicolons in ``if`` expressions. + + :since: 7.0.1 + + :status: Included in :extension:`Haskell2010` + + Allow semicolons in ``if`` expressions. + +Normally, a conditional is written like this: ``if cond then expr1 else expr2``. With the extension +:extension:`DoAndIfThenElse`, semicolons are allowed before the ``then`` and also before the ``else``, allowing +``if cond; then expr1; else expr2``. (You can also include either semicolon on its own.) + +Allowing semicolons in the middle of a conditional is useful in connection with layout-controlled +blocks, like ``do``\ -blocks. This is because GHC invisibly inserts a semicolon between each line of a +layout-controlled block. Accordingly, with :extension:`DoAndIfThenElse`, we can write code like this :: + + f mb x y = do + b <- mb + if b + then x + else y + +Without :extension:`DoAndIfThenElse`, the ``then`` and ``else`` lines would have to be indented with respect +to the rest of the lines in the ``do``\ -block. ===================================== docs/users_guide/exts/syntax.rst ===================================== @@ -20,6 +20,7 @@ Syntax lambda_case empty_case multiway_if + doandifthenelse local_fixity_decls block_arguments typed_holes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85c60aead149dd52a5c778e124e21aae3f95a23b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85c60aead149dd52a5c778e124e21aae3f95a23b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 03:15:36 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Thu, 23 Jan 2025 22:15:36 -0500 Subject: [Git][ghc/ghc][wip/T25609] Fix lexing comments in multiline strings (#25609) Message-ID: <679305d8e7e01_1047bb25c61f48078@gitlab.mail> Brandon Chinn pushed to branch wip/T25609 at Glasgow Haskell Compiler / GHC Commits: b3cbf332 by Brandon Chinn at 2025-01-23T19:15:24-08:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - 10 changed files: - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/String.x - compiler/ghc.cabal.in - hadrian/src/Rules/SourceDist.hs - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/parser/should_run/NumericUnderscores0.hs - testsuite/tests/parser/should_run/NumericUnderscores0.stdout - + testsuite/tests/parser/should_run/T25609.hs - + testsuite/tests/parser/should_run/T25609.stdout - testsuite/tests/parser/should_run/all.T Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -132,6 +132,7 @@ import GHC.Parser.Errors.Basic import GHC.Parser.Errors.Types import GHC.Parser.Errors.Ppr () import GHC.Parser.Lexer.Interface +import qualified GHC.Parser.Lexer.String as Lexer.String import GHC.Parser.String } @@ -622,13 +623,6 @@ $unigraphic / { isSmartQuote } { smart_quote_error } \" @stringchar* $unigraphic / { isSmartQuote } { smart_quote_error } } - { - -- Parse as much of the multiline string as possible, except for quotes - @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { tok_string_multi_content } - -- Allow bare quotes if it's not a triple quote - (\" | \"\") / ([\n .] # \") { tok_string_multi_content } -} - <0> { \'\' { token ITtyQuote } @@ -2171,11 +2165,23 @@ tok_string span buf len _buf2 = do src = SourceText $ lexemeToFastString buf len endsInHash = currentChar (offsetBytes (len - 1) buf) == '#' --- | Ideally, we would define this completely with Alex syntax, like normal strings. --- Instead, this is defined as a hybrid solution by manually invoking lex states, which --- we're doing for two reasons: --- 1. The multiline string should all be one lexical token, not multiple --- 2. We need to allow bare quotes, which can't be done with one regex +{- Note [Lexing multiline strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ideally, we would lex multiline strings completely with Alex syntax, like +normal strings. However, we can't because: + + 1. The multiline string should all be one lexical token, not multiple + 2. We need to allow bare quotes, which can't be done with one regex + +Instead, we'll lex them with a hybrid solution in tok_string_multi by manually +invoking lex states. This allows us to get the performance of native Alex +syntax as much as possible, and just gluing the pieces together outside of +Alex. + +Implemented in string_multi_content in GHC/Parser/Lexer/String.x +-} + +-- | See Note [Lexing multiline strings] tok_string_multi :: Action tok_string_multi startSpan startBuf _len _buf2 = do -- advance to the end of the multiline string @@ -2201,17 +2207,14 @@ tok_string_multi startSpan startBuf _len _buf2 = do pure $ L span $ ITstringMulti src (mkFastString s) where goContent i0 = - case alexScan i0 string_multi_content of - AlexToken i1 len _ + case Lexer.String.alexScan i0 Lexer.String.string_multi_content of + Lexer.String.AlexToken i1 len _ | Just i2 <- lexDelim i1 -> pure (i1, i2) | isEOF i1 -> checkSmartQuotes >> setInput i1 >> lexError LexError - -- is the next token a tab character? - -- need this explicitly because there's a global rule matching $tab - | Just ('\t', _) <- alexGetChar' i1 -> setInput i1 >> lexError LexError -- Can happen if no patterns match, e.g. an unterminated gap | len == 0 -> setInput i1 >> lexError LexError | otherwise -> goContent i1 - AlexSkip i1 _ -> goContent i1 + Lexer.String.AlexSkip i1 _ -> goContent i1 _ -> setInput i0 >> lexError LexError lexDelim = @@ -2235,11 +2238,6 @@ tok_string_multi startSpan startBuf _len _buf2 = do Just (c, loc) -> throwSmartQuoteError c loc Nothing -> pure () --- | Dummy action that should never be called. Should only be used in lex states --- that are manually lexed in tok_string_multi. -tok_string_multi_content :: Action -tok_string_multi_content = panic "tok_string_multi_content unexpectedly invoked" - lex_chars :: (String, String) -> PsSpan -> StringBuffer -> Int -> P String lex_chars (startDelim, endDelim) span buf len = either (throwStringLexError i0) pure $ @@ -3371,6 +3369,7 @@ topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. +-- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} lexToken :: P (PsLocated Token) ===================================== compiler/GHC/Parser/Lexer/String.x ===================================== @@ -0,0 +1,96 @@ +{ +{- | +This module defines lex states for strings. + +This needs to be separate from the normal lexer because the normal lexer +automatically includes rules like skipping whitespace or lexing comments, +which we don't want in these contexts. +-} +module GHC.Parser.Lexer.String ( + AlexReturn (..), + alexScan, + string_multi_content, +) where + +import GHC.Prelude + +import GHC.Parser.Lexer.Interface +import GHC.Utils.Panic (panic) +} + +-- ----------------------------------------------------------------------------- +-- Alex "Character set macros" +-- Copied from GHC/Parser/Lexer.x + +$unispace = \x05 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$nl = [\n\r\f] +$space = [\ $unispace] +$whitechar = [$nl \v $space] +$tab = \t + +$ascdigit = 0-9 +$unidigit = \x03 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$decdigit = $ascdigit -- exactly $ascdigit, no more no less. +$digit = [$ascdigit $unidigit] + +$special = [\(\)\,\;\[\]\`\{\}] +$ascsymbol = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~\:] +$unisymbol = \x04 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$symbol = [$ascsymbol $unisymbol] # [$special \_\"\'] + +$unilarge = \x01 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$asclarge = [A-Z] +$large = [$asclarge $unilarge] + +$unismall = \x02 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$ascsmall = [a-z] +$small = [$ascsmall $unismall \_] + +$uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$idchar = [$small $large $digit $uniidchar \'] + +$unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] +$charesc = [a b f n r t v \\ \" \' \&] + +$octit = 0-7 +$hexit = [$decdigit A-F a-f] + +-- ----------------------------------------------------------------------------- +-- Alex "Regular expression macros" +-- Copied from GHC/Parser/Lexer.x + + at numspc = _* -- numeric spacer (#14473) + at decimal = $decdigit(@numspc $decdigit)* + at octal = $octit(@numspc $octit)* + at hexadecimal = $hexit(@numspc $hexit)* + at gap = \\ $whitechar+ \\ + at cntrl = $asclarge | \@ | \[ | \\ | \] | \^ | \_ + at ascii = \^ @cntrl | "NUL" | "SOH" | "STX" | "ETX" | "EOT" | "ENQ" | "ACK" + | "BEL" | "BS" | "HT" | "LF" | "VT" | "FF" | "CR" | "SO" | "SI" | "DLE" + | "DC1" | "DC2" | "DC3" | "DC4" | "NAK" | "SYN" | "ETB" | "CAN" + | "EM" | "SUB" | "ESC" | "FS" | "GS" | "RS" | "US" | "SP" | "DEL" + at escape = \\ ( $charesc | @ascii | @decimal | o @octal | x @hexadecimal ) + at stringchar = ($graphic # [\\ \"]) | $space | @escape | @gap + +:- + +-- Define an empty rule so it compiles; callers should always explicitly specify a startcode +<0> () ; + +-- See Note [Lexing multiline strings] + { + -- Parse as much of the multiline string as possible, except for quotes + @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { string_multi_content_action } + -- Allow bare quotes if it's not a triple quote + (\" | \"\") / ([\n .] # \") { string_multi_content_action } +} + +-- ----------------------------------------------------------------------------- +-- Haskell actions +{ +-- | Dummy action that should never be called. Should only be used in lex states +-- that are manually lexed in tok_string_multi. +string_multi_content_action :: a +string_multi_content_action = panic "string_multi_content_action unexpectedly invoked" +} ===================================== compiler/ghc.cabal.in ===================================== @@ -647,6 +647,7 @@ Library GHC.Parser.Header GHC.Parser.Lexer GHC.Parser.Lexer.Interface + GHC.Parser.Lexer.String GHC.Parser.HaddockLex GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock ===================================== hadrian/src/Rules/SourceDist.hs ===================================== @@ -185,6 +185,7 @@ prepareTree dest = do , (stage0InTree , compiler, "GHC/Cmm/Lexer.x", "GHC/Cmm/Lexer.hs") , (stage0InTree , compiler, "GHC/Parser.y", "GHC/Parser.hs") , (stage0InTree , compiler, "GHC/Parser/Lexer.x", "GHC/Parser/Lexer.hs") + , (stage0InTree , compiler, "GHC/Parser/Lexer/String.x", "GHC/Parser/Lexer/String.hs") , (stage0InTree , compiler, "GHC/Parser/HaddockLex.x", "GHC/Parser/HaddockLex.hs") , (stage0InTree , hpcBin, "src/Trace/Hpc/Parser.y", "src/Trace/Hpc/Parser.hs") , (stage0InTree , genprimopcode, "Parser.y", "Parser.hs") ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -128,6 +128,7 @@ GHC.Parser.Errors.Types GHC.Parser.HaddockLex GHC.Parser.Lexer GHC.Parser.Lexer.Interface +GHC.Parser.Lexer.String GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock GHC.Parser.String ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.hs ===================================== @@ -99,3 +99,6 @@ main = do 0x_ff == 0xff, 0x__ff == 0xff ] + + -- ensure that strings are unaffected + print ["\o16_000", "\16_000", "\x16_000"] ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.stdout ===================================== @@ -11,3 +11,4 @@ [True,True,True] [True,True,True] [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] +["\SO_000","\DLE_000","\SYN_000"] ===================================== testsuite/tests/parser/should_run/T25609.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE MultilineStrings #-} + +main :: IO () +main = do + -- strings with comment tokens + print """{- asdf -}""" + print """a {- asdf -} b""" + print """-- asdf""" + print """{-""" + + -- strings with haddock comments + print """{- | test -}""" + print """{- * test -}""" + print """{- ^ test -}""" + print """{- $ test -}""" + print """-- | test""" + print """-- * test""" + print """-- ^ test""" + print """-- $ test""" + + -- strings with only whitespace + print """ """ + print """ + + + """ + + -- strings with unicode + print """ + ★ + ★ + ★ + ★ + """ ===================================== testsuite/tests/parser/should_run/T25609.stdout ===================================== @@ -0,0 +1,15 @@ +"{- asdf -}" +"a {- asdf -} b" +"-- asdf" +"{-" +"{- | test -}" +"{- * test -}" +"{- ^ test -}" +"{- $ test -}" +"-- | test" +"-- * test" +"-- ^ test" +"-- $ test" +" " +"\n" +" \9733\n\9733\n \9733\n\9733" ===================================== testsuite/tests/parser/should_run/all.T ===================================== @@ -21,6 +21,9 @@ test('RecordDotSyntax3', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compil test('RecordDotSyntax4', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compile_and_run, ['RecordDotSyntax4', '']) test('RecordDotSyntax5', normal, compile_and_run, ['']) test('ListTuplePunsConstraints', extra_files(['ListTuplePunsConstraints.hs']), ghci_script, ['ListTuplePunsConstraints.script']) + +# Multiline strings test('MultilineStrings', normal, compile_and_run, ['']) test('MultilineStringsOverloaded', normal, compile_and_run, ['']) test('T25375', normal, compile_and_run, ['']) +test('T25609', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3cbf332e4d513628bb8aa9fda28330afb5e4d05 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b3cbf332e4d513628bb8aa9fda28330afb5e4d05 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 03:18:44 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Thu, 23 Jan 2025 22:18:44 -0500 Subject: [Git][ghc/ghc][wip/T25623] Fix for alex-3.5.2.0 (#25623) Message-ID: <679306949b7bd_1047bb25133b0814d1@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: c6ed6f7a by Brandon Chinn at 2025-01-23T19:18:35-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 1 changed file: - compiler/GHC/Parser/Lexer.x Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3467,10 +3468,12 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. {-# INLINE alexScanUser #-} +#endif lexToken :: P (PsLocated Token) lexToken = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6ed6f7a3897bbf1b41ada7a1701038fda604969 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c6ed6f7a3897bbf1b41ada7a1701038fda604969 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 13:44:35 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 24 Jan 2025 08:44:35 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: doc: Add documentation for -XDoAndIfThenElse Message-ID: <67939943b926f_31326bc0954698d9@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 85c60aea by Teo Camarasu at 2025-01-23T18:06:21-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 45bfe5f5 by Brandon Chinn at 2025-01-24T08:44:16-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 156b0a75 by Brandon Chinn at 2025-01-24T08:44:16-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - 88e174ff by Matthew Pickering at 2025-01-24T08:44:17-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - 23 changed files: - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/ghc.cabal.in - docs/users_guide/conf.py - docs/users_guide/expected-undocumented-flags.txt - + docs/users_guide/exts/doandifthenelse.rst - docs/users_guide/exts/syntax.rst - hadrian/src/Rules/SourceDist.hs - testsuite/tests/bytecode/T24634/Makefile - testsuite/tests/codeGen/should_compile/Makefile - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/driver/j-space/jspace.hs - testsuite/tests/parser/should_run/NumericUnderscores0.hs - testsuite/tests/parser/should_run/NumericUnderscores0.stdout - + testsuite/tests/parser/should_run/T25609.hs - + testsuite/tests/parser/should_run/T25609.stdout - testsuite/tests/parser/should_run/all.T - testsuite/tests/patsyn/should_compile/T13350/Makefile - testsuite/tests/rts/Makefile - testsuite/tests/rts/T1791/Makefile - testsuite/tests/wasm/should_run/control-flow/WasmControlFlow.hs Changes: ===================================== compiler/GHC/Parser/HaddockLex.x ===================================== @@ -8,6 +8,7 @@ import GHC.Prelude import GHC.Data.FastString import GHC.Hs.Doc import GHC.Parser.Lexer +import GHC.Parser.Lexer.Interface (adjustChar) import GHC.Parser.Annotation import GHC.Types.SrcLoc import GHC.Types.SourceText ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -78,7 +78,6 @@ module GHC.Parser.Lexer ( commentToAnnotation, HdkComment(..), warnopt, - adjustChar, addPsMessage ) where @@ -132,6 +131,8 @@ import GHC.Driver.Flags import GHC.Parser.Errors.Basic import GHC.Parser.Errors.Types import GHC.Parser.Errors.Ppr () +import GHC.Parser.Lexer.Interface +import qualified GHC.Parser.Lexer.String as Lexer.String import GHC.Parser.String } @@ -622,13 +623,6 @@ $unigraphic / { isSmartQuote } { smart_quote_error } \" @stringchar* $unigraphic / { isSmartQuote } { smart_quote_error } } - { - -- Parse as much of the multiline string as possible, except for quotes - @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { tok_string_multi_content } - -- Allow bare quotes if it's not a triple quote - (\" | \"\") / ([\n .] # \") { tok_string_multi_content } -} - <0> { \'\' { token ITtyQuote } @@ -2171,11 +2165,23 @@ tok_string span buf len _buf2 = do src = SourceText $ lexemeToFastString buf len endsInHash = currentChar (offsetBytes (len - 1) buf) == '#' --- | Ideally, we would define this completely with Alex syntax, like normal strings. --- Instead, this is defined as a hybrid solution by manually invoking lex states, which --- we're doing for two reasons: --- 1. The multiline string should all be one lexical token, not multiple --- 2. We need to allow bare quotes, which can't be done with one regex +{- Note [Lexing multiline strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ideally, we would lex multiline strings completely with Alex syntax, like +normal strings. However, we can't because: + + 1. The multiline string should all be one lexical token, not multiple + 2. We need to allow bare quotes, which can't be done with one regex + +Instead, we'll lex them with a hybrid solution in tok_string_multi by manually +invoking lex states. This allows us to get the performance of native Alex +syntax as much as possible, and just gluing the pieces together outside of +Alex. + +Implemented in string_multi_content in GHC/Parser/Lexer/String.x +-} + +-- | See Note [Lexing multiline strings] tok_string_multi :: Action tok_string_multi startSpan startBuf _len _buf2 = do -- advance to the end of the multiline string @@ -2201,17 +2207,14 @@ tok_string_multi startSpan startBuf _len _buf2 = do pure $ L span $ ITstringMulti src (mkFastString s) where goContent i0 = - case alexScan i0 string_multi_content of - AlexToken i1 len _ + case Lexer.String.alexScan i0 Lexer.String.string_multi_content of + Lexer.String.AlexToken i1 len _ | Just i2 <- lexDelim i1 -> pure (i1, i2) | isEOF i1 -> checkSmartQuotes >> setInput i1 >> lexError LexError - -- is the next token a tab character? - -- need this explicitly because there's a global rule matching $tab - | Just ('\t', _) <- alexGetChar' i1 -> setInput i1 >> lexError LexError -- Can happen if no patterns match, e.g. an unterminated gap | len == 0 -> setInput i1 >> lexError LexError | otherwise -> goContent i1 - AlexSkip i1 _ -> goContent i1 + Lexer.String.AlexSkip i1 _ -> goContent i1 _ -> setInput i0 >> lexError LexError lexDelim = @@ -2235,11 +2238,6 @@ tok_string_multi startSpan startBuf _len _buf2 = do Just (c, loc) -> throwSmartQuoteError c loc Nothing -> pure () --- | Dummy action that should never be called. Should only be used in lex states --- that are manually lexed in tok_string_multi. -tok_string_multi_content :: Action -tok_string_multi_content = panic "tok_string_multi_content unexpectedly invoked" - lex_chars :: (String, String) -> PsSpan -> StringBuffer -> Int -> P String lex_chars (startDelim, endDelim) span buf len = either (throwStringLexError i0) pure $ @@ -2591,105 +2589,6 @@ getLastLocIncludingComments = P $ \s@(PState { prev_loc = prev_loc }) -> POk s p getLastLoc :: P PsSpan getLastLoc = P $ \s@(PState { last_loc = last_loc }) -> POk s last_loc -data AlexInput = AI !PsLoc !StringBuffer deriving (Show) - -{- -Note [Unicode in Alex] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Although newer versions of Alex support unicode, this grammar is processed with -the old style '--latin1' behaviour. This means that when implementing the -functions - - alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) - alexInputPrevChar :: AlexInput -> Char - -which Alex uses to take apart our 'AlexInput', we must - - * return a latin1 character in the 'Word8' that 'alexGetByte' expects - * return a latin1 character in 'alexInputPrevChar'. - -We handle this in 'adjustChar' by squishing entire classes of unicode -characters into single bytes. --} - -{-# INLINE adjustChar #-} -adjustChar :: Char -> Word8 -adjustChar c = adj_c - where non_graphic = 0x00 - upper = 0x01 - lower = 0x02 - digit = 0x03 - symbol = 0x04 - space = 0x05 - other_graphic = 0x06 - uniidchar = 0x07 - - adj_c - | c <= '\x07' = non_graphic - | c <= '\x7f' = fromIntegral (ord c) - -- Alex doesn't handle Unicode, so when Unicode - -- character is encountered we output these values - -- with the actual character value hidden in the state. - | otherwise = - -- NB: The logic behind these definitions is also reflected - -- in "GHC.Utils.Lexeme" - -- Any changes here should likely be reflected there. - - case generalCategory c of - UppercaseLetter -> upper - LowercaseLetter -> lower - TitlecaseLetter -> upper - ModifierLetter -> uniidchar -- see #10196 - OtherLetter -> lower -- see #1103 - NonSpacingMark -> uniidchar -- see #7650 - SpacingCombiningMark -> other_graphic - EnclosingMark -> other_graphic - DecimalNumber -> digit - LetterNumber -> digit - OtherNumber -> digit -- see #4373 - ConnectorPunctuation -> symbol - DashPunctuation -> symbol - OpenPunctuation -> other_graphic - ClosePunctuation -> other_graphic - InitialQuote -> other_graphic - FinalQuote -> other_graphic - OtherPunctuation -> symbol - MathSymbol -> symbol - CurrencySymbol -> symbol - ModifierSymbol -> symbol - OtherSymbol -> symbol - Space -> space - _other -> non_graphic - --- Getting the previous 'Char' isn't enough here - we need to convert it into --- the same format that 'alexGetByte' would have produced. --- --- See Note [Unicode in Alex] and #13986. -alexInputPrevChar :: AlexInput -> Char -alexInputPrevChar (AI _ buf) = unsafeChr (fromIntegral (adjustChar pc)) - where pc = prevChar buf '\n' - -unsafeChr :: Int -> Char -unsafeChr (I# c) = GHC.Exts.C# (GHC.Exts.chr# c) - --- backwards compatibility for Alex 2.x -alexGetChar :: AlexInput -> Maybe (Char,AlexInput) -alexGetChar inp = case alexGetByte inp of - Nothing -> Nothing - Just (b,i) -> c `seq` Just (c,i) - where c = unsafeChr $ fromIntegral b - --- See Note [Unicode in Alex] -alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) -alexGetByte (AI loc s) - | atEnd s = Nothing - | otherwise = byte `seq` loc' `seq` s' `seq` - --trace (show (ord c)) $ - Just (byte, (AI loc' s')) - where (c,s') = nextChar s - loc' = advancePsLoc loc c - byte = adjustChar c - {-# INLINE alexGetChar' #-} -- This version does not squash unicode characters, it is used when -- lexing strings. @@ -3470,6 +3369,7 @@ topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. +-- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} lexToken :: P (PsLocated Token) ===================================== compiler/GHC/Parser/Lexer/Interface.hs ===================================== @@ -0,0 +1,124 @@ +{-# LANGUAGE MagicHash #-} + +{- | +This module defines the types and functions necessary for an Alex-generated +lexer. + +https://haskell-alex.readthedocs.io/en/latest/api.html# +-} +module GHC.Parser.Lexer.Interface ( + AlexInput (..), + alexGetByte, + alexInputPrevChar, + + -- * Helpers + alexGetChar, + adjustChar, +) where + +import GHC.Prelude + +import Data.Char (GeneralCategory (..), generalCategory, ord) +import Data.Word (Word8) +import GHC.Data.StringBuffer (StringBuffer, atEnd, nextChar, prevChar) +import GHC.Exts +import GHC.Types.SrcLoc (PsLoc, advancePsLoc) + +data AlexInput = AI !PsLoc !StringBuffer deriving (Show) + +-- See Note [Unicode in Alex] +alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) +alexGetByte (AI loc s) + | atEnd s = Nothing + | otherwise = byte `seq` loc' `seq` s' `seq` + --trace (show (ord c)) $ + Just (byte, (AI loc' s')) + where (c,s') = nextChar s + loc' = advancePsLoc loc c + byte = adjustChar c + +-- Getting the previous 'Char' isn't enough here - we need to convert it into +-- the same format that 'alexGetByte' would have produced. +-- +-- See Note [Unicode in Alex] and #13986. +alexInputPrevChar :: AlexInput -> Char +alexInputPrevChar (AI _ buf) = unsafeChr (fromIntegral (adjustChar pc)) + where pc = prevChar buf '\n' + +-- backwards compatibility for Alex 2.x +alexGetChar :: AlexInput -> Maybe (Char,AlexInput) +alexGetChar inp = case alexGetByte inp of + Nothing -> Nothing + Just (b,i) -> c `seq` Just (c,i) + where c = unsafeChr $ fromIntegral b + +unsafeChr :: Int -> Char +unsafeChr (I# c) = GHC.Exts.C# (GHC.Exts.chr# c) + +{- +Note [Unicode in Alex] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Although newer versions of Alex support unicode, this grammar is processed with +the old style '--latin1' behaviour. This means that when implementing the +functions + + alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) + alexInputPrevChar :: AlexInput -> Char + +which Alex uses to take apart our 'AlexInput', we must + + * return a latin1 character in the 'Word8' that 'alexGetByte' expects + * return a latin1 character in 'alexInputPrevChar'. + +We handle this in 'adjustChar' by squishing entire classes of unicode +characters into single bytes. +-} + +{-# INLINE adjustChar #-} +adjustChar :: Char -> Word8 +adjustChar c = adj_c + where non_graphic = 0x00 + upper = 0x01 + lower = 0x02 + digit = 0x03 + symbol = 0x04 + space = 0x05 + other_graphic = 0x06 + uniidchar = 0x07 + + adj_c + | c <= '\x07' = non_graphic + | c <= '\x7f' = fromIntegral (ord c) + -- Alex doesn't handle Unicode, so when Unicode + -- character is encountered we output these values + -- with the actual character value hidden in the state. + | otherwise = + -- NB: The logic behind these definitions is also reflected + -- in "GHC.Utils.Lexeme" + -- Any changes here should likely be reflected there. + + case generalCategory c of + UppercaseLetter -> upper + LowercaseLetter -> lower + TitlecaseLetter -> upper + ModifierLetter -> uniidchar -- see #10196 + OtherLetter -> lower -- see #1103 + NonSpacingMark -> uniidchar -- see #7650 + SpacingCombiningMark -> other_graphic + EnclosingMark -> other_graphic + DecimalNumber -> digit + LetterNumber -> digit + OtherNumber -> digit -- see #4373 + ConnectorPunctuation -> symbol + DashPunctuation -> symbol + OpenPunctuation -> other_graphic + ClosePunctuation -> other_graphic + InitialQuote -> other_graphic + FinalQuote -> other_graphic + OtherPunctuation -> symbol + MathSymbol -> symbol + CurrencySymbol -> symbol + ModifierSymbol -> symbol + OtherSymbol -> symbol + Space -> space + _other -> non_graphic ===================================== compiler/GHC/Parser/Lexer/String.x ===================================== @@ -0,0 +1,96 @@ +{ +{- | +This module defines lex states for strings. + +This needs to be separate from the normal lexer because the normal lexer +automatically includes rules like skipping whitespace or lexing comments, +which we don't want in these contexts. +-} +module GHC.Parser.Lexer.String ( + AlexReturn (..), + alexScan, + string_multi_content, +) where + +import GHC.Prelude + +import GHC.Parser.Lexer.Interface +import GHC.Utils.Panic (panic) +} + +-- ----------------------------------------------------------------------------- +-- Alex "Character set macros" +-- Copied from GHC/Parser/Lexer.x + +$unispace = \x05 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$nl = [\n\r\f] +$space = [\ $unispace] +$whitechar = [$nl \v $space] +$tab = \t + +$ascdigit = 0-9 +$unidigit = \x03 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$decdigit = $ascdigit -- exactly $ascdigit, no more no less. +$digit = [$ascdigit $unidigit] + +$special = [\(\)\,\;\[\]\`\{\}] +$ascsymbol = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~\:] +$unisymbol = \x04 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$symbol = [$ascsymbol $unisymbol] # [$special \_\"\'] + +$unilarge = \x01 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$asclarge = [A-Z] +$large = [$asclarge $unilarge] + +$unismall = \x02 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$ascsmall = [a-z] +$small = [$ascsmall $unismall \_] + +$uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$idchar = [$small $large $digit $uniidchar \'] + +$unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] +$charesc = [a b f n r t v \\ \" \' \&] + +$octit = 0-7 +$hexit = [$decdigit A-F a-f] + +-- ----------------------------------------------------------------------------- +-- Alex "Regular expression macros" +-- Copied from GHC/Parser/Lexer.x + + at numspc = _* -- numeric spacer (#14473) + at decimal = $decdigit(@numspc $decdigit)* + at octal = $octit(@numspc $octit)* + at hexadecimal = $hexit(@numspc $hexit)* + at gap = \\ $whitechar+ \\ + at cntrl = $asclarge | \@ | \[ | \\ | \] | \^ | \_ + at ascii = \^ @cntrl | "NUL" | "SOH" | "STX" | "ETX" | "EOT" | "ENQ" | "ACK" + | "BEL" | "BS" | "HT" | "LF" | "VT" | "FF" | "CR" | "SO" | "SI" | "DLE" + | "DC1" | "DC2" | "DC3" | "DC4" | "NAK" | "SYN" | "ETB" | "CAN" + | "EM" | "SUB" | "ESC" | "FS" | "GS" | "RS" | "US" | "SP" | "DEL" + at escape = \\ ( $charesc | @ascii | @decimal | o @octal | x @hexadecimal ) + at stringchar = ($graphic # [\\ \"]) | $space | @escape | @gap + +:- + +-- Define an empty rule so it compiles; callers should always explicitly specify a startcode +<0> () ; + +-- See Note [Lexing multiline strings] + { + -- Parse as much of the multiline string as possible, except for quotes + @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { string_multi_content_action } + -- Allow bare quotes if it's not a triple quote + (\" | \"\") / ([\n .] # \") { string_multi_content_action } +} + +-- ----------------------------------------------------------------------------- +-- Haskell actions +{ +-- | Dummy action that should never be called. Should only be used in lex states +-- that are manually lexed in tok_string_multi. +string_multi_content_action :: a +string_multi_content_action = panic "string_multi_content_action unexpectedly invoked" +} ===================================== compiler/ghc.cabal.in ===================================== @@ -646,6 +646,8 @@ Library GHC.Parser.Errors.Types GHC.Parser.Header GHC.Parser.Lexer + GHC.Parser.Lexer.Interface + GHC.Parser.Lexer.String GHC.Parser.HaddockLex GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock ===================================== docs/users_guide/conf.py ===================================== @@ -36,7 +36,6 @@ nitpick_ignore = [ ("c:type", "bool"), - ("extension", "DoAndIfThenElse"), ("extension", "RelaxedPolyRec"), ] ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -7,7 +7,6 @@ -XAlternativeLayoutRule -XAlternativeLayoutRuleTransitional -XAutoDeriveTypeable --XDoAndIfThenElse -XDoRec -XJavaScriptFFI -XParallelArrays ===================================== docs/users_guide/exts/doandifthenelse.rst ===================================== @@ -0,0 +1,30 @@ +.. _doandifthenelse: + +Do And If Then Else +============ + +.. extension:: DoAndIfThenElse + :shortdesc: Allow semicolons in ``if`` expressions. + + :since: 7.0.1 + + :status: Included in :extension:`Haskell2010` + + Allow semicolons in ``if`` expressions. + +Normally, a conditional is written like this: ``if cond then expr1 else expr2``. With the extension +:extension:`DoAndIfThenElse`, semicolons are allowed before the ``then`` and also before the ``else``, allowing +``if cond; then expr1; else expr2``. (You can also include either semicolon on its own.) + +Allowing semicolons in the middle of a conditional is useful in connection with layout-controlled +blocks, like ``do``\ -blocks. This is because GHC invisibly inserts a semicolon between each line of a +layout-controlled block. Accordingly, with :extension:`DoAndIfThenElse`, we can write code like this :: + + f mb x y = do + b <- mb + if b + then x + else y + +Without :extension:`DoAndIfThenElse`, the ``then`` and ``else`` lines would have to be indented with respect +to the rest of the lines in the ``do``\ -block. ===================================== docs/users_guide/exts/syntax.rst ===================================== @@ -20,6 +20,7 @@ Syntax lambda_case empty_case multiway_if + doandifthenelse local_fixity_decls block_arguments typed_holes ===================================== hadrian/src/Rules/SourceDist.hs ===================================== @@ -185,6 +185,7 @@ prepareTree dest = do , (stage0InTree , compiler, "GHC/Cmm/Lexer.x", "GHC/Cmm/Lexer.hs") , (stage0InTree , compiler, "GHC/Parser.y", "GHC/Parser.hs") , (stage0InTree , compiler, "GHC/Parser/Lexer.x", "GHC/Parser/Lexer.hs") + , (stage0InTree , compiler, "GHC/Parser/Lexer/String.x", "GHC/Parser/Lexer/String.hs") , (stage0InTree , compiler, "GHC/Parser/HaddockLex.x", "GHC/Parser/HaddockLex.hs") , (stage0InTree , hpcBin, "src/Trace/Hpc/Parser.y", "src/Trace/Hpc/Parser.hs") , (stage0InTree , genprimopcode, "Parser.y", "Parser.hs") ===================================== testsuite/tests/bytecode/T24634/Makefile ===================================== @@ -4,14 +4,14 @@ include $(TOP)/mk/test.mk # This case loads bytecode from the interface file written in the second invocation. T24634a: - '$(TEST_HC)' -c hello_c.c -o hello_c.o - '$(TEST_HC)' -c -fbyte-code-and-object-code -fno-omit-interface-pragmas Hello.hs - '$(TEST_HC)' -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Main.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -c hello_c.c -o hello_c.o + '$(TEST_HC)' $(TEST_HC_OPTS) -c -fbyte-code-and-object-code -fno-omit-interface-pragmas Hello.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Main.hs ./Main # This case uses the bytecode generated in 'runHscBackendPhase', not involving the interface, since 'Hello' is compiled # in the same invocation as 'Main'. T24634b: - '$(TEST_HC)' -c hello_c.c -o hello_c.o - '$(TEST_HC)' -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Hello.hs Main.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -c hello_c.c -o hello_c.o + '$(TEST_HC)' $(TEST_HC_OPTS) -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Hello.hs Main.hs ./Main ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -79,4 +79,4 @@ T17648: grep -F 'f :: T GHC.Types.Int -> () [TagSig' >/dev/null T25166: - '$(TEST_HC)' -O2 -dno-typeable-binds -ddump-cmm T25166.hs | awk '/foo_closure/{flag=1}/}]/{flag=0}flag' + '$(TEST_HC)' $(TEST_HC_OPTS) -O2 -dno-typeable-binds -ddump-cmm T25166.hs | awk '/foo_closure/{flag=1}/}]/{flag=0}flag' ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -127,6 +127,8 @@ GHC.Parser.Errors.Ppr GHC.Parser.Errors.Types GHC.Parser.HaddockLex GHC.Parser.Lexer +GHC.Parser.Lexer.Interface +GHC.Parser.Lexer.String GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock GHC.Parser.String ===================================== testsuite/tests/driver/j-space/jspace.hs ===================================== @@ -23,7 +23,7 @@ initGhcM :: [String] -> Ghc () initGhcM xs = do session <- getSession df1 <- getSessionDynFlags - let cmdOpts = ["-fforce-recomp"] ++ xs + let cmdOpts = ["-fforce-recomp", "-dno-debug-output"] ++ xs (df2, leftovers, _) <- parseDynamicFlags (hsc_logger session) df1 (map noLoc cmdOpts) setSessionDynFlags df2 ghcUnitId <- case lookup "Project Unit Id" (compilerInfo df2) of ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.hs ===================================== @@ -99,3 +99,6 @@ main = do 0x_ff == 0xff, 0x__ff == 0xff ] + + -- ensure that strings are unaffected + print ["\o16_000", "\16_000", "\x16_000"] ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.stdout ===================================== @@ -11,3 +11,4 @@ [True,True,True] [True,True,True] [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] +["\SO_000","\DLE_000","\SYN_000"] ===================================== testsuite/tests/parser/should_run/T25609.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE MultilineStrings #-} + +main :: IO () +main = do + -- strings with comment tokens + print """{- asdf -}""" + print """a {- asdf -} b""" + print """-- asdf""" + print """{-""" + + -- strings with haddock comments + print """{- | test -}""" + print """{- * test -}""" + print """{- ^ test -}""" + print """{- $ test -}""" + print """-- | test""" + print """-- * test""" + print """-- ^ test""" + print """-- $ test""" + + -- strings with only whitespace + print """ """ + print """ + + + """ + + -- strings with unicode + print """ + ★ + ★ + ★ + ★ + """ ===================================== testsuite/tests/parser/should_run/T25609.stdout ===================================== @@ -0,0 +1,15 @@ +"{- asdf -}" +"a {- asdf -} b" +"-- asdf" +"{-" +"{- | test -}" +"{- * test -}" +"{- ^ test -}" +"{- $ test -}" +"-- | test" +"-- * test" +"-- ^ test" +"-- $ test" +" " +"\n" +" \9733\n\9733\n \9733\n\9733" ===================================== testsuite/tests/parser/should_run/all.T ===================================== @@ -21,6 +21,9 @@ test('RecordDotSyntax3', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compil test('RecordDotSyntax4', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compile_and_run, ['RecordDotSyntax4', '']) test('RecordDotSyntax5', normal, compile_and_run, ['']) test('ListTuplePunsConstraints', extra_files(['ListTuplePunsConstraints.hs']), ghci_script, ['ListTuplePunsConstraints.script']) + +# Multiline strings test('MultilineStrings', normal, compile_and_run, ['']) test('MultilineStringsOverloaded', normal, compile_and_run, ['']) test('T25375', normal, compile_and_run, ['']) +test('T25609', normal, compile_and_run, ['']) ===================================== testsuite/tests/patsyn/should_compile/T13350/Makefile ===================================== @@ -7,7 +7,7 @@ LOCAL_PKGCONF=local.package.conf T13350: "$(GHC_PKG)" init $(LOCAL_PKGCONF) cd boolean && "$(TEST_HC)" $(TEST_HC_OPTS) -v0 --make Setup.hs - cd boolean && ./Setup configure -v0 --with-compiler="$(TEST_HC)" --with-hc-pkg="$(GHC_PKG)" --package-db=../$(LOCAL_PKGCONF) + cd boolean && ./Setup configure -v0 --with-compiler="$(TEST_HC)" --ghc-options='$(filter-out -rtsopts,$(TEST_HC_OPTS))' --with-hc-pkg="$(GHC_PKG)" --package-db=../$(LOCAL_PKGCONF) cd boolean && ./Setup build -v0 cd boolean && ./Setup register -v0 --inplace "$(TEST_HC)" $(TEST_HC_OPTS) -c T13350.hs -package-db $(LOCAL_PKGCONF) ===================================== testsuite/tests/rts/Makefile ===================================== @@ -82,7 +82,7 @@ T10296a: .PHONY: T11788 T11788: - "$(TEST_HC)" -c T11788.c -o T11788_obj.o + "$(TEST_HC)" $(TEST_HC_OPTS) -c T11788.c -o T11788_obj.o "$(AR)" rsT libT11788.a T11788_obj.o 2> /dev/null echo main | "$(TEST_HC)" $(filter-out -rtsopts, $(TEST_HC_OPTS_INTERACTIVE)) T11788.hs -lT11788 -L"$(PWD)" @@ -101,13 +101,13 @@ T14695: .PHONY: InternalCounters InternalCounters: - "$(TEST_HC)" +RTS -s --internal-counters -RTS 2>&1 | grep "Internal Counters" - -"$(TEST_HC)" +RTS -s -RTS 2>&1 | grep "Internal Counters" + "$(TEST_HC)" $(TEST_HC_OPTS) +RTS -s --internal-counters -RTS 2>&1 | grep "Internal Counters" + -"$(TEST_HC)" $(TEST_HC_OPTS) +RTS -s -RTS 2>&1 | grep "Internal Counters" .PHONY: KeepCafsFail KeepCafsFail: - "$(TEST_HC)" -c -g -v0 KeepCafsBase.hs KeepCafs1.hs KeepCafs2.hs - "$(TEST_HC)" -g -v0 KeepCafsMain.hs KeepCafsBase.o -debug -rdynamic -fwhole-archive-hs-libs $(KEEPCAFS) + "$(TEST_HC)" $(TEST_HC_OPTS) -c -g -v0 KeepCafsBase.hs KeepCafs1.hs KeepCafs2.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -g -v0 KeepCafsMain.hs KeepCafsBase.o -debug -rdynamic -fwhole-archive-hs-libs $(KEEPCAFS) ./KeepCafsMain 2>&1 || echo "exit($$?)" .PHONY: KeepCafs @@ -116,37 +116,37 @@ KeepCafs: .PHONY: EventlogOutput1 EventlogOutput1: - "$(TEST_HC)" -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -v0 EventlogOutput.hs ./EventlogOutput +RTS -l -olhello.eventlog ls hello.eventlog >/dev/null .PHONY: EventlogOutput2 EventlogOutput2: - "$(TEST_HC)" -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -v0 EventlogOutput.hs ./EventlogOutput +RTS -l ls EventlogOutput.eventlog >/dev/null .PHONY: EventlogOutputNull EventlogOutputNull: - "$(TEST_HC)" -rtsopts -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -rtsopts -v0 EventlogOutput.hs ./EventlogOutput +RTS -l --null-eventlog-writer test ! -e EventlogOutput.eventlog .PHONY: T20199 T20199: - "$(TEST_HC)" -no-hs-main -optcxx-std=c++11 -v0 T20199.cpp -o T20199 + "$(TEST_HC)" $(TEST_HC_OPTS) -no-hs-main -optcxx-std=c++11 -v0 T20199.cpp -o T20199 ./T20199 .PHONY: EventlogOutput_IPE EventlogOutput_IPE: - "$(TEST_HC)" -debug -finfo-table-map -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -debug -finfo-table-map -v0 EventlogOutput.hs ./EventlogOutput +RTS -va 2> EventlogOutput_IPE.stderr.log grep "IPE:" EventlogOutput_IPE.stderr.log .PHONY: T23142 T23142: # Test that the -Di output contains different frames - "$(TEST_HC)" --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log + "$(TEST_HC)" $(TEST_HC_OPTS) --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log grep -m1 -c "ATOMICALLY_FRAME" T23142.log grep -m1 -c "CATCH_RETRY_FRAME" T23142.log grep -m1 -c "CATCH_STM_FRAME" T23142.log ===================================== testsuite/tests/rts/T1791/Makefile ===================================== @@ -3,4 +3,4 @@ include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk T1791: - '$(TEST_HC)' T1791.hs -o T1791 -O -rtsopts + '$(TEST_HC)' $(TEST_HC_OPTS) T1791.hs -o T1791 -O -rtsopts ===================================== testsuite/tests/wasm/should_run/control-flow/WasmControlFlow.hs ===================================== @@ -41,6 +41,7 @@ main = do `xopt_set` LangExt.StandaloneKindSignatures `xopt_set` LangExt.UnliftedDatatypes `xopt_set` LangExt.DataKinds + `dopt_set` Opt_D_no_debug_output setSessionDynFlags dflags groups <- mapM loadPath files liftIO $ do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c6992fbd5e50a8ffdc90a2d3707d3ae169441bb...88e174ff8cf11589ef6106cc481d1f7dad284a6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c6992fbd5e50a8ffdc90a2d3707d3ae169441bb...88e174ff8cf11589ef6106cc481d1f7dad284a6c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 14:56:32 2025 From: gitlab at gitlab.haskell.org (Jens Petersen (@juhp)) Date: Fri, 24 Jan 2025 09:56:32 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/juhp-hp2ps-fixup Message-ID: <6793aa205214e_33c5b94dfa309734e@gitlab.mail> Jens Petersen pushed new branch wip/juhp-hp2ps-fixup at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/juhp-hp2ps-fixup You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 14:59:27 2025 From: gitlab at gitlab.haskell.org (Jens Petersen (@juhp)) Date: Fri, 24 Jan 2025 09:59:27 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/juhp-hp2ps-fixup2 Message-ID: <6793aacfc82ee_33c5b95467a8975b0@gitlab.mail> Jens Petersen pushed new branch wip/juhp-hp2ps-fixup2 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/juhp-hp2ps-fixup2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 15:19:14 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Fri, 24 Jan 2025 10:19:14 -0500 Subject: [Git][ghc/ghc][wip/T24359] 2 commits: wip 2 Message-ID: <6793af724fcb0_35f386c0580413a7@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 5ee12fb7 by sheaf at 2025-01-23T14:30:29+01:00 wip 2 - - - - - 3d52add4 by sheaf at 2025-01-24T16:17:18+01:00 first attempt at new approach for specialise expression - - - - - 9 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs - hie.yaml Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Utils.Misc ((<||>)) import Data.Function import Data.List (sortBy) import Data.Data (Data) +import GHC.Data.Bag (Bag) {- ************************************************************************ @@ -824,7 +825,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +836,51 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_expr :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + , spe_rule_binds :: TcEvBinds + -- ^ "RULE RHS evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_evvars :: [Var] + -- ^ "specialised call evidence variables" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_binds :: (TcEvBinds, Bag EvBind) + -- ^ "specialised call evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] @@ -996,7 +1028,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,6 +791,9 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SLD TODO: rewrite this whole note, using the same example as +Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. + Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -823,7 +826,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,88 +924,72 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_expr = the_call + , spe_rule_binds = EvBinds rule_evbinds + -- BLUE bindings, let sd1 = d1, sd3 = d3 + , spe_call_evvars = rule_evvars + -- RED dictionary binders d1, ..., d4 + , spe_call_binds = (EvBinds non_quant_call_evbinds, call_evbinds) + -- RED bindings d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig = do { ds_call <- zapUnspecables $ -- zapUnspecables: see dsLExpr the_call -- Note [Desugaring RULE left hand sides] - -- Simplify the (desugared) call; see wrinkle (SP1) - -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - - ; case prepareSpecLHS poly_id bndrs core_call of { - Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - - Just (bndr_set, spec_const_binds, lhs_args) -> - - do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) - all_bndrs = bndr_set `unionVarSet` const_bndrs - -- all_bndrs: all binders in core_call that should be quantified - - -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] - rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) - spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs - - mk_spec_body fn_body = mkLets spec_const_binds $ - mkCoreApps fn_body lhs_args - - ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id - , text "bndrs" <+> ppr bndrs - , text "all_bndrs" <+> ppr all_bndrs - , text "const_bndrs" <+> ppr const_bndrs - , text "ds_call" <+> ppr ds_call - , text "core_call" <+> ppr core_call - , text "core_call fvs" <+> ppr (exprFreeVars core_call) - , text "spec_const_binds" <+> ppr spec_const_binds ]) - + ; let + simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + (_, rule_lhs_args) = collectArgs ds_call + + -- Yes, this is correct (rule_evvars defined using call_evbinds, + -- and spec_evvars defined using rule_evbinds) + spec_evvars = + map evBindVar (bagToList rule_evbinds) + + -- The rule binders, including the RED binders d1, ..., d4 + rule_bndrs = scopedSort $ + bndrs ++ rule_evvars + -- The specialised $sf binders, including the BLUE binders sd1, sd2 + spec_bndrs = scopedSort $ + bndrs ++ spec_evvars + + spec_evbinds = + non_quant_call_evbinds `unionBags` call_evbinds + + ; spec_coreevbinds <- dsEvBinds spec_evbinds return + + ; let + mk_spec_body spec_fun = + mkLets spec_coreevbinds $ + mkCoreApps spec_fun rule_lhs_args + + ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id + , text "bndrs:" <+> ppr bndrs + , text "ds_call:" <+> ppr ds_call + , text "core_call:" <+> ppr core_call + , text "rule_evbinds:" <+> ppr rule_evbinds + , text "non_quant_call_evbinds:" <+> ppr non_quant_call_evbinds + , text "call_evbinds:" <+> ppr call_evbinds + , text (replicate 40 '-') + , text "rule_evvars:" <+> ppr rule_evvars + , text "spec_evvars:" <+> ppr spec_evvars + , text "rule_bndrs:" <+> ppr rule_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_coreevbinds:" <+> ppr spec_coreevbinds + , text "rule_lhs_args:" <+> ppr rule_lhs_args + ]) ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id lhs_args - spec_bndrs mk_spec_body inl } } } - -prepareSpecLHS :: Id -> [EvVar] -> CoreExpr - -> Maybe (VarSet, [CoreBind], [CoreExpr]) --- See (SP2) in Note [Desugaring SPECIALISE pragmas] -prepareSpecLHS poly_id evs the_call - = go (mkVarSet evs) [] the_call - where - go :: VarSet -- Quantified variables, or dependencies thereof - -> [CoreBind] -- Reversed list of constant evidence bindings - -> CoreExpr - -> Maybe (IdSet, [CoreBind], [CoreExpr]) - go qevs acc (Cast e _) - = go qevs acc e - go qevs acc (Let bind e) - | not (all isDictId bndrs) -- A normal 'let' is too complicated - = Nothing - - | all (transfer_to_spec_rhs qevs) $ - rhssOfBind bind -- One of the `const_binds` - = go qevs (bind:acc) e - - | otherwise - = go (qevs `extendVarSetList` bndrs) acc e - where - bndrs = bindersOf bind + rule_bndrs poly_id rule_lhs_args + spec_bndrs mk_spec_body inl - go qevs acc e - | (Var fun, args) <- collectArgs e - = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just (qevs, reverse acc, args) - | otherwise - = Nothing - - transfer_to_spec_rhs qevs rhs - = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) - where - is_quant_id v = isId v && v `elemVarSet` qevs - -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + } +dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern @@ -1054,7 +1041,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS, runTcSWithEvBinds ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -703,32 +703,112 @@ Note [Handling new-form SPECIALISE pragmas] New-form SPECIALISE pragmas are described by GHC Proposal #493. The pragma takes the form of a function application, possibly with intervening -parens and type signatures, with a variable at the head. It may have rule -for-alls at the top. e.g. +parens and type signatures, with a variable at the head: {-# SPECIALISE f1 @Int 3 #-} - {-# SPECIALISE forall x xs. f2 (x:xs) #-} - {-# SPECIALISE f3 :: Int -> Int #-} - {-# SPECIALISE (f4 :: Int -> Int) 5 #-} + {-# SPECIALISE f2 :: Int -> Int #-} + {-# SPECIALISE (f3 :: Int -> Int) 5 #-} + +It may also have rule for-alls at the top, e.g. + + {-# SPECIALISE forall x xs. f4 (x:xs) #-} {-# SPECIALISE forall a. forall x xs. f5 @a @a (x:xs) #-} See `GHC.Rename.Bind.checkSpecESigShape` for the shape-check. +We are going to use the following (perhaps somewhat contrived) example to +demonstrate the subtle aspects of the implementation: -Example: - f :: forall a b. (Eq a, Eq b, Eq c) => a -> b -> c -> Bool -> blah - {-# SPECIALISE forall x y. f (x::Int) y y True #-} - -- y::p + f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} We want to generate: - RULE forall @p (d1::Eq Int) (d2::Eq p) (d3::Eq p) (x::Int) (y::p). - f @Int @p @p d1 d2 d3 x y y True - = $sf @p d2 x y - $sf @p (d2::Eq p) (x::Int) (y::p) - = let d1 = $fEqInt - d3 = d2 - in @p @p @Int (d1::Eq p) (d2::Eq p) (d3::Eq p) x y y True + RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True + = let + sd1 = d2 -- We will refer to these as the + sd2 = d4 -- "RULE RHS evidence bindings" + in + $sf @p @q sd1 sd2 x y z + $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) + = let(non-rec) f = in + let + d1 = $fEqList $fEqInt -- + d2 = sd1 -- We will refer to these as the + d3 = sd1 -- "specialised call evidence bindings" + d4 = sd2 -- + in + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True + +Key observations: + + O1. + + The most important part is to **completely solve** the Eq [Int] constraint, + so that we specialise the call to 'f' to a known dictionary. Without that, + we're not doing any typeclass specialisation! + + O2. + + The `rule_bndrs`, over which the RULE is quantified, are all the variables + free in the call to `f`, /ignoring/ all dictionary simplification. Why? + Because we want to make the rule maximally applicable; provided the types + match, the dictionaries should match. This is why, in the above example, + the rule binders are: + + rule_bndrs = @p @q + (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) + (x::[Int]) (y::p) (z::q). + + Note that: + + - We have separate binders for `d2` and `d3` even though they are + the same (Eq p) dictionary. Reason: we don't want to force them to be + visibly equal at the call site. + + - We don't assume that the dictionary for 'Eq [q]' was obtained + from the top-level instance 'instance Eq x => Eq [x]'. If we did that, + e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: + + - generate a RULE of the form + + forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... + + which is verboten (it matches on the structure of a dictionary), or + + - "run the instance in reverse" to extract evidence for + (Eq q) from (Eq [q]), which is impossible to do in general. + + "Partially solving" the Eq [q] constraint by using the instance doesn't + buy us anything; we can't do anything useful with the information that an + Eq [q] dictionary is of the form ($fEqList ..). + + To achieve this, we solve the constraints that originated from typechecking + the expression to specialise, but in the special 'TcSSpecPrag' mode, which + ensures that: + + - We don't use instances (whether top-level instances or local instances + from quantified constraints), as those are not "reversible", + - EXCEPT that we **do** use the short-cut solver, so that we can fully + solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). + + O3. + + In the body of $sf, note that we: + + - define 'let(non-rec) f = ' + - refer to this shadowing 'f' in the last line of $sf + + This allows us to deal with functions that recursively call themselves, + as opposed to simply writing + + $sf ... = + let + in + () @p @p @[q] d1 d2 d3 d4 x y y [z] True + + Note that @@ -757,7 +837,7 @@ Note that How it works: -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results +* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results into a `SpecPragE` record. Nothing very exciting happens here. * `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any @@ -771,7 +851,7 @@ How it works: it should look like let in f e1 e1 e3 - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards + * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards the other dictionary bindings, and decomposes the call. * Then it can build the RULE and specialised function. @@ -944,49 +1024,85 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) - = do { -- Typecheck the expression, spec_e, capturing its constraints + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] + = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) ; skol_info <- mkSkolemInfo skol_info_anon - ; (rhs_tclvl, wanted, (rule_bndrs', (spec_e', _rho))) + ; (rhs_tclvl, wanted, (rule_bndrs', (tc_spec_e, _rho))) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- Simplify the constraints enough to perform unificaitons + -- (2) Perform unifications: + -- - clone the original constraints, + -- - simplify these cloned constraints + -- - zonk the original constraints ; wanted_clone <- cloneWC wanted ; _ <- setTcLevel rhs_tclvl $ runTcS $ solveWanteds wanted_clone ; wanted <- liftZonkM $ zonkWC wanted - -- Quantify over the the constraints - ; (quant_cts, residual_wanted) <- getRuleQuantCts wanted + -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) + ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted ; let qevs = map ctEvId (bagToList quant_cts) - -- Wrap the call in bindings for any other constraints - ; ev_binds_var1 <- newTcEvBinds + -- (4) Emit the residual constraints. + ; non_quant_binds <- newTcEvBinds ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var1 + ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds emptyVarSet tv_bndrs qevs - residual_wanted - ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var1)) spec_e' - -- The free vars of `lhs_call` are `qevs`, plus the explicit `rule_bndrs` - -- and any free tyvars of the above - - ; - ; traceTc "tcSpecPrag:SpecSigE" $ + non_quant_wc + + -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) + -- by solving "quant_cts" in the special TcSSpecPrag mode + ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ + vcat [ text "quant_cts:" <+> ppr quant_cts ] + ; (rule_rhs_wc, spec_call_binds) + <- setTcLevel rhs_tclvl $ + runTcSSpecPrag $ + solveWanteds (emptyWC { wc_simple = quant_cts }) + ; let rule_rhs_implics = wc_impl rule_rhs_wc + ; massertPpr (null rule_rhs_implics) $ + vcat [ text "tcSpecPrag: unexpected non-simple constraints" + , text "quant_cts:" <+> ppr quant_cts + , text "implics:" <+> ppr rule_rhs_implics ] + ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ + vcat [ text "quant_cts:" <+> ppr quant_cts + , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] + + -- (6) Figure out the blue bindings by solving the implication + -- [G] d1, d2, d3, d4 => [W] sd1, sd2 + ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ + vcat [ text "qevs:" <+> ppr qevs + , text "rule_rhs_wc:" <+> ppr rule_rhs_wc + ] + ; (implics, rule_rhs_binds) <- + buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs + qevs -- d1, d2, d3, d4 + rule_rhs_wc -- sd1, sd2 + ; emitImplications implics + + ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs - , text "spec_e:" <+> ppr spec_e' - , text "inl:" <+> ppr inl ] + , text "spec_e:" <+> ppr tc_spec_e + , text "inl:" <+> ppr inl + , text "non_quant:" <+> ppr non_quant_wc + , text (replicate 40 '-') + , text "spec_call_binds:" <+> ppr spec_call_binds + ] - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order - -- does not matter - , spe_call = lhs_call - , spe_inl = inl }] } + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = rule_bndrs' + , spe_expr = tc_spec_e + , spe_rule_binds = rule_rhs_binds + , spe_call_evvars = qevs + , spe_call_binds = (TcEvBinds non_quant_binds, spec_call_binds) + }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) @@ -1419,9 +1535,9 @@ in `getRuleQuantCts`. Why not? * Equality constraints are unboxed, and that leads to complications For example equality constraints from the LHS will emit coercion hole Wanteds. These don't have a name, so we can't quantify over them directly. - Instead, in `mk_one` in `getRuleQuantCts` in we'd have to invent a new EvVar - for the coercion, fill the hole with the invented EvVar, and then quantify - over the EvVar. Here is old code from `mk_one` + Instead, in `getRuleQuantCts`, we'd have to invent a new EvVar for the + coercion, fill the hole with the invented EvVar, and then quantify over the + EvVar. Here is old code from `mk_one` do { ev_id <- newEvVar pred ; fillCoercionHole hole (mkCoVarCo ev_id) ; return ev_id } @@ -1488,8 +1604,8 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; lhs_wanted <- liftZonkM $ zonkWC lhs_wanted -- Note [The SimplifyRule Plan] step 3 - ; (quant_cts, residual_lhs_wanted) <-getRuleQuantCts lhs_wanted - ; let qant_evs = map ctEvId (bagToTolist quant_cts) + ; (quant_cts, residual_lhs_wanted) <- getRuleQuantCts lhs_wanted + ; let quant_evs = map ctEvId (bagToList quant_cts) ; traceTc "simplifyRule" $ vcat [ text "LHS of rule" <+> doubleQuotes (ftext name) @@ -1510,16 +1626,16 @@ getRuleQuantCts :: WantedConstraints -> TcM (Cts, WantedConstraints) -- and attempt to solve them from the quantified constraints. Instead -- we /partition/ the WantedConstraints into ones to quantify and ones -- we can't quantify. We could use approximateWC instead, and leave --- `wanted` unchanged; but then we'd have clone fresh binders and +-- `wanted` unchanged; but then we'd have to clone fresh binders and -- generate silly identity bindings. Seems more direct to do this. --- Probably not a big eal wither way. +-- Probably not a big deal wither way. -- -- NB: we must look inside implications, because with -- -fdefer-type-errors we generate implications rather eagerly; -- see GHC.Tc.Utils.Unify.implicationNeeded. Not doing so caused #14732. getRuleQuantCts wc - = float_wc emptyVarSet wc + = return $ float_wc emptyVarSet wc where float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_errors = errs }) @@ -1545,17 +1661,6 @@ getRuleQuantCts wc EqPred {} -> False -- Note [RULE quantification over equalities] _ -> tyCoVarsOfCt ct `disjointVarSet` skol_tvs - mk_one :: Ct -> TcM EvVar - mk_one ct - | CtWanted { ctev_dest = dest } <- ctEvidence ct - , EvVarDest ev_id <- dest - -- HoleDest can't happen because we don't quantify - -- over EqPred: See rule_quant_ct above - = return ev_id - - | otherwise - = pprPanic "getRuleQuantCts" (ppr ct) - {- Note [Quantifying over equalities in RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -727,7 +727,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +757,37 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] + , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +803,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -886,7 +892,18 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls | otherwise -- Wanted, but not cached = do { dflags <- getDynFlags ; mode <- getModeTcS - ; lkup_res <- matchClassInst dflags mode inerts cls xis dict_loc + ; case mode of + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + { TcSSpecPrag -> + do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" + else continueWith () + } + ; _ -> + do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc ; case lkup_res of OneInst { cir_what = what } -> do { insertSafeOverlapFailureTcS what work_item @@ -894,7 +911,7 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls ; chooseInstance ev lkup_res } _ -> -- NoInstance or NotSure -- We didn't solve it; so try functional dependencies - continueWith () } + continueWith () } } } where dict_loc = ctEvLoc ev @@ -941,13 +958,11 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> TcSMode +matchClassInst :: DynFlags -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult -matchClassInst dflags mode inerts clas tys loc - | TcSSpecPrag <- mode -- See Note [Handling new-form SPECIALISE pragmas] - = return NoInstance -- in GHc.Tc.Gen.Sig +matchClassInst dflags inerts clas tys loc -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -851,12 +851,13 @@ data TcSEnv data TcSMode = TcSVanilla - | TcSHoleFits -- See Note [Speeding up valid hole-fits]. - -- In this moe we throw an exception if we come across an - -- insoluble constraint, to fail-fast when checking for hole-fits. + | TcSHoleFits -- ^ Throw an exception if we come across an insoluble constraint, + -- to fail-fast when checking for hole-fits. + -- + -- See Note [Speeding up valid hole-fits]. - | TcSSpecPrag -- Don't use instance declarations or upack forall constraints - -- when simplifying a SPECIALISE pragma + | TcSSpecPrag -- ^ Don't use instance declarations or unpack forall constraints; + -- used when simplifying a SPECIALISE pragma. deriving( Eq ) instance Outputable TcSMode where @@ -996,7 +997,7 @@ runTcSWithEvBinds = runTcSWorker True TcSVanilla runTcS :: TcS a -> TcM (a, EvBindMap) runTcS tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; res <- runTcSWorker True TcSVanilla aev_binds_var tcs + ; res <- runTcSWorker True TcSVanilla ev_binds_var tcs ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var ; return (res, ev_binds) } @@ -1006,7 +1007,7 @@ runTcS tcs runTcSEarlyAbort :: TcS a -> TcM a runTcSEarlyAbort tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; runTcSWorker' True TcSHoleFits ev_binds_var tcs } + ; runTcSWorker True TcSHoleFits ev_binds_var tcs } -- | This can deal only with equality constraints. runTcSEqualities :: TcS a -> TcM a @@ -1018,16 +1019,16 @@ runTcSEqualities thing_inside runTcSSpecPrag :: TcS a -> TcM (a, Bag EvBind) runTcSSpecPrag thing_inside = do { ev_binds_var <- TcM.newTcEvBinds - ; res <- runTcSWorker True TcSSpecPrag ev_binds_var tcs + ; res <- runTcSWorker True TcSSpecPrag ev_binds_var thing_inside ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var ; return (res, evBindMapBinds ev_binds) } -- | A variant of 'runTcS' that takes and returns an 'InertSet' for -- later resumption of the 'TcS' session. runTcSInerts :: InertSet -> TcS a -> TcM (a, InertSet) -runTcSInerts inerts tcs = do +runTcSInerts inerts tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; runTcWorker False TcSVanilla ev_binds_var $ + ; runTcSWorker False TcSVanilla ev_binds_var $ do { setInertSet inerts ; a <- tcs ; new_inerts <- getInertSet ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,20 +854,32 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = spec_e })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_expr = spec_e + , spe_rule_binds = rule_evbinds + , spe_call_evvars = call_evvars + , spe_call_binds = (non_quant_evbinds, call_evbinds) })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> + runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> + runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> + runZonkBndrT (zonkTcEvBinds non_quant_evbinds) $ \ non_quant_evbinds' -> + runZonkBndrT (zonkEvBinds call_evbinds) $ \ call_evbinds' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_expr = spec_e' + , spe_rule_binds = rule_evbinds' + , spe_call_evvars = call_evvars' + , spe_call_binds = (non_quant_evbinds', call_evbinds') + })) + }} {- ************************************************************************ ===================================== hie.yaml ===================================== @@ -5,4 +5,4 @@ # cradle: {bios: {program: "./hadrian/hie-bios.bat"}} # # The format is documented here - https://github.com/mpickering/hie-bios -cradle: {bios: {program: "./hadrian/hie-bios"}} +cradle: {bios: {program: "./hadrian/hie-bios.bat"}} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/32e0aa0571ac34032426a94b8f2f1be10002bdd9...3d52add4d0f8def6818adad064f129eca62afa6f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/32e0aa0571ac34032426a94b8f2f1be10002bdd9...3d52add4d0f8def6818adad064f129eca62afa6f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 15:27:54 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Fri, 24 Jan 2025 10:27:54 -0500 Subject: [Git][ghc/ghc][wip/T24359] first attempt at new approach for specialise expression Message-ID: <6793b179f1ec4_35f386c09184421b@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: e6f37f8a by sheaf at 2025-01-24T16:27:39+01:00 first attempt at new approach for specialise expression - - - - - 7 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Utils.Misc ((<||>)) import Data.Function import Data.List (sortBy) import Data.Data (Data) +import GHC.Data.Bag (Bag) {- ************************************************************************ @@ -824,7 +825,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +836,51 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_expr :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + , spe_rule_binds :: TcEvBinds + -- ^ "RULE RHS evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_evvars :: [Var] + -- ^ "specialised call evidence variables" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_binds :: (TcEvBinds, Bag EvBind) + -- ^ "specialised call evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] @@ -996,7 +1028,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,6 +791,9 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SLD TODO: rewrite this whole note, using the same example as +Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. + Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -823,7 +826,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,88 +924,78 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_expr = the_call + + -- BLUE bindings (let sd1 = d1, sd3 = d3) + , spe_rule_binds = EvBinds rule_evbinds + + -- RED binders (d1,..., d4) + , spe_call_evvars = rule_evvars + -- RED evidence binds (d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ...) + , spe_call_binds = (EvBinds non_quant_call_evbinds, call_evbinds) + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig = do { ds_call <- zapUnspecables $ -- zapUnspecables: see dsLExpr the_call -- Note [Desugaring RULE left hand sides] - -- Simplify the (desugared) call; see wrinkle (SP1) - -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - - ; case prepareSpecLHS poly_id bndrs core_call of { - Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - - Just (bndr_set, spec_const_binds, lhs_args) -> - - do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) - all_bndrs = bndr_set `unionVarSet` const_bndrs - -- all_bndrs: all binders in core_call that should be quantified - - -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] - rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) - spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs - - mk_spec_body fn_body = mkLets spec_const_binds $ - mkCoreApps fn_body lhs_args - - ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id - , text "bndrs" <+> ppr bndrs - , text "all_bndrs" <+> ppr all_bndrs - , text "const_bndrs" <+> ppr const_bndrs - , text "ds_call" <+> ppr ds_call - , text "core_call" <+> ppr core_call - , text "core_call fvs" <+> ppr (exprFreeVars core_call) - , text "spec_const_binds" <+> ppr spec_const_binds ]) - + ; let + simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + (_, rule_lhs_args) = collectArgs ds_call + + -- BLUE binders, in correspondence with the LHS of the blue bindings + spec_evvars = + map evBindVar (bagToList rule_evbinds) + -- Yes: rule_evbinds and not call_evbinds. + -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] + -- if this is not clear. + + -- The rule binders, including the RED binders d1, ..., d4 + rule_bndrs = scopedSort $ + bndrs ++ rule_evvars + -- The specialised $sf binders, including the BLUE binders sd1, sd2 + spec_bndrs = scopedSort $ + bndrs ++ spec_evvars + + spec_evbinds = + non_quant_call_evbinds `unionBags` call_evbinds + + ; spec_coreevbinds <- dsEvBinds spec_evbinds return + + ; let + mk_spec_body spec_fun = + mkLets spec_coreevbinds $ + mkCoreApps spec_fun rule_lhs_args + + ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id + , text "bndrs:" <+> ppr bndrs + , text "ds_call:" <+> ppr ds_call + , text "core_call:" <+> ppr core_call + , text "rule_evbinds:" <+> ppr rule_evbinds + , text "non_quant_call_evbinds:" <+> ppr non_quant_call_evbinds + , text "call_evbinds:" <+> ppr call_evbinds + , text (replicate 40 '-') + , text "rule_evvars:" <+> ppr rule_evvars + , text "spec_evvars:" <+> ppr spec_evvars + , text "rule_bndrs:" <+> ppr rule_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_coreevbinds:" <+> ppr spec_coreevbinds + , text "rule_lhs_args:" <+> ppr rule_lhs_args + ]) ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id lhs_args - spec_bndrs mk_spec_body inl } } } - -prepareSpecLHS :: Id -> [EvVar] -> CoreExpr - -> Maybe (VarSet, [CoreBind], [CoreExpr]) --- See (SP2) in Note [Desugaring SPECIALISE pragmas] -prepareSpecLHS poly_id evs the_call - = go (mkVarSet evs) [] the_call - where - go :: VarSet -- Quantified variables, or dependencies thereof - -> [CoreBind] -- Reversed list of constant evidence bindings - -> CoreExpr - -> Maybe (IdSet, [CoreBind], [CoreExpr]) - go qevs acc (Cast e _) - = go qevs acc e - go qevs acc (Let bind e) - | not (all isDictId bndrs) -- A normal 'let' is too complicated - = Nothing - - | all (transfer_to_spec_rhs qevs) $ - rhssOfBind bind -- One of the `const_binds` - = go qevs (bind:acc) e - - | otherwise - = go (qevs `extendVarSetList` bndrs) acc e - where - bndrs = bindersOf bind + rule_bndrs poly_id rule_lhs_args + spec_bndrs mk_spec_body inl - go qevs acc e - | (Var fun, args) <- collectArgs e - = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just (qevs, reverse acc, args) - | otherwise - = Nothing - - transfer_to_spec_rhs qevs rhs - = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) - where - is_quant_id v = isId v && v `elemVarSet` qevs - -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + } +dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern @@ -1054,7 +1047,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -720,26 +720,26 @@ We are going to use the following (perhaps somewhat contrived) example to demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah - {-# SPECIALISE forall x y z. f (x::[Int]) y y [z] True #-} + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} We want to generate: - RULE forall @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::Int) (y::p) (z :: q). - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True = let - sd1 = d2 -- - sd2 = d4 -- (*) + sd1 = d2 -- We will refer to these as the + sd2 = d4 -- "RULE RHS evidence bindings" in $sf @p @q sd1 sd2 x y z - $sf @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Int]) (y::p) (z :: q) + $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) = let(non-rec) f = in let d1 = $fEqList $fEqInt -- - d2 = sd1 -- - d3 = sd1 -- - d4 = sd2 -- (**) + d2 = sd1 -- We will refer to these as the + d3 = sd1 -- "specialised call evidence bindings" + d4 = sd2 -- in - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True Key observations: @@ -754,7 +754,8 @@ Key observations: The `rule_bndrs`, over which the RULE is quantified, are all the variables free in the call to `f`, /ignoring/ all dictionary simplification. Why? Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. + match, the dictionaries should match. This is why, in the above example, + the rule binders are: rule_bndrs = @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) @@ -768,20 +769,31 @@ Key observations: - We don't assume that the dictionary for 'Eq [q]' was obtained from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - with a rule binder (d4 :: Eq q), we would either have to: + e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - generate a RULE LHS of the form + - generate a RULE of the form - forall ... @q (d5 :: Eq q). f d1 d2 d3 ($fEqList d5) + forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - find a way to "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]). + which is verboten (it matches on the structure of a dictionary), or + + - "run the instance in reverse" to extract evidence for + (Eq q) from (Eq [q]), which is impossible to do in general. "Partially solving" the Eq [q] constraint by using the instance doesn't buy us anything; we can't do anything useful with the information that an Eq [q] dictionary is of the form ($fEqList ..). - O4. + To achieve this, we solve the constraints that originated from typechecking + the expression to specialise, but in the special 'TcSSpecPrag' mode, which + ensures that: + + - We don't use instances (whether top-level instances or local instances + from quantified constraints), as those are not "reversible", + - EXCEPT that we **do** use the short-cut solver, so that we can fully + solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). + + O3. In the body of $sf, note that we: @@ -825,7 +837,7 @@ Note that How it works: -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results +* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results into a `SpecPragE` record. Nothing very exciting happens here. * `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any @@ -839,7 +851,7 @@ How it works: it should look like let in f e1 e1 e3 - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards + * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards the other dictionary bindings, and decomposes the call. * Then it can build the RULE and specialised function. @@ -1012,6 +1024,7 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) @@ -1031,33 +1044,65 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) ; wanted <- liftZonkM $ zonkWC wanted -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, residual_wanted) <- getRuleQuantCts wanted + ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted ; let qevs = map ctEvId (bagToList quant_cts) - -- (4) Emit the residual constraints, and wrap the call in the appropriate - -- bindings. - ; ev_binds_var1 <- newTcEvBinds + -- (4) Emit the residual constraints. + ; non_quant_binds <- newTcEvBinds ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var1 + ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds emptyVarSet tv_bndrs qevs - residual_wanted - ; let residual_wrap = mkLHsWrap (WpLet (TcEvBinds ev_binds_var1)) - -- The free vars in this wrapper are `qevs`, plus the explicit `rule_bndrs` - -- and any free tyvars of the above. - - ; traceTc "tcSpecPrag:SpecSigE" $ + non_quant_wc + + -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) + -- by solving "quant_cts" in the special TcSSpecPrag mode + ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ + vcat [ text "quant_cts:" <+> ppr quant_cts ] + ; (rule_rhs_wc, spec_call_binds) + <- setTcLevel rhs_tclvl $ + runTcSSpecPrag $ + solveWanteds (emptyWC { wc_simple = quant_cts }) + ; let rule_rhs_implics = wc_impl rule_rhs_wc + ; massertPpr (null rule_rhs_implics) $ + vcat [ text "tcSpecPrag: unexpected non-simple constraints" + , text "quant_cts:" <+> ppr quant_cts + , text "implics:" <+> ppr rule_rhs_implics ] + ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ + vcat [ text "quant_cts:" <+> ppr quant_cts + , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] + + -- (6) Figure out the blue bindings by solving the implication + -- [G] d1, d2, d3, d4 => [W] sd1, sd2 + ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ + vcat [ text "qevs:" <+> ppr qevs + , text "rule_rhs_wc:" <+> ppr rule_rhs_wc + ] + ; (implics, rule_rhs_binds) <- + buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs + qevs -- d1, d2, d3, d4 + rule_rhs_wc -- sd1, sd2 + ; emitImplications implics + + ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order - -- does not matter - , spe_call = lhs_call - , spe_inl = inl }] } + , text "inl:" <+> ppr inl + , text "non_quant:" <+> ppr non_quant_wc + , text (replicate 40 '-') + , text "spec_call_binds:" <+> ppr spec_call_binds + ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = rule_bndrs' + , spe_expr = tc_spec_e + , spe_rule_binds = rule_rhs_binds + , spe_call_evvars = qevs + , spe_call_binds = (TcEvBinds non_quant_binds, spec_call_binds) + }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -727,7 +727,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +757,37 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] + , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +803,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -886,7 +892,18 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls | otherwise -- Wanted, but not cached = do { dflags <- getDynFlags ; mode <- getModeTcS - ; lkup_res <- matchClassInst dflags mode inerts cls xis dict_loc + ; case mode of + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + { TcSSpecPrag -> + do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" + else continueWith () + } + ; _ -> + do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc ; case lkup_res of OneInst { cir_what = what } -> do { insertSafeOverlapFailureTcS what work_item @@ -894,7 +911,7 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls ; chooseInstance ev lkup_res } _ -> -- NoInstance or NotSure -- We didn't solve it; so try functional dependencies - continueWith () } + continueWith () } } } where dict_loc = ctEvLoc ev @@ -941,13 +958,11 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> TcSMode +matchClassInst :: DynFlags -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult -matchClassInst dflags mode inerts clas tys loc - | TcSSpecPrag <- mode -- See Note [Handling new-form SPECIALISE pragmas] - = return NoInstance -- in GHc.Tc.Gen.Sig +matchClassInst dflags inerts clas tys loc -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,20 +854,32 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = spec_e })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_expr = spec_e + , spe_rule_binds = rule_evbinds + , spe_call_evvars = call_evvars + , spe_call_binds = (non_quant_evbinds, call_evbinds) })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> + runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> + runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> + runZonkBndrT (zonkTcEvBinds non_quant_evbinds) $ \ non_quant_evbinds' -> + runZonkBndrT (zonkEvBinds call_evbinds) $ \ call_evbinds' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_expr = spec_e' + , spe_rule_binds = rule_evbinds' + , spe_call_evvars = call_evvars' + , spe_call_binds = (non_quant_evbinds', call_evbinds') + })) + }} {- ************************************************************************ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6f37f8adcf49245233ae316014206636caae28c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e6f37f8adcf49245233ae316014206636caae28c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 15:33:22 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Fri, 24 Jan 2025 10:33:22 -0500 Subject: [Git][ghc/ghc][wip/T24359] first attempt at new approach for specialise expression Message-ID: <6793b2c2bec1c_35f3863b1e74473b7@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 4a63a80b by sheaf at 2025-01-24T16:33:04+01:00 first attempt at new approach for specialise expression - - - - - 8 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Utils.Misc ((<||>)) import Data.Function import Data.List (sortBy) import Data.Data (Data) +import GHC.Data.Bag (Bag) {- ************************************************************************ @@ -824,7 +825,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +836,51 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_expr :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + , spe_rule_binds :: TcEvBinds + -- ^ "RULE RHS evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_evvars :: [Var] + -- ^ "specialised call evidence variables" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_binds :: (TcEvBinds, Bag EvBind) + -- ^ "specialised call evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] @@ -996,7 +1028,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,6 +791,9 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SLD TODO: rewrite this whole note, using the same example as +Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. + Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -823,7 +826,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,88 +924,78 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_expr = the_call + + -- BLUE bindings (sd1 = d1, sd3 = d3) + , spe_rule_binds = EvBinds rule_evbinds + + -- RED binders (d1,..., d4) + , spe_call_evvars = rule_evvars + -- RED evidence binds (d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ...) + , spe_call_binds = (EvBinds non_quant_call_evbinds, call_evbinds) + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig = do { ds_call <- zapUnspecables $ -- zapUnspecables: see dsLExpr the_call -- Note [Desugaring RULE left hand sides] - -- Simplify the (desugared) call; see wrinkle (SP1) - -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - - ; case prepareSpecLHS poly_id bndrs core_call of { - Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - - Just (bndr_set, spec_const_binds, lhs_args) -> - - do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) - all_bndrs = bndr_set `unionVarSet` const_bndrs - -- all_bndrs: all binders in core_call that should be quantified - - -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] - rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) - spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs - - mk_spec_body fn_body = mkLets spec_const_binds $ - mkCoreApps fn_body lhs_args - - ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id - , text "bndrs" <+> ppr bndrs - , text "all_bndrs" <+> ppr all_bndrs - , text "const_bndrs" <+> ppr const_bndrs - , text "ds_call" <+> ppr ds_call - , text "core_call" <+> ppr core_call - , text "core_call fvs" <+> ppr (exprFreeVars core_call) - , text "spec_const_binds" <+> ppr spec_const_binds ]) - + ; let + simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + (_, rule_lhs_args) = collectArgs ds_call + + -- BLUE binders, in correspondence with the LHS of the blue bindings + spec_evvars = + map evBindVar (bagToList rule_evbinds) + -- Yes: rule_evbinds and not call_evbinds. + -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] + -- if this is not clear. + + -- The rule binders, including the RED binders d1, ..., d4 + rule_bndrs = scopedSort $ + bndrs ++ rule_evvars + -- The specialised $sf binders, including the BLUE binders sd1, sd2 + spec_bndrs = scopedSort $ + bndrs ++ spec_evvars + + spec_evbinds = + non_quant_call_evbinds `unionBags` call_evbinds + + ; spec_coreevbinds <- dsEvBinds spec_evbinds return + + ; let + mk_spec_body spec_fun = + mkLets spec_coreevbinds $ + mkCoreApps spec_fun rule_lhs_args + + ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id + , text "bndrs:" <+> ppr bndrs + , text "ds_call:" <+> ppr ds_call + , text "core_call:" <+> ppr core_call + , text "rule_evbinds:" <+> ppr rule_evbinds + , text "non_quant_call_evbinds:" <+> ppr non_quant_call_evbinds + , text "call_evbinds:" <+> ppr call_evbinds + , text (replicate 40 '-') + , text "rule_evvars:" <+> ppr rule_evvars + , text "spec_evvars:" <+> ppr spec_evvars + , text "rule_bndrs:" <+> ppr rule_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_coreevbinds:" <+> ppr spec_coreevbinds + , text "rule_lhs_args:" <+> ppr rule_lhs_args + ]) ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id lhs_args - spec_bndrs mk_spec_body inl } } } - -prepareSpecLHS :: Id -> [EvVar] -> CoreExpr - -> Maybe (VarSet, [CoreBind], [CoreExpr]) --- See (SP2) in Note [Desugaring SPECIALISE pragmas] -prepareSpecLHS poly_id evs the_call - = go (mkVarSet evs) [] the_call - where - go :: VarSet -- Quantified variables, or dependencies thereof - -> [CoreBind] -- Reversed list of constant evidence bindings - -> CoreExpr - -> Maybe (IdSet, [CoreBind], [CoreExpr]) - go qevs acc (Cast e _) - = go qevs acc e - go qevs acc (Let bind e) - | not (all isDictId bndrs) -- A normal 'let' is too complicated - = Nothing - - | all (transfer_to_spec_rhs qevs) $ - rhssOfBind bind -- One of the `const_binds` - = go qevs (bind:acc) e - - | otherwise - = go (qevs `extendVarSetList` bndrs) acc e - where - bndrs = bindersOf bind + rule_bndrs poly_id rule_lhs_args + spec_bndrs mk_spec_body inl - go qevs acc e - | (Var fun, args) <- collectArgs e - = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just (qevs, reverse acc, args) - | otherwise - = Nothing - - transfer_to_spec_rhs qevs rhs - = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) - where - is_quant_id v = isId v && v `elemVarSet` qevs - -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + } +dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern @@ -1054,7 +1047,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -720,26 +720,26 @@ We are going to use the following (perhaps somewhat contrived) example to demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah - {-# SPECIALISE forall x y z. f (x::[Int]) y y [z] True #-} + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} We want to generate: - RULE forall @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::Int) (y::p) (z :: q). - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True = let - sd1 = d2 -- - sd2 = d4 -- (*) + sd1 = d2 -- We will refer to these as the + sd2 = d4 -- "RULE RHS evidence bindings" in $sf @p @q sd1 sd2 x y z - $sf @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Int]) (y::p) (z :: q) + $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) = let(non-rec) f = in let d1 = $fEqList $fEqInt -- - d2 = sd1 -- - d3 = sd1 -- - d4 = sd2 -- (**) + d2 = sd1 -- We will refer to these as the + d3 = sd1 -- "specialised call evidence bindings" + d4 = sd2 -- in - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True Key observations: @@ -754,7 +754,8 @@ Key observations: The `rule_bndrs`, over which the RULE is quantified, are all the variables free in the call to `f`, /ignoring/ all dictionary simplification. Why? Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. + match, the dictionaries should match. This is why, in the above example, + the rule binders are: rule_bndrs = @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) @@ -768,20 +769,31 @@ Key observations: - We don't assume that the dictionary for 'Eq [q]' was obtained from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - with a rule binder (d4 :: Eq q), we would either have to: + e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - generate a RULE LHS of the form + - generate a RULE of the form - forall ... @q (d5 :: Eq q). f d1 d2 d3 ($fEqList d5) + forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - find a way to "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]). + which is verboten (it matches on the structure of a dictionary), or + + - "run the instance in reverse" to extract evidence for + (Eq q) from (Eq [q]), which is impossible to do in general. "Partially solving" the Eq [q] constraint by using the instance doesn't buy us anything; we can't do anything useful with the information that an Eq [q] dictionary is of the form ($fEqList ..). - O4. + To achieve this, we solve the constraints that originated from typechecking + the expression to specialise, but in the special 'TcSSpecPrag' mode, which + ensures that: + + - We don't use instances (whether top-level instances or local instances + from quantified constraints), as those are not "reversible", + - EXCEPT that we **do** use the short-cut solver, so that we can fully + solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). + + O3. In the body of $sf, note that we: @@ -825,7 +837,7 @@ Note that How it works: -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results +* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results into a `SpecPragE` record. Nothing very exciting happens here. * `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any @@ -839,7 +851,7 @@ How it works: it should look like let in f e1 e1 e3 - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards + * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards the other dictionary bindings, and decomposes the call. * Then it can build the RULE and specialised function. @@ -1012,6 +1024,7 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) @@ -1031,33 +1044,65 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) ; wanted <- liftZonkM $ zonkWC wanted -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, residual_wanted) <- getRuleQuantCts wanted + ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted ; let qevs = map ctEvId (bagToList quant_cts) - -- (4) Emit the residual constraints, and wrap the call in the appropriate - -- bindings. - ; ev_binds_var1 <- newTcEvBinds + -- (4) Emit the residual constraints. + ; non_quant_binds <- newTcEvBinds ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var1 + ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds emptyVarSet tv_bndrs qevs - residual_wanted - ; let residual_wrap = mkLHsWrap (WpLet (TcEvBinds ev_binds_var1)) - -- The free vars in this wrapper are `qevs`, plus the explicit `rule_bndrs` - -- and any free tyvars of the above. - - ; traceTc "tcSpecPrag:SpecSigE" $ + non_quant_wc + + -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) + -- by solving "quant_cts" in the special TcSSpecPrag mode + ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ + vcat [ text "quant_cts:" <+> ppr quant_cts ] + ; (rule_rhs_wc, spec_call_binds) + <- setTcLevel rhs_tclvl $ + runTcSSpecPrag $ + solveWanteds (emptyWC { wc_simple = quant_cts }) + ; let rule_rhs_implics = wc_impl rule_rhs_wc + ; massertPpr (null rule_rhs_implics) $ + vcat [ text "tcSpecPrag: unexpected non-simple constraints" + , text "quant_cts:" <+> ppr quant_cts + , text "implics:" <+> ppr rule_rhs_implics ] + ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ + vcat [ text "quant_cts:" <+> ppr quant_cts + , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] + + -- (6) Figure out the blue bindings by solving the implication + -- [G] d1, d2, d3, d4 => [W] sd1, sd2 + ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ + vcat [ text "qevs:" <+> ppr qevs + , text "rule_rhs_wc:" <+> ppr rule_rhs_wc + ] + ; (implics, rule_rhs_binds) <- + buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs + qevs -- d1, d2, d3, d4 + rule_rhs_wc -- sd1, sd2 + ; emitImplications implics + + ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order - -- does not matter - , spe_call = lhs_call - , spe_inl = inl }] } + , text "inl:" <+> ppr inl + , text "non_quant:" <+> ppr non_quant_wc + , text (replicate 40 '-') + , text "spec_call_binds:" <+> ppr spec_call_binds + ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = rule_bndrs' + , spe_expr = tc_spec_e + , spe_rule_binds = rule_rhs_binds + , spe_call_evvars = qevs + , spe_call_binds = (TcEvBinds non_quant_binds, spec_call_binds) + }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -727,7 +727,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +757,37 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] + , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +803,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -886,7 +892,18 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls | otherwise -- Wanted, but not cached = do { dflags <- getDynFlags ; mode <- getModeTcS - ; lkup_res <- matchClassInst dflags mode inerts cls xis dict_loc + ; case mode of + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + { TcSSpecPrag -> + do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" + else continueWith () + } + ; _ -> + do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc ; case lkup_res of OneInst { cir_what = what } -> do { insertSafeOverlapFailureTcS what work_item @@ -894,7 +911,7 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls ; chooseInstance ev lkup_res } _ -> -- NoInstance or NotSure -- We didn't solve it; so try functional dependencies - continueWith () } + continueWith () } } } where dict_loc = ctEvLoc ev @@ -941,13 +958,11 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> TcSMode +matchClassInst :: DynFlags -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult -matchClassInst dflags mode inerts clas tys loc - | TcSSpecPrag <- mode -- See Note [Handling new-form SPECIALISE pragmas] - = return NoInstance -- in GHc.Tc.Gen.Sig +matchClassInst dflags inerts clas tys loc -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2020,7 +2020,7 @@ finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, -- and the TcSMode is TcsHoleFits mode <- getModeTcS - ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,20 +854,32 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = spec_e })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_expr = spec_e + , spe_rule_binds = rule_evbinds + , spe_call_evvars = call_evvars + , spe_call_binds = (non_quant_evbinds, call_evbinds) })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> + runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> + runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> + runZonkBndrT (zonkTcEvBinds non_quant_evbinds) $ \ non_quant_evbinds' -> + runZonkBndrT (zonkEvBinds call_evbinds) $ \ call_evbinds' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_expr = spec_e' + , spe_rule_binds = rule_evbinds' + , spe_call_evvars = call_evvars' + , spe_call_binds = (non_quant_evbinds', call_evbinds') + })) + }} {- ************************************************************************ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4a63a80bb378f29149f2dc2706360457e8000ff5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4a63a80bb378f29149f2dc2706360457e8000ff5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 16:49:12 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Fri, 24 Jan 2025 11:49:12 -0500 Subject: [Git][ghc/ghc][wip/T25623] Fix for alex-3.5.2.0 (#25623) Message-ID: <6793c4883d677_399e92c060c1580@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 02dc0751 by Brandon Chinn at 2025-01-24T08:49:01-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 2 changed files: - compiler/GHC/Parser/Lexer.x - compiler/ghc.cabal.in Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3467,10 +3468,12 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. {-# INLINE alexScanUser #-} +#endif lexToken :: P (PsLocated Token) lexToken = do ===================================== compiler/ghc.cabal.in ===================================== @@ -101,8 +101,10 @@ Library ClosureTypes.h FunTypes.h + -- always include alex so we can use MIN_TOOL_VERSION_alex + build-tool-depends: alex:alex >= 3.2.6 if flag(build-tool-depends) - build-tool-depends: alex:alex >= 3.2.6, happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants + build-tool-depends: happy:happy >= 1.20.0, genprimopcode:genprimopcode, deriveConstants:deriveConstants if flag(with-libzstd) if flag(static-libzstd) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/02dc07516eefe29d5b9ac6fe39e310c05a6732fe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/02dc07516eefe29d5b9ac6fe39e310c05a6732fe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 16:54:51 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 24 Jan 2025 11:54:51 -0500 Subject: [Git][ghc/ghc][master] 2 commits: Break out GHC.Parser.Lexer.Interface Message-ID: <6793c5db9d6a3_399e9257083c19843@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4495e48f by Brandon Chinn at 2025-01-24T11:54:24-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 4f8fc11e by Brandon Chinn at 2025-01-24T11:54:24-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - 12 changed files: - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/ghc.cabal.in - hadrian/src/Rules/SourceDist.hs - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/parser/should_run/NumericUnderscores0.hs - testsuite/tests/parser/should_run/NumericUnderscores0.stdout - + testsuite/tests/parser/should_run/T25609.hs - + testsuite/tests/parser/should_run/T25609.stdout - testsuite/tests/parser/should_run/all.T Changes: ===================================== compiler/GHC/Parser/HaddockLex.x ===================================== @@ -8,6 +8,7 @@ import GHC.Prelude import GHC.Data.FastString import GHC.Hs.Doc import GHC.Parser.Lexer +import GHC.Parser.Lexer.Interface (adjustChar) import GHC.Parser.Annotation import GHC.Types.SrcLoc import GHC.Types.SourceText ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -78,7 +78,6 @@ module GHC.Parser.Lexer ( commentToAnnotation, HdkComment(..), warnopt, - adjustChar, addPsMessage ) where @@ -132,6 +131,8 @@ import GHC.Driver.Flags import GHC.Parser.Errors.Basic import GHC.Parser.Errors.Types import GHC.Parser.Errors.Ppr () +import GHC.Parser.Lexer.Interface +import qualified GHC.Parser.Lexer.String as Lexer.String import GHC.Parser.String } @@ -622,13 +623,6 @@ $unigraphic / { isSmartQuote } { smart_quote_error } \" @stringchar* $unigraphic / { isSmartQuote } { smart_quote_error } } - { - -- Parse as much of the multiline string as possible, except for quotes - @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { tok_string_multi_content } - -- Allow bare quotes if it's not a triple quote - (\" | \"\") / ([\n .] # \") { tok_string_multi_content } -} - <0> { \'\' { token ITtyQuote } @@ -2171,11 +2165,23 @@ tok_string span buf len _buf2 = do src = SourceText $ lexemeToFastString buf len endsInHash = currentChar (offsetBytes (len - 1) buf) == '#' --- | Ideally, we would define this completely with Alex syntax, like normal strings. --- Instead, this is defined as a hybrid solution by manually invoking lex states, which --- we're doing for two reasons: --- 1. The multiline string should all be one lexical token, not multiple --- 2. We need to allow bare quotes, which can't be done with one regex +{- Note [Lexing multiline strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ideally, we would lex multiline strings completely with Alex syntax, like +normal strings. However, we can't because: + + 1. The multiline string should all be one lexical token, not multiple + 2. We need to allow bare quotes, which can't be done with one regex + +Instead, we'll lex them with a hybrid solution in tok_string_multi by manually +invoking lex states. This allows us to get the performance of native Alex +syntax as much as possible, and just gluing the pieces together outside of +Alex. + +Implemented in string_multi_content in GHC/Parser/Lexer/String.x +-} + +-- | See Note [Lexing multiline strings] tok_string_multi :: Action tok_string_multi startSpan startBuf _len _buf2 = do -- advance to the end of the multiline string @@ -2201,17 +2207,14 @@ tok_string_multi startSpan startBuf _len _buf2 = do pure $ L span $ ITstringMulti src (mkFastString s) where goContent i0 = - case alexScan i0 string_multi_content of - AlexToken i1 len _ + case Lexer.String.alexScan i0 Lexer.String.string_multi_content of + Lexer.String.AlexToken i1 len _ | Just i2 <- lexDelim i1 -> pure (i1, i2) | isEOF i1 -> checkSmartQuotes >> setInput i1 >> lexError LexError - -- is the next token a tab character? - -- need this explicitly because there's a global rule matching $tab - | Just ('\t', _) <- alexGetChar' i1 -> setInput i1 >> lexError LexError -- Can happen if no patterns match, e.g. an unterminated gap | len == 0 -> setInput i1 >> lexError LexError | otherwise -> goContent i1 - AlexSkip i1 _ -> goContent i1 + Lexer.String.AlexSkip i1 _ -> goContent i1 _ -> setInput i0 >> lexError LexError lexDelim = @@ -2235,11 +2238,6 @@ tok_string_multi startSpan startBuf _len _buf2 = do Just (c, loc) -> throwSmartQuoteError c loc Nothing -> pure () --- | Dummy action that should never be called. Should only be used in lex states --- that are manually lexed in tok_string_multi. -tok_string_multi_content :: Action -tok_string_multi_content = panic "tok_string_multi_content unexpectedly invoked" - lex_chars :: (String, String) -> PsSpan -> StringBuffer -> Int -> P String lex_chars (startDelim, endDelim) span buf len = either (throwStringLexError i0) pure $ @@ -2591,105 +2589,6 @@ getLastLocIncludingComments = P $ \s@(PState { prev_loc = prev_loc }) -> POk s p getLastLoc :: P PsSpan getLastLoc = P $ \s@(PState { last_loc = last_loc }) -> POk s last_loc -data AlexInput = AI !PsLoc !StringBuffer deriving (Show) - -{- -Note [Unicode in Alex] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Although newer versions of Alex support unicode, this grammar is processed with -the old style '--latin1' behaviour. This means that when implementing the -functions - - alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) - alexInputPrevChar :: AlexInput -> Char - -which Alex uses to take apart our 'AlexInput', we must - - * return a latin1 character in the 'Word8' that 'alexGetByte' expects - * return a latin1 character in 'alexInputPrevChar'. - -We handle this in 'adjustChar' by squishing entire classes of unicode -characters into single bytes. --} - -{-# INLINE adjustChar #-} -adjustChar :: Char -> Word8 -adjustChar c = adj_c - where non_graphic = 0x00 - upper = 0x01 - lower = 0x02 - digit = 0x03 - symbol = 0x04 - space = 0x05 - other_graphic = 0x06 - uniidchar = 0x07 - - adj_c - | c <= '\x07' = non_graphic - | c <= '\x7f' = fromIntegral (ord c) - -- Alex doesn't handle Unicode, so when Unicode - -- character is encountered we output these values - -- with the actual character value hidden in the state. - | otherwise = - -- NB: The logic behind these definitions is also reflected - -- in "GHC.Utils.Lexeme" - -- Any changes here should likely be reflected there. - - case generalCategory c of - UppercaseLetter -> upper - LowercaseLetter -> lower - TitlecaseLetter -> upper - ModifierLetter -> uniidchar -- see #10196 - OtherLetter -> lower -- see #1103 - NonSpacingMark -> uniidchar -- see #7650 - SpacingCombiningMark -> other_graphic - EnclosingMark -> other_graphic - DecimalNumber -> digit - LetterNumber -> digit - OtherNumber -> digit -- see #4373 - ConnectorPunctuation -> symbol - DashPunctuation -> symbol - OpenPunctuation -> other_graphic - ClosePunctuation -> other_graphic - InitialQuote -> other_graphic - FinalQuote -> other_graphic - OtherPunctuation -> symbol - MathSymbol -> symbol - CurrencySymbol -> symbol - ModifierSymbol -> symbol - OtherSymbol -> symbol - Space -> space - _other -> non_graphic - --- Getting the previous 'Char' isn't enough here - we need to convert it into --- the same format that 'alexGetByte' would have produced. --- --- See Note [Unicode in Alex] and #13986. -alexInputPrevChar :: AlexInput -> Char -alexInputPrevChar (AI _ buf) = unsafeChr (fromIntegral (adjustChar pc)) - where pc = prevChar buf '\n' - -unsafeChr :: Int -> Char -unsafeChr (I# c) = GHC.Exts.C# (GHC.Exts.chr# c) - --- backwards compatibility for Alex 2.x -alexGetChar :: AlexInput -> Maybe (Char,AlexInput) -alexGetChar inp = case alexGetByte inp of - Nothing -> Nothing - Just (b,i) -> c `seq` Just (c,i) - where c = unsafeChr $ fromIntegral b - --- See Note [Unicode in Alex] -alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) -alexGetByte (AI loc s) - | atEnd s = Nothing - | otherwise = byte `seq` loc' `seq` s' `seq` - --trace (show (ord c)) $ - Just (byte, (AI loc' s')) - where (c,s') = nextChar s - loc' = advancePsLoc loc c - byte = adjustChar c - {-# INLINE alexGetChar' #-} -- This version does not squash unicode characters, it is used when -- lexing strings. @@ -3470,6 +3369,7 @@ topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. +-- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} lexToken :: P (PsLocated Token) ===================================== compiler/GHC/Parser/Lexer/Interface.hs ===================================== @@ -0,0 +1,124 @@ +{-# LANGUAGE MagicHash #-} + +{- | +This module defines the types and functions necessary for an Alex-generated +lexer. + +https://haskell-alex.readthedocs.io/en/latest/api.html# +-} +module GHC.Parser.Lexer.Interface ( + AlexInput (..), + alexGetByte, + alexInputPrevChar, + + -- * Helpers + alexGetChar, + adjustChar, +) where + +import GHC.Prelude + +import Data.Char (GeneralCategory (..), generalCategory, ord) +import Data.Word (Word8) +import GHC.Data.StringBuffer (StringBuffer, atEnd, nextChar, prevChar) +import GHC.Exts +import GHC.Types.SrcLoc (PsLoc, advancePsLoc) + +data AlexInput = AI !PsLoc !StringBuffer deriving (Show) + +-- See Note [Unicode in Alex] +alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) +alexGetByte (AI loc s) + | atEnd s = Nothing + | otherwise = byte `seq` loc' `seq` s' `seq` + --trace (show (ord c)) $ + Just (byte, (AI loc' s')) + where (c,s') = nextChar s + loc' = advancePsLoc loc c + byte = adjustChar c + +-- Getting the previous 'Char' isn't enough here - we need to convert it into +-- the same format that 'alexGetByte' would have produced. +-- +-- See Note [Unicode in Alex] and #13986. +alexInputPrevChar :: AlexInput -> Char +alexInputPrevChar (AI _ buf) = unsafeChr (fromIntegral (adjustChar pc)) + where pc = prevChar buf '\n' + +-- backwards compatibility for Alex 2.x +alexGetChar :: AlexInput -> Maybe (Char,AlexInput) +alexGetChar inp = case alexGetByte inp of + Nothing -> Nothing + Just (b,i) -> c `seq` Just (c,i) + where c = unsafeChr $ fromIntegral b + +unsafeChr :: Int -> Char +unsafeChr (I# c) = GHC.Exts.C# (GHC.Exts.chr# c) + +{- +Note [Unicode in Alex] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Although newer versions of Alex support unicode, this grammar is processed with +the old style '--latin1' behaviour. This means that when implementing the +functions + + alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) + alexInputPrevChar :: AlexInput -> Char + +which Alex uses to take apart our 'AlexInput', we must + + * return a latin1 character in the 'Word8' that 'alexGetByte' expects + * return a latin1 character in 'alexInputPrevChar'. + +We handle this in 'adjustChar' by squishing entire classes of unicode +characters into single bytes. +-} + +{-# INLINE adjustChar #-} +adjustChar :: Char -> Word8 +adjustChar c = adj_c + where non_graphic = 0x00 + upper = 0x01 + lower = 0x02 + digit = 0x03 + symbol = 0x04 + space = 0x05 + other_graphic = 0x06 + uniidchar = 0x07 + + adj_c + | c <= '\x07' = non_graphic + | c <= '\x7f' = fromIntegral (ord c) + -- Alex doesn't handle Unicode, so when Unicode + -- character is encountered we output these values + -- with the actual character value hidden in the state. + | otherwise = + -- NB: The logic behind these definitions is also reflected + -- in "GHC.Utils.Lexeme" + -- Any changes here should likely be reflected there. + + case generalCategory c of + UppercaseLetter -> upper + LowercaseLetter -> lower + TitlecaseLetter -> upper + ModifierLetter -> uniidchar -- see #10196 + OtherLetter -> lower -- see #1103 + NonSpacingMark -> uniidchar -- see #7650 + SpacingCombiningMark -> other_graphic + EnclosingMark -> other_graphic + DecimalNumber -> digit + LetterNumber -> digit + OtherNumber -> digit -- see #4373 + ConnectorPunctuation -> symbol + DashPunctuation -> symbol + OpenPunctuation -> other_graphic + ClosePunctuation -> other_graphic + InitialQuote -> other_graphic + FinalQuote -> other_graphic + OtherPunctuation -> symbol + MathSymbol -> symbol + CurrencySymbol -> symbol + ModifierSymbol -> symbol + OtherSymbol -> symbol + Space -> space + _other -> non_graphic ===================================== compiler/GHC/Parser/Lexer/String.x ===================================== @@ -0,0 +1,96 @@ +{ +{- | +This module defines lex states for strings. + +This needs to be separate from the normal lexer because the normal lexer +automatically includes rules like skipping whitespace or lexing comments, +which we don't want in these contexts. +-} +module GHC.Parser.Lexer.String ( + AlexReturn (..), + alexScan, + string_multi_content, +) where + +import GHC.Prelude + +import GHC.Parser.Lexer.Interface +import GHC.Utils.Panic (panic) +} + +-- ----------------------------------------------------------------------------- +-- Alex "Character set macros" +-- Copied from GHC/Parser/Lexer.x + +$unispace = \x05 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$nl = [\n\r\f] +$space = [\ $unispace] +$whitechar = [$nl \v $space] +$tab = \t + +$ascdigit = 0-9 +$unidigit = \x03 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$decdigit = $ascdigit -- exactly $ascdigit, no more no less. +$digit = [$ascdigit $unidigit] + +$special = [\(\)\,\;\[\]\`\{\}] +$ascsymbol = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~\:] +$unisymbol = \x04 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$symbol = [$ascsymbol $unisymbol] # [$special \_\"\'] + +$unilarge = \x01 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$asclarge = [A-Z] +$large = [$asclarge $unilarge] + +$unismall = \x02 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$ascsmall = [a-z] +$small = [$ascsmall $unismall \_] + +$uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$idchar = [$small $large $digit $uniidchar \'] + +$unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] +$charesc = [a b f n r t v \\ \" \' \&] + +$octit = 0-7 +$hexit = [$decdigit A-F a-f] + +-- ----------------------------------------------------------------------------- +-- Alex "Regular expression macros" +-- Copied from GHC/Parser/Lexer.x + + at numspc = _* -- numeric spacer (#14473) + at decimal = $decdigit(@numspc $decdigit)* + at octal = $octit(@numspc $octit)* + at hexadecimal = $hexit(@numspc $hexit)* + at gap = \\ $whitechar+ \\ + at cntrl = $asclarge | \@ | \[ | \\ | \] | \^ | \_ + at ascii = \^ @cntrl | "NUL" | "SOH" | "STX" | "ETX" | "EOT" | "ENQ" | "ACK" + | "BEL" | "BS" | "HT" | "LF" | "VT" | "FF" | "CR" | "SO" | "SI" | "DLE" + | "DC1" | "DC2" | "DC3" | "DC4" | "NAK" | "SYN" | "ETB" | "CAN" + | "EM" | "SUB" | "ESC" | "FS" | "GS" | "RS" | "US" | "SP" | "DEL" + at escape = \\ ( $charesc | @ascii | @decimal | o @octal | x @hexadecimal ) + at stringchar = ($graphic # [\\ \"]) | $space | @escape | @gap + +:- + +-- Define an empty rule so it compiles; callers should always explicitly specify a startcode +<0> () ; + +-- See Note [Lexing multiline strings] + { + -- Parse as much of the multiline string as possible, except for quotes + @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { string_multi_content_action } + -- Allow bare quotes if it's not a triple quote + (\" | \"\") / ([\n .] # \") { string_multi_content_action } +} + +-- ----------------------------------------------------------------------------- +-- Haskell actions +{ +-- | Dummy action that should never be called. Should only be used in lex states +-- that are manually lexed in tok_string_multi. +string_multi_content_action :: a +string_multi_content_action = panic "string_multi_content_action unexpectedly invoked" +} ===================================== compiler/ghc.cabal.in ===================================== @@ -646,6 +646,8 @@ Library GHC.Parser.Errors.Types GHC.Parser.Header GHC.Parser.Lexer + GHC.Parser.Lexer.Interface + GHC.Parser.Lexer.String GHC.Parser.HaddockLex GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock ===================================== hadrian/src/Rules/SourceDist.hs ===================================== @@ -185,6 +185,7 @@ prepareTree dest = do , (stage0InTree , compiler, "GHC/Cmm/Lexer.x", "GHC/Cmm/Lexer.hs") , (stage0InTree , compiler, "GHC/Parser.y", "GHC/Parser.hs") , (stage0InTree , compiler, "GHC/Parser/Lexer.x", "GHC/Parser/Lexer.hs") + , (stage0InTree , compiler, "GHC/Parser/Lexer/String.x", "GHC/Parser/Lexer/String.hs") , (stage0InTree , compiler, "GHC/Parser/HaddockLex.x", "GHC/Parser/HaddockLex.hs") , (stage0InTree , hpcBin, "src/Trace/Hpc/Parser.y", "src/Trace/Hpc/Parser.hs") , (stage0InTree , genprimopcode, "Parser.y", "Parser.hs") ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -127,6 +127,8 @@ GHC.Parser.Errors.Ppr GHC.Parser.Errors.Types GHC.Parser.HaddockLex GHC.Parser.Lexer +GHC.Parser.Lexer.Interface +GHC.Parser.Lexer.String GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock GHC.Parser.String ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.hs ===================================== @@ -99,3 +99,6 @@ main = do 0x_ff == 0xff, 0x__ff == 0xff ] + + -- ensure that strings are unaffected + print ["\o16_000", "\16_000", "\x16_000"] ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.stdout ===================================== @@ -11,3 +11,4 @@ [True,True,True] [True,True,True] [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] +["\SO_000","\DLE_000","\SYN_000"] ===================================== testsuite/tests/parser/should_run/T25609.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE MultilineStrings #-} + +main :: IO () +main = do + -- strings with comment tokens + print """{- asdf -}""" + print """a {- asdf -} b""" + print """-- asdf""" + print """{-""" + + -- strings with haddock comments + print """{- | test -}""" + print """{- * test -}""" + print """{- ^ test -}""" + print """{- $ test -}""" + print """-- | test""" + print """-- * test""" + print """-- ^ test""" + print """-- $ test""" + + -- strings with only whitespace + print """ """ + print """ + + + """ + + -- strings with unicode + print """ + ★ + ★ + ★ + ★ + """ ===================================== testsuite/tests/parser/should_run/T25609.stdout ===================================== @@ -0,0 +1,15 @@ +"{- asdf -}" +"a {- asdf -} b" +"-- asdf" +"{-" +"{- | test -}" +"{- * test -}" +"{- ^ test -}" +"{- $ test -}" +"-- | test" +"-- * test" +"-- ^ test" +"-- $ test" +" " +"\n" +" \9733\n\9733\n \9733\n\9733" ===================================== testsuite/tests/parser/should_run/all.T ===================================== @@ -21,6 +21,9 @@ test('RecordDotSyntax3', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compil test('RecordDotSyntax4', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compile_and_run, ['RecordDotSyntax4', '']) test('RecordDotSyntax5', normal, compile_and_run, ['']) test('ListTuplePunsConstraints', extra_files(['ListTuplePunsConstraints.hs']), ghci_script, ['ListTuplePunsConstraints.script']) + +# Multiline strings test('MultilineStrings', normal, compile_and_run, ['']) test('MultilineStringsOverloaded', normal, compile_and_run, ['']) test('T25375', normal, compile_and_run, ['']) +test('T25609', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85c60aead149dd52a5c778e124e21aae3f95a23b...4f8fc11e45fc5e7311572bb16a60b1f756b536c6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85c60aead149dd52a5c778e124e21aae3f95a23b...4f8fc11e45fc5e7311572bb16a60b1f756b536c6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 16:55:45 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 24 Jan 2025 11:55:45 -0500 Subject: [Git][ghc/ghc][master] testsuite: Pass TEST_HC_OPTS to many more tests Message-ID: <6793c6112513_399e92570760224ec@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e7ab778f by Matthew Pickering at 2025-01-24T11:55:01-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - 7 changed files: - testsuite/tests/bytecode/T24634/Makefile - testsuite/tests/codeGen/should_compile/Makefile - testsuite/tests/driver/j-space/jspace.hs - testsuite/tests/patsyn/should_compile/T13350/Makefile - testsuite/tests/rts/Makefile - testsuite/tests/rts/T1791/Makefile - testsuite/tests/wasm/should_run/control-flow/WasmControlFlow.hs Changes: ===================================== testsuite/tests/bytecode/T24634/Makefile ===================================== @@ -4,14 +4,14 @@ include $(TOP)/mk/test.mk # This case loads bytecode from the interface file written in the second invocation. T24634a: - '$(TEST_HC)' -c hello_c.c -o hello_c.o - '$(TEST_HC)' -c -fbyte-code-and-object-code -fno-omit-interface-pragmas Hello.hs - '$(TEST_HC)' -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Main.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -c hello_c.c -o hello_c.o + '$(TEST_HC)' $(TEST_HC_OPTS) -c -fbyte-code-and-object-code -fno-omit-interface-pragmas Hello.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Main.hs ./Main # This case uses the bytecode generated in 'runHscBackendPhase', not involving the interface, since 'Hello' is compiled # in the same invocation as 'Main'. T24634b: - '$(TEST_HC)' -c hello_c.c -o hello_c.o - '$(TEST_HC)' -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Hello.hs Main.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -c hello_c.c -o hello_c.o + '$(TEST_HC)' $(TEST_HC_OPTS) -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Hello.hs Main.hs ./Main ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -79,4 +79,4 @@ T17648: grep -F 'f :: T GHC.Types.Int -> () [TagSig' >/dev/null T25166: - '$(TEST_HC)' -O2 -dno-typeable-binds -ddump-cmm T25166.hs | awk '/foo_closure/{flag=1}/}]/{flag=0}flag' + '$(TEST_HC)' $(TEST_HC_OPTS) -O2 -dno-typeable-binds -ddump-cmm T25166.hs | awk '/foo_closure/{flag=1}/}]/{flag=0}flag' ===================================== testsuite/tests/driver/j-space/jspace.hs ===================================== @@ -23,7 +23,7 @@ initGhcM :: [String] -> Ghc () initGhcM xs = do session <- getSession df1 <- getSessionDynFlags - let cmdOpts = ["-fforce-recomp"] ++ xs + let cmdOpts = ["-fforce-recomp", "-dno-debug-output"] ++ xs (df2, leftovers, _) <- parseDynamicFlags (hsc_logger session) df1 (map noLoc cmdOpts) setSessionDynFlags df2 ghcUnitId <- case lookup "Project Unit Id" (compilerInfo df2) of ===================================== testsuite/tests/patsyn/should_compile/T13350/Makefile ===================================== @@ -7,7 +7,7 @@ LOCAL_PKGCONF=local.package.conf T13350: "$(GHC_PKG)" init $(LOCAL_PKGCONF) cd boolean && "$(TEST_HC)" $(TEST_HC_OPTS) -v0 --make Setup.hs - cd boolean && ./Setup configure -v0 --with-compiler="$(TEST_HC)" --with-hc-pkg="$(GHC_PKG)" --package-db=../$(LOCAL_PKGCONF) + cd boolean && ./Setup configure -v0 --with-compiler="$(TEST_HC)" --ghc-options='$(filter-out -rtsopts,$(TEST_HC_OPTS))' --with-hc-pkg="$(GHC_PKG)" --package-db=../$(LOCAL_PKGCONF) cd boolean && ./Setup build -v0 cd boolean && ./Setup register -v0 --inplace "$(TEST_HC)" $(TEST_HC_OPTS) -c T13350.hs -package-db $(LOCAL_PKGCONF) ===================================== testsuite/tests/rts/Makefile ===================================== @@ -82,7 +82,7 @@ T10296a: .PHONY: T11788 T11788: - "$(TEST_HC)" -c T11788.c -o T11788_obj.o + "$(TEST_HC)" $(TEST_HC_OPTS) -c T11788.c -o T11788_obj.o "$(AR)" rsT libT11788.a T11788_obj.o 2> /dev/null echo main | "$(TEST_HC)" $(filter-out -rtsopts, $(TEST_HC_OPTS_INTERACTIVE)) T11788.hs -lT11788 -L"$(PWD)" @@ -101,13 +101,13 @@ T14695: .PHONY: InternalCounters InternalCounters: - "$(TEST_HC)" +RTS -s --internal-counters -RTS 2>&1 | grep "Internal Counters" - -"$(TEST_HC)" +RTS -s -RTS 2>&1 | grep "Internal Counters" + "$(TEST_HC)" $(TEST_HC_OPTS) +RTS -s --internal-counters -RTS 2>&1 | grep "Internal Counters" + -"$(TEST_HC)" $(TEST_HC_OPTS) +RTS -s -RTS 2>&1 | grep "Internal Counters" .PHONY: KeepCafsFail KeepCafsFail: - "$(TEST_HC)" -c -g -v0 KeepCafsBase.hs KeepCafs1.hs KeepCafs2.hs - "$(TEST_HC)" -g -v0 KeepCafsMain.hs KeepCafsBase.o -debug -rdynamic -fwhole-archive-hs-libs $(KEEPCAFS) + "$(TEST_HC)" $(TEST_HC_OPTS) -c -g -v0 KeepCafsBase.hs KeepCafs1.hs KeepCafs2.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -g -v0 KeepCafsMain.hs KeepCafsBase.o -debug -rdynamic -fwhole-archive-hs-libs $(KEEPCAFS) ./KeepCafsMain 2>&1 || echo "exit($$?)" .PHONY: KeepCafs @@ -116,37 +116,37 @@ KeepCafs: .PHONY: EventlogOutput1 EventlogOutput1: - "$(TEST_HC)" -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -v0 EventlogOutput.hs ./EventlogOutput +RTS -l -olhello.eventlog ls hello.eventlog >/dev/null .PHONY: EventlogOutput2 EventlogOutput2: - "$(TEST_HC)" -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -v0 EventlogOutput.hs ./EventlogOutput +RTS -l ls EventlogOutput.eventlog >/dev/null .PHONY: EventlogOutputNull EventlogOutputNull: - "$(TEST_HC)" -rtsopts -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -rtsopts -v0 EventlogOutput.hs ./EventlogOutput +RTS -l --null-eventlog-writer test ! -e EventlogOutput.eventlog .PHONY: T20199 T20199: - "$(TEST_HC)" -no-hs-main -optcxx-std=c++11 -v0 T20199.cpp -o T20199 + "$(TEST_HC)" $(TEST_HC_OPTS) -no-hs-main -optcxx-std=c++11 -v0 T20199.cpp -o T20199 ./T20199 .PHONY: EventlogOutput_IPE EventlogOutput_IPE: - "$(TEST_HC)" -debug -finfo-table-map -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -debug -finfo-table-map -v0 EventlogOutput.hs ./EventlogOutput +RTS -va 2> EventlogOutput_IPE.stderr.log grep "IPE:" EventlogOutput_IPE.stderr.log .PHONY: T23142 T23142: # Test that the -Di output contains different frames - "$(TEST_HC)" --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log + "$(TEST_HC)" $(TEST_HC_OPTS) --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log grep -m1 -c "ATOMICALLY_FRAME" T23142.log grep -m1 -c "CATCH_RETRY_FRAME" T23142.log grep -m1 -c "CATCH_STM_FRAME" T23142.log ===================================== testsuite/tests/rts/T1791/Makefile ===================================== @@ -3,4 +3,4 @@ include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk T1791: - '$(TEST_HC)' T1791.hs -o T1791 -O -rtsopts + '$(TEST_HC)' $(TEST_HC_OPTS) T1791.hs -o T1791 -O -rtsopts ===================================== testsuite/tests/wasm/should_run/control-flow/WasmControlFlow.hs ===================================== @@ -41,6 +41,7 @@ main = do `xopt_set` LangExt.StandaloneKindSignatures `xopt_set` LangExt.UnliftedDatatypes `xopt_set` LangExt.DataKinds + `dopt_set` Opt_D_no_debug_output setSessionDynFlags dflags groups <- mapM loadPath files liftIO $ do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e7ab778f55e070b9381e2a7dbb445a86718acb17 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e7ab778f55e070b9381e2a7dbb445a86718acb17 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 17:24:42 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Fri, 24 Jan 2025 12:24:42 -0500 Subject: [Git][ghc/ghc][wip/T24359] first attempt at new approach for specialise expression Message-ID: <6793ccdad70e_3ae8d533dd44548c@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: d2da66af by sheaf at 2025-01-24T18:24:26+01:00 first attempt at new approach for specialise expression - - - - - 8 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -59,6 +59,7 @@ import GHC.Utils.Misc ((<||>)) import Data.Function import Data.List (sortBy) import Data.Data (Data) +import GHC.Data.Bag (Bag) {- ************************************************************************ @@ -824,7 +825,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +836,51 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_expr :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + , spe_rule_binds :: TcEvBinds + -- ^ "RULE RHS evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_evvars :: [Var] + -- ^ "specialised call evidence variables" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_wrapper :: HsWrapper + -- ^ wrapper for the specialised call + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] @@ -996,7 +1028,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,6 +791,9 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SLD TODO: rewrite this whole note, using the same example as +Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. + Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -823,7 +826,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,88 +924,74 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_expr = the_call + + -- BLUE bindings (sd1 = d1, sd2 = d3) + , spe_rule_binds = EvBinds rule_evbinds + + -- RED binders (d1,..., d4) + , spe_call_evvars = rule_evvars + -- HsWrapper for RED evidence binds (d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ...) + , spe_call_wrapper = call_wrapper + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig = do { ds_call <- zapUnspecables $ -- zapUnspecables: see dsLExpr the_call -- Note [Desugaring RULE left hand sides] - -- Simplify the (desugared) call; see wrinkle (SP1) - -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - - ; case prepareSpecLHS poly_id bndrs core_call of { - Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - - Just (bndr_set, spec_const_binds, lhs_args) -> - - do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) - all_bndrs = bndr_set `unionVarSet` const_bndrs - -- all_bndrs: all binders in core_call that should be quantified - - -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] - rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) - spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs - - mk_spec_body fn_body = mkLets spec_const_binds $ - mkCoreApps fn_body lhs_args - - ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id - , text "bndrs" <+> ppr bndrs - , text "all_bndrs" <+> ppr all_bndrs - , text "const_bndrs" <+> ppr const_bndrs - , text "ds_call" <+> ppr ds_call - , text "core_call" <+> ppr core_call - , text "core_call fvs" <+> ppr (exprFreeVars core_call) - , text "spec_const_binds" <+> ppr spec_const_binds ]) - + ; let + -- See (SP1) in Note [Desugaring SPECIALISE pragmas] + simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + (_, rule_lhs_args) = collectArgs core_call + -- TODO: why do we need rule_lhs_args? + -- Can't we get away without them by using the trick: + -- + -- $sf sd1 sd2 = let[non-rec] f = in + -- let d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... in + -- in f d1 d2 d3 d4 + + -- BLUE binders, in correspondence with the LHS of the blue bindings + spec_evvars = + map evBindVar (bagToList rule_evbinds) + -- Yes: rule_evbinds and not call_evbinds. + -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] + -- if this is not clear. + + -- The rule binders, including the RED binders d1, ..., d4 + rule_bndrs = scopedSort $ + bndrs ++ rule_evvars + -- The specialised $sf binders, including the BLUE binders sd1, sd2 + spec_bndrs = scopedSort $ + bndrs ++ spec_evvars + + ; dsHsWrapper call_wrapper $ \ wrap_call -> + do { let mk_spec_body fn_rhs = wrap_call $ mkCoreApps fn_rhs rule_lhs_args + ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id + , text "bndrs:" <+> ppr bndrs + , text "ds_call:" <+> ppr ds_call + , text "core_call:" <+> ppr core_call + , text "rule_evbinds:" <+> ppr rule_evbinds + , text (replicate 40 '-') + , text "rule_evvars:" <+> ppr rule_evvars + , text "spec_evvars:" <+> ppr spec_evvars + , text "rule_bndrs:" <+> ppr rule_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs + , text "rule_lhs_args:" <+> ppr rule_lhs_args + ]) ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id lhs_args - spec_bndrs mk_spec_body inl } } } - -prepareSpecLHS :: Id -> [EvVar] -> CoreExpr - -> Maybe (VarSet, [CoreBind], [CoreExpr]) --- See (SP2) in Note [Desugaring SPECIALISE pragmas] -prepareSpecLHS poly_id evs the_call - = go (mkVarSet evs) [] the_call - where - go :: VarSet -- Quantified variables, or dependencies thereof - -> [CoreBind] -- Reversed list of constant evidence bindings - -> CoreExpr - -> Maybe (IdSet, [CoreBind], [CoreExpr]) - go qevs acc (Cast e _) - = go qevs acc e - go qevs acc (Let bind e) - | not (all isDictId bndrs) -- A normal 'let' is too complicated - = Nothing - - | all (transfer_to_spec_rhs qevs) $ - rhssOfBind bind -- One of the `const_binds` - = go qevs (bind:acc) e - - | otherwise - = go (qevs `extendVarSetList` bndrs) acc e - where - bndrs = bindersOf bind + rule_bndrs poly_id rule_lhs_args + spec_bndrs mk_spec_body inl - go qevs acc e - | (Var fun, args) <- collectArgs e - = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just (qevs, reverse acc, args) - | otherwise - = Nothing - - transfer_to_spec_rhs qevs rhs - = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) - where - is_quant_id v = isId v && v `elemVarSet` qevs - -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + } } +dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern @@ -1054,7 +1043,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -50,7 +50,7 @@ import GHC.Tc.Utils.Instantiate( topInstantiate, tcInstTypeBndrs ) import GHC.Tc.Utils.Env import GHC.Tc.Types.Origin -import GHC.Tc.Types.Evidence( HsWrapper(..), (<.>), TcEvBinds(..) ) +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Constraint import GHC.Tc.Zonk.TcType @@ -720,26 +720,26 @@ We are going to use the following (perhaps somewhat contrived) example to demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah - {-# SPECIALISE forall x y z. f (x::[Int]) y y [z] True #-} + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} We want to generate: - RULE forall @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::Int) (y::p) (z :: q). - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True = let - sd1 = d2 -- - sd2 = d4 -- (*) + sd1 = d2 -- We will refer to these as the + sd2 = d4 -- "RULE RHS evidence bindings" in $sf @p @q sd1 sd2 x y z - $sf @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Int]) (y::p) (z :: q) + $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) = let(non-rec) f = in let d1 = $fEqList $fEqInt -- - d2 = sd1 -- - d3 = sd1 -- - d4 = sd2 -- (**) + d2 = sd1 -- We will refer to these as the + d3 = sd1 -- "specialised call evidence bindings" + d4 = sd2 -- in - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True Key observations: @@ -754,7 +754,8 @@ Key observations: The `rule_bndrs`, over which the RULE is quantified, are all the variables free in the call to `f`, /ignoring/ all dictionary simplification. Why? Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. + match, the dictionaries should match. This is why, in the above example, + the rule binders are: rule_bndrs = @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) @@ -768,20 +769,31 @@ Key observations: - We don't assume that the dictionary for 'Eq [q]' was obtained from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - with a rule binder (d4 :: Eq q), we would either have to: + e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - generate a RULE LHS of the form + - generate a RULE of the form - forall ... @q (d5 :: Eq q). f d1 d2 d3 ($fEqList d5) + forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - find a way to "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]). + which is verboten (it matches on the structure of a dictionary), or + + - "run the instance in reverse" to extract evidence for + (Eq q) from (Eq [q]), which is impossible to do in general. "Partially solving" the Eq [q] constraint by using the instance doesn't buy us anything; we can't do anything useful with the information that an Eq [q] dictionary is of the form ($fEqList ..). - O4. + To achieve this, we solve the constraints that originated from typechecking + the expression to specialise, but in the special 'TcSSpecPrag' mode, which + ensures that: + + - We don't use instances (whether top-level instances or local instances + from quantified constraints), as those are not "reversible", + - EXCEPT that we **do** use the short-cut solver, so that we can fully + solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). + + O3. In the body of $sf, note that we: @@ -825,7 +837,7 @@ Note that How it works: -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results +* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results into a `SpecPragE` record. Nothing very exciting happens here. * `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any @@ -839,7 +851,7 @@ How it works: it should look like let in f e1 e1 e3 - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards + * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards the other dictionary bindings, and decomposes the call. * Then it can build the RULE and specialised function. @@ -1012,6 +1024,7 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) @@ -1031,33 +1044,67 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) ; wanted <- liftZonkM $ zonkWC wanted -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, residual_wanted) <- getRuleQuantCts wanted + ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted ; let qevs = map ctEvId (bagToList quant_cts) - -- (4) Emit the residual constraints, and wrap the call in the appropriate - -- bindings. - ; ev_binds_var1 <- newTcEvBinds + -- (4) Emit the residual constraints. + ; non_quant_binds <- newTcEvBinds ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var1 + ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds emptyVarSet tv_bndrs qevs - residual_wanted - ; let residual_wrap = mkLHsWrap (WpLet (TcEvBinds ev_binds_var1)) - -- The free vars in this wrapper are `qevs`, plus the explicit `rule_bndrs` - -- and any free tyvars of the above. - - ; traceTc "tcSpecPrag:SpecSigE" $ + non_quant_wc + + -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) + -- by solving "quant_cts" in the special TcSSpecPrag mode + ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ + vcat [ text "quant_cts:" <+> ppr quant_cts ] + ; (rule_rhs_wc, spec_call_binds) + <- setTcLevel rhs_tclvl $ + runTcSSpecPrag $ + solveWanteds (emptyWC { wc_simple = quant_cts }) + ; let rule_rhs_implics = wc_impl rule_rhs_wc + ; massertPpr (null rule_rhs_implics) $ + vcat [ text "tcSpecPrag: unexpected non-simple constraints" + , text "quant_cts:" <+> ppr quant_cts + , text "implics:" <+> ppr rule_rhs_implics ] + ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ + vcat [ text "quant_cts:" <+> ppr quant_cts + , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] + + -- (6) Figure out the blue bindings by solving the implication + -- [G] d1, d2, d3, d4 => [W] sd1, sd2 + ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ + vcat [ text "qevs:" <+> ppr qevs + , text "rule_rhs_wc:" <+> ppr rule_rhs_wc + ] + ; (implics, rule_rhs_binds) <- + buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs + qevs -- d1, d2, d3, d4 + rule_rhs_wc -- sd1, sd2 + ; emitImplications implics + + ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order - -- does not matter - , spe_call = lhs_call - , spe_inl = inl }] } + , text "inl:" <+> ppr inl + , text "non_quant:" <+> ppr non_quant_wc + , text (replicate 40 '-') + , text "spec_call_binds:" <+> ppr spec_call_binds + ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = rule_bndrs' + , spe_expr = tc_spec_e + , spe_rule_binds = rule_rhs_binds + , spe_call_evvars = qevs + , spe_call_wrapper = + WpLet (TcEvBinds non_quant_binds) + <.> WpLet (EvBinds spec_call_binds) + }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -727,7 +727,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +757,37 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] + , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +803,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -886,7 +892,19 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls | otherwise -- Wanted, but not cached = do { dflags <- getDynFlags ; mode <- getModeTcS - ; lkup_res <- matchClassInst dflags mode inerts cls xis dict_loc + ; case mode of + -- SLD TODO: pass mode to try_instances and have this as a top-level guard + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + { TcSSpecPrag -> + do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" + else continueWith () + } + ; _ -> + do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc ; case lkup_res of OneInst { cir_what = what } -> do { insertSafeOverlapFailureTcS what work_item @@ -894,7 +912,7 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls ; chooseInstance ev lkup_res } _ -> -- NoInstance or NotSure -- We didn't solve it; so try functional dependencies - continueWith () } + continueWith () } } } where dict_loc = ctEvLoc ev @@ -941,13 +959,11 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> TcSMode +matchClassInst :: DynFlags -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult -matchClassInst dflags mode inerts clas tys loc - | TcSSpecPrag <- mode -- See Note [Handling new-form SPECIALISE pragmas] - = return NoInstance -- in GHc.Tc.Gen.Sig +matchClassInst dflags inerts clas tys loc -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2020,7 +2020,7 @@ finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, -- and the TcSMode is TcsHoleFits mode <- getModeTcS - ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,20 +854,31 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = spec_e })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_expr = spec_e + , spe_rule_binds = rule_evbinds + , spe_call_evvars = call_evvars + , spe_call_wrapper = call_wrapper })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> + runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> + runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> + runZonkBndrT (zonkCoFn call_wrapper) $ \ call_wrapper' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_expr = spec_e' + , spe_rule_binds = rule_evbinds' + , spe_call_evvars = call_evvars' + , spe_call_wrapper = call_wrapper' + })) + }} {- ************************************************************************ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2da66af31439e60f5cd1553bb4ec3cf906b137d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d2da66af31439e60f5cd1553bb4ec3cf906b137d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 17:28:31 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Fri, 24 Jan 2025 12:28:31 -0500 Subject: [Git][ghc/ghc][wip/T24359] first attempt at new approach for specialise expression Message-ID: <6793cdbfa8b01_3ae8d5665ad096b4@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 5a409925 by sheaf at 2025-01-24T18:28:18+01:00 first attempt at new approach for specialise expression - - - - - 8 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -824,7 +824,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +835,51 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_expr :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + , spe_rule_binds :: TcEvBinds + -- ^ "RULE RHS evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_evvars :: [Var] + -- ^ "specialised call evidence variables" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_wrapper :: HsWrapper + -- ^ wrapper for the specialised call + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] @@ -996,7 +1027,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,6 +791,9 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SLD TODO: rewrite this whole note, using the same example as +Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. + Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -823,7 +826,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,88 +924,74 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_expr = the_call + + -- BLUE bindings (sd1 = d1, sd2 = d3) + , spe_rule_binds = EvBinds rule_evbinds + + -- RED binders (d1,..., d4) + , spe_call_evvars = rule_evvars + -- HsWrapper for RED evidence binds (d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ...) + , spe_call_wrapper = call_wrapper + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig = do { ds_call <- zapUnspecables $ -- zapUnspecables: see dsLExpr the_call -- Note [Desugaring RULE left hand sides] - -- Simplify the (desugared) call; see wrinkle (SP1) - -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - - ; case prepareSpecLHS poly_id bndrs core_call of { - Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - - Just (bndr_set, spec_const_binds, lhs_args) -> - - do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) - all_bndrs = bndr_set `unionVarSet` const_bndrs - -- all_bndrs: all binders in core_call that should be quantified - - -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] - rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) - spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs - - mk_spec_body fn_body = mkLets spec_const_binds $ - mkCoreApps fn_body lhs_args - - ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id - , text "bndrs" <+> ppr bndrs - , text "all_bndrs" <+> ppr all_bndrs - , text "const_bndrs" <+> ppr const_bndrs - , text "ds_call" <+> ppr ds_call - , text "core_call" <+> ppr core_call - , text "core_call fvs" <+> ppr (exprFreeVars core_call) - , text "spec_const_binds" <+> ppr spec_const_binds ]) - + ; let + -- See (SP1) in Note [Desugaring SPECIALISE pragmas] + simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + (_, rule_lhs_args) = collectArgs core_call + -- TODO: why do we need rule_lhs_args? + -- Can't we get away without them by using the trick: + -- + -- $sf sd1 sd2 = let[non-rec] f = in + -- let d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... in + -- in f d1 d2 d3 d4 + + -- BLUE binders, in correspondence with the LHS of the blue bindings + spec_evvars = + map evBindVar (bagToList rule_evbinds) + -- Yes: rule_evbinds and not call_evbinds. + -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] + -- if this is not clear. + + -- The rule binders, including the RED binders d1, ..., d4 + rule_bndrs = scopedSort $ + bndrs ++ rule_evvars + -- The specialised $sf binders, including the BLUE binders sd1, sd2 + spec_bndrs = scopedSort $ + bndrs ++ spec_evvars + + ; dsHsWrapper call_wrapper $ \ wrap_call -> + do { let mk_spec_body fn_rhs = wrap_call $ mkCoreApps fn_rhs rule_lhs_args + ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id + , text "bndrs:" <+> ppr bndrs + , text "ds_call:" <+> ppr ds_call + , text "core_call:" <+> ppr core_call + , text "rule_evbinds:" <+> ppr rule_evbinds + , text (replicate 40 '-') + , text "rule_evvars:" <+> ppr rule_evvars + , text "spec_evvars:" <+> ppr spec_evvars + , text "rule_bndrs:" <+> ppr rule_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs + , text "rule_lhs_args:" <+> ppr rule_lhs_args + ]) ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id lhs_args - spec_bndrs mk_spec_body inl } } } - -prepareSpecLHS :: Id -> [EvVar] -> CoreExpr - -> Maybe (VarSet, [CoreBind], [CoreExpr]) --- See (SP2) in Note [Desugaring SPECIALISE pragmas] -prepareSpecLHS poly_id evs the_call - = go (mkVarSet evs) [] the_call - where - go :: VarSet -- Quantified variables, or dependencies thereof - -> [CoreBind] -- Reversed list of constant evidence bindings - -> CoreExpr - -> Maybe (IdSet, [CoreBind], [CoreExpr]) - go qevs acc (Cast e _) - = go qevs acc e - go qevs acc (Let bind e) - | not (all isDictId bndrs) -- A normal 'let' is too complicated - = Nothing - - | all (transfer_to_spec_rhs qevs) $ - rhssOfBind bind -- One of the `const_binds` - = go qevs (bind:acc) e - - | otherwise - = go (qevs `extendVarSetList` bndrs) acc e - where - bndrs = bindersOf bind + rule_bndrs poly_id rule_lhs_args + spec_bndrs mk_spec_body inl - go qevs acc e - | (Var fun, args) <- collectArgs e - = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just (qevs, reverse acc, args) - | otherwise - = Nothing - - transfer_to_spec_rhs qevs rhs - = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) - where - is_quant_id v = isId v && v `elemVarSet` qevs - -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + } } +dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern @@ -1054,7 +1043,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -50,7 +50,7 @@ import GHC.Tc.Utils.Instantiate( topInstantiate, tcInstTypeBndrs ) import GHC.Tc.Utils.Env import GHC.Tc.Types.Origin -import GHC.Tc.Types.Evidence( HsWrapper(..), (<.>), TcEvBinds(..) ) +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Constraint import GHC.Tc.Zonk.TcType @@ -720,26 +720,26 @@ We are going to use the following (perhaps somewhat contrived) example to demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah - {-# SPECIALISE forall x y z. f (x::[Int]) y y [z] True #-} + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} We want to generate: - RULE forall @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::Int) (y::p) (z :: q). - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True = let - sd1 = d2 -- - sd2 = d4 -- (*) + sd1 = d2 -- We will refer to these as the + sd2 = d4 -- "RULE RHS evidence bindings" in $sf @p @q sd1 sd2 x y z - $sf @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Int]) (y::p) (z :: q) + $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) = let(non-rec) f = in let d1 = $fEqList $fEqInt -- - d2 = sd1 -- - d3 = sd1 -- - d4 = sd2 -- (**) + d2 = sd1 -- We will refer to these as the + d3 = sd1 -- "specialised call evidence bindings" + d4 = sd2 -- in - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True Key observations: @@ -754,7 +754,8 @@ Key observations: The `rule_bndrs`, over which the RULE is quantified, are all the variables free in the call to `f`, /ignoring/ all dictionary simplification. Why? Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. + match, the dictionaries should match. This is why, in the above example, + the rule binders are: rule_bndrs = @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) @@ -768,20 +769,31 @@ Key observations: - We don't assume that the dictionary for 'Eq [q]' was obtained from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - with a rule binder (d4 :: Eq q), we would either have to: + e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - generate a RULE LHS of the form + - generate a RULE of the form - forall ... @q (d5 :: Eq q). f d1 d2 d3 ($fEqList d5) + forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - find a way to "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]). + which is verboten (it matches on the structure of a dictionary), or + + - "run the instance in reverse" to extract evidence for + (Eq q) from (Eq [q]), which is impossible to do in general. "Partially solving" the Eq [q] constraint by using the instance doesn't buy us anything; we can't do anything useful with the information that an Eq [q] dictionary is of the form ($fEqList ..). - O4. + To achieve this, we solve the constraints that originated from typechecking + the expression to specialise, but in the special 'TcSSpecPrag' mode, which + ensures that: + + - We don't use instances (whether top-level instances or local instances + from quantified constraints), as those are not "reversible", + - EXCEPT that we **do** use the short-cut solver, so that we can fully + solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). + + O3. In the body of $sf, note that we: @@ -825,7 +837,7 @@ Note that How it works: -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results +* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results into a `SpecPragE` record. Nothing very exciting happens here. * `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any @@ -839,7 +851,7 @@ How it works: it should look like let in f e1 e1 e3 - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards + * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards the other dictionary bindings, and decomposes the call. * Then it can build the RULE and specialised function. @@ -1012,6 +1024,7 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) @@ -1031,33 +1044,67 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) ; wanted <- liftZonkM $ zonkWC wanted -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, residual_wanted) <- getRuleQuantCts wanted + ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted ; let qevs = map ctEvId (bagToList quant_cts) - -- (4) Emit the residual constraints, and wrap the call in the appropriate - -- bindings. - ; ev_binds_var1 <- newTcEvBinds + -- (4) Emit the residual constraints. + ; non_quant_binds <- newTcEvBinds ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var1 + ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds emptyVarSet tv_bndrs qevs - residual_wanted - ; let residual_wrap = mkLHsWrap (WpLet (TcEvBinds ev_binds_var1)) - -- The free vars in this wrapper are `qevs`, plus the explicit `rule_bndrs` - -- and any free tyvars of the above. - - ; traceTc "tcSpecPrag:SpecSigE" $ + non_quant_wc + + -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) + -- by solving "quant_cts" in the special TcSSpecPrag mode + ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ + vcat [ text "quant_cts:" <+> ppr quant_cts ] + ; (rule_rhs_wc, spec_call_binds) + <- setTcLevel rhs_tclvl $ + runTcSSpecPrag $ + solveWanteds (emptyWC { wc_simple = quant_cts }) + ; let rule_rhs_implics = wc_impl rule_rhs_wc + ; massertPpr (null rule_rhs_implics) $ + vcat [ text "tcSpecPrag: unexpected non-simple constraints" + , text "quant_cts:" <+> ppr quant_cts + , text "implics:" <+> ppr rule_rhs_implics ] + ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ + vcat [ text "quant_cts:" <+> ppr quant_cts + , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] + + -- (6) Figure out the blue bindings by solving the implication + -- [G] d1, d2, d3, d4 => [W] sd1, sd2 + ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ + vcat [ text "qevs:" <+> ppr qevs + , text "rule_rhs_wc:" <+> ppr rule_rhs_wc + ] + ; (implics, rule_rhs_binds) <- + buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs + qevs -- d1, d2, d3, d4 + rule_rhs_wc -- sd1, sd2 + ; emitImplications implics + + ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order - -- does not matter - , spe_call = lhs_call - , spe_inl = inl }] } + , text "inl:" <+> ppr inl + , text "non_quant:" <+> ppr non_quant_wc + , text (replicate 40 '-') + , text "spec_call_binds:" <+> ppr spec_call_binds + ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = rule_bndrs' + , spe_expr = tc_spec_e + , spe_rule_binds = rule_rhs_binds + , spe_call_evvars = qevs + , spe_call_wrapper = + WpLet (TcEvBinds non_quant_binds) + <.> WpLet (EvBinds spec_call_binds) + }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -727,7 +727,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +757,37 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] + , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +803,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -886,7 +892,19 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls | otherwise -- Wanted, but not cached = do { dflags <- getDynFlags ; mode <- getModeTcS - ; lkup_res <- matchClassInst dflags mode inerts cls xis dict_loc + ; case mode of + -- SLD TODO: pass mode to try_instances and have this as a top-level guard + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + { TcSSpecPrag -> + do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" + else continueWith () + } + ; _ -> + do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc ; case lkup_res of OneInst { cir_what = what } -> do { insertSafeOverlapFailureTcS what work_item @@ -894,7 +912,7 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls ; chooseInstance ev lkup_res } _ -> -- NoInstance or NotSure -- We didn't solve it; so try functional dependencies - continueWith () } + continueWith () } } } where dict_loc = ctEvLoc ev @@ -941,13 +959,11 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> TcSMode +matchClassInst :: DynFlags -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult -matchClassInst dflags mode inerts clas tys loc - | TcSSpecPrag <- mode -- See Note [Handling new-form SPECIALISE pragmas] - = return NoInstance -- in GHc.Tc.Gen.Sig +matchClassInst dflags inerts clas tys loc -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2020,7 +2020,7 @@ finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, -- and the TcSMode is TcsHoleFits mode <- getModeTcS - ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,20 +854,31 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = spec_e })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_expr = spec_e + , spe_rule_binds = rule_evbinds + , spe_call_evvars = call_evvars + , spe_call_wrapper = call_wrapper })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> + runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> + runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> + runZonkBndrT (zonkCoFn call_wrapper) $ \ call_wrapper' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_expr = spec_e' + , spe_rule_binds = rule_evbinds' + , spe_call_evvars = call_evvars' + , spe_call_wrapper = call_wrapper' + })) + }} {- ************************************************************************ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5a409925f44bc9c74f830b16ed7417b81a5c828c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5a409925f44bc9c74f830b16ed7417b81a5c828c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 17:46:54 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Fri, 24 Jan 2025 12:46:54 -0500 Subject: [Git][ghc/ghc][wip/T24359] first attempt at new approach for specialise expression Message-ID: <6793d20e135ed_3ae8d5a750801463c@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: d18a1617 by sheaf at 2025-01-24T18:46:40+01:00 first attempt at new approach for specialise expression - - - - - 8 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -824,7 +824,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +835,51 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_expr :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + , spe_rule_binds :: TcEvBinds + -- ^ "RULE RHS evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_evvars :: [Var] + -- ^ "specialised call evidence variables" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_wrapper :: HsWrapper + -- ^ wrapper for the specialised call + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] @@ -996,7 +1027,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,6 +791,9 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SLD TODO: rewrite this whole note, using the same example as +Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. + Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -823,7 +826,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,88 +924,74 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_expr = the_call + + -- BLUE bindings (sd1 = d1, sd2 = d3) + , spe_rule_binds = EvBinds rule_evbinds + + -- RED binders (d1,..., d4) + , spe_call_evvars = rule_evvars + -- HsWrapper for RED evidence binds (let d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... in) + , spe_call_wrapper = call_wrapper + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig - = do { ds_call <- zapUnspecables $ -- zapUnspecables: see - dsLExpr the_call -- Note [Desugaring RULE left hand sides] + = do { ds_call <- unsetGOptM Opt_EnableRewriteRules $ -- Note [Desugaring RULE left hand sides] + unsetWOptM Opt_WarnIdentities $ + zapUnspecables $ + dsLExpr the_call - -- Simplify the (desugared) call; see wrinkle (SP1) - -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - - ; case prepareSpecLHS poly_id bndrs core_call of { - Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - - Just (bndr_set, spec_const_binds, lhs_args) -> - - do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) - all_bndrs = bndr_set `unionVarSet` const_bndrs - -- all_bndrs: all binders in core_call that should be quantified - - -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] - rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) - spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs - - mk_spec_body fn_body = mkLets spec_const_binds $ - mkCoreApps fn_body lhs_args - - ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id - , text "bndrs" <+> ppr bndrs - , text "all_bndrs" <+> ppr all_bndrs - , text "const_bndrs" <+> ppr const_bndrs - , text "ds_call" <+> ppr ds_call - , text "core_call" <+> ppr core_call - , text "core_call fvs" <+> ppr (exprFreeVars core_call) - , text "spec_const_binds" <+> ppr spec_const_binds ]) - + ; let + -- See (SP1) in Note [Desugaring SPECIALISE pragmas] + simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + (_, rule_lhs_args) = collectArgs ds_call + -- TODO: why do we need rule_lhs_args? + -- Can't we get away without them by using the trick: + -- + -- $sf sd1 sd2 = let[non-rec] f = in + -- let d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... in + -- in f d1 d2 d3 d4 + + -- BLUE binders, in correspondence with the LHS of the blue bindings + spec_evvars = + map evBindVar (bagToList rule_evbinds) + -- Yes: rule_evbinds and not call_evbinds. + -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] + -- if this is not clear. + + -- The rule binders, including the RED binders d1, ..., d4 + rule_bndrs = scopedSort $ bndrs ++ rule_evvars + -- The specialised $sf binders, including the BLUE binders sd1, sd2 + spec_bndrs = scopedSort $ bndrs ++ spec_evvars + + ; dsHsWrapper call_wrapper $ \ wrap_call -> + do { let mk_spec_body fn_rhs = wrap_call $ mkCoreApps fn_rhs rule_lhs_args + ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id + , text "bndrs:" <+> ppr bndrs + , text "ds_call:" <+> ppr ds_call + , text "core_call:" <+> ppr core_call + , text "rule_evbinds:" <+> ppr rule_evbinds + , text (replicate 40 '-') + , text "rule_evvars:" <+> ppr rule_evvars + , text "spec_evvars:" <+> ppr spec_evvars + , text "rule_bndrs:" <+> ppr rule_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs + , text "rule_lhs_args:" <+> ppr rule_lhs_args + ]) ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id lhs_args - spec_bndrs mk_spec_body inl } } } - -prepareSpecLHS :: Id -> [EvVar] -> CoreExpr - -> Maybe (VarSet, [CoreBind], [CoreExpr]) --- See (SP2) in Note [Desugaring SPECIALISE pragmas] -prepareSpecLHS poly_id evs the_call - = go (mkVarSet evs) [] the_call - where - go :: VarSet -- Quantified variables, or dependencies thereof - -> [CoreBind] -- Reversed list of constant evidence bindings - -> CoreExpr - -> Maybe (IdSet, [CoreBind], [CoreExpr]) - go qevs acc (Cast e _) - = go qevs acc e - go qevs acc (Let bind e) - | not (all isDictId bndrs) -- A normal 'let' is too complicated - = Nothing - - | all (transfer_to_spec_rhs qevs) $ - rhssOfBind bind -- One of the `const_binds` - = go qevs (bind:acc) e - - | otherwise - = go (qevs `extendVarSetList` bndrs) acc e - where - bndrs = bindersOf bind + rule_bndrs poly_id rule_lhs_args + spec_bndrs mk_spec_body inl - go qevs acc e - | (Var fun, args) <- collectArgs e - = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just (qevs, reverse acc, args) - | otherwise - = Nothing - - transfer_to_spec_rhs qevs rhs - = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) - where - is_quant_id v = isId v && v `elemVarSet` qevs - -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + } } +dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern @@ -1054,7 +1043,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -50,7 +50,7 @@ import GHC.Tc.Utils.Instantiate( topInstantiate, tcInstTypeBndrs ) import GHC.Tc.Utils.Env import GHC.Tc.Types.Origin -import GHC.Tc.Types.Evidence( HsWrapper(..), (<.>), TcEvBinds(..) ) +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Constraint import GHC.Tc.Zonk.TcType @@ -720,26 +720,26 @@ We are going to use the following (perhaps somewhat contrived) example to demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah - {-# SPECIALISE forall x y z. f (x::[Int]) y y [z] True #-} + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} We want to generate: - RULE forall @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::Int) (y::p) (z :: q). - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True = let - sd1 = d2 -- - sd2 = d4 -- (*) + sd1 = d2 -- We will refer to these as the + sd2 = d4 -- "RULE RHS evidence bindings" in $sf @p @q sd1 sd2 x y z - $sf @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Int]) (y::p) (z :: q) + $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) = let(non-rec) f = in let d1 = $fEqList $fEqInt -- - d2 = sd1 -- - d3 = sd1 -- - d4 = sd2 -- (**) + d2 = sd1 -- We will refer to these as the + d3 = sd1 -- "specialised call evidence bindings" + d4 = sd2 -- in - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True Key observations: @@ -754,7 +754,8 @@ Key observations: The `rule_bndrs`, over which the RULE is quantified, are all the variables free in the call to `f`, /ignoring/ all dictionary simplification. Why? Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. + match, the dictionaries should match. This is why, in the above example, + the rule binders are: rule_bndrs = @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) @@ -768,20 +769,31 @@ Key observations: - We don't assume that the dictionary for 'Eq [q]' was obtained from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - with a rule binder (d4 :: Eq q), we would either have to: + e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - generate a RULE LHS of the form + - generate a RULE of the form - forall ... @q (d5 :: Eq q). f d1 d2 d3 ($fEqList d5) + forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - find a way to "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]). + which is verboten (it matches on the structure of a dictionary), or + + - "run the instance in reverse" to extract evidence for + (Eq q) from (Eq [q]), which is impossible to do in general. "Partially solving" the Eq [q] constraint by using the instance doesn't buy us anything; we can't do anything useful with the information that an Eq [q] dictionary is of the form ($fEqList ..). - O4. + To achieve this, we solve the constraints that originated from typechecking + the expression to specialise, but in the special 'TcSSpecPrag' mode, which + ensures that: + + - We don't use instances (whether top-level instances or local instances + from quantified constraints), as those are not "reversible", + - EXCEPT that we **do** use the short-cut solver, so that we can fully + solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). + + O3. In the body of $sf, note that we: @@ -825,7 +837,7 @@ Note that How it works: -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results +* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results into a `SpecPragE` record. Nothing very exciting happens here. * `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any @@ -839,7 +851,7 @@ How it works: it should look like let in f e1 e1 e3 - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards + * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards the other dictionary bindings, and decomposes the call. * Then it can build the RULE and specialised function. @@ -1012,6 +1024,7 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) @@ -1031,33 +1044,67 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) ; wanted <- liftZonkM $ zonkWC wanted -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, residual_wanted) <- getRuleQuantCts wanted + ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted ; let qevs = map ctEvId (bagToList quant_cts) - -- (4) Emit the residual constraints, and wrap the call in the appropriate - -- bindings. - ; ev_binds_var1 <- newTcEvBinds + -- (4) Emit the residual constraints. + ; non_quant_binds <- newTcEvBinds ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var1 + ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds emptyVarSet tv_bndrs qevs - residual_wanted - ; let residual_wrap = mkLHsWrap (WpLet (TcEvBinds ev_binds_var1)) - -- The free vars in this wrapper are `qevs`, plus the explicit `rule_bndrs` - -- and any free tyvars of the above. - - ; traceTc "tcSpecPrag:SpecSigE" $ + non_quant_wc + + -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) + -- by solving "quant_cts" in the special TcSSpecPrag mode + ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ + vcat [ text "quant_cts:" <+> ppr quant_cts ] + ; (rule_rhs_wc, spec_call_binds) + <- setTcLevel rhs_tclvl $ + runTcSSpecPrag $ + solveWanteds (emptyWC { wc_simple = quant_cts }) + ; let rule_rhs_implics = wc_impl rule_rhs_wc + ; massertPpr (null rule_rhs_implics) $ + vcat [ text "tcSpecPrag: unexpected non-simple constraints" + , text "quant_cts:" <+> ppr quant_cts + , text "implics:" <+> ppr rule_rhs_implics ] + ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ + vcat [ text "quant_cts:" <+> ppr quant_cts + , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] + + -- (6) Figure out the blue bindings by solving the implication + -- [G] d1, d2, d3, d4 => [W] sd1, sd2 + ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ + vcat [ text "qevs:" <+> ppr qevs + , text "rule_rhs_wc:" <+> ppr rule_rhs_wc + ] + ; (implics, rule_rhs_binds) <- + buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs + qevs -- d1, d2, d3, d4 + rule_rhs_wc -- sd1, sd2 + ; emitImplications implics + + ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order - -- does not matter - , spe_call = lhs_call - , spe_inl = inl }] } + , text "inl:" <+> ppr inl + , text "non_quant:" <+> ppr non_quant_wc + , text (replicate 40 '-') + , text "spec_call_binds:" <+> ppr spec_call_binds + ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = rule_bndrs' + , spe_expr = tc_spec_e + , spe_rule_binds = rule_rhs_binds + , spe_call_evvars = qevs + , spe_call_wrapper = + WpLet (TcEvBinds non_quant_binds) + <.> WpLet (EvBinds spec_call_binds) + }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -727,7 +727,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +757,37 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] + , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +803,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -886,7 +892,19 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls | otherwise -- Wanted, but not cached = do { dflags <- getDynFlags ; mode <- getModeTcS - ; lkup_res <- matchClassInst dflags mode inerts cls xis dict_loc + ; case mode of + -- SLD TODO: pass mode to try_instances and have this as a top-level guard + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + { TcSSpecPrag -> + do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" + else continueWith () + } + ; _ -> + do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc ; case lkup_res of OneInst { cir_what = what } -> do { insertSafeOverlapFailureTcS what work_item @@ -894,7 +912,7 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls ; chooseInstance ev lkup_res } _ -> -- NoInstance or NotSure -- We didn't solve it; so try functional dependencies - continueWith () } + continueWith () } } } where dict_loc = ctEvLoc ev @@ -941,13 +959,11 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> TcSMode +matchClassInst :: DynFlags -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult -matchClassInst dflags mode inerts clas tys loc - | TcSSpecPrag <- mode -- See Note [Handling new-form SPECIALISE pragmas] - = return NoInstance -- in GHc.Tc.Gen.Sig +matchClassInst dflags inerts clas tys loc -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2020,7 +2020,7 @@ finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, -- and the TcSMode is TcsHoleFits mode <- getModeTcS - ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,20 +854,31 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = spec_e })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_expr = spec_e + , spe_rule_binds = rule_evbinds + , spe_call_evvars = call_evvars + , spe_call_wrapper = call_wrapper })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> + runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> + runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> + runZonkBndrT (zonkCoFn call_wrapper) $ \ call_wrapper' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_expr = spec_e' + , spe_rule_binds = rule_evbinds' + , spe_call_evvars = call_evvars' + , spe_call_wrapper = call_wrapper' + })) + }} {- ************************************************************************ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d18a1617dcc2dba8c33c71a6a84008af282844af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d18a1617dcc2dba8c33c71a6a84008af282844af You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 18:36:02 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Fri, 24 Jan 2025 13:36:02 -0500 Subject: [Git][ghc/ghc][wip/T24359] first attempt at new approach for specialise expression Message-ID: <6793dd927061e_3d889e6393541924c@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 8c186fb0 by sheaf at 2025-01-24T19:35:47+01:00 first attempt at new approach for specialise expression - - - - - 8 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -824,7 +824,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +835,51 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_expr :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + , spe_rule_binds :: TcEvBinds + -- ^ "RULE RHS evidence bindings" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_evvars :: [Var] + -- ^ "specialised call evidence variables" + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + , spe_call_wrapper :: HsWrapper + -- ^ wrapper for the specialised call + -- + -- See Note [Handling new-form SPECIALISE pragmas] + -- in GHC.Tc.Gen.Sig + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] @@ -996,7 +1027,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,6 +791,9 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SLD TODO: rewrite this whole note, using the same example as +Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. + Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -823,7 +826,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,89 +924,98 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_expr = the_call + + -- BLUE bindings (sd1 = d1, sd2 = d3) + , spe_rule_binds = EvBinds rule_evbinds + -- SLD TODO: I am not using the bindings anywhere, only the LHS EvVars + -- + -- On the face of it, this seems obviously incorrect (I am missing the + -- BLUE let bindings), but I don't have a case that triggers a problem, + -- while ADDING the BLUE bindings causes complications due to the fact + -- that the 'sd's are defined by simplifying the 'd's, without cloning, + -- so we naively get (loopy) recursive bindings. + + -- RED binders (d1,..., d4) + , spe_call_evvars = rule_evvars + -- HsWrapper for RED evidence binds (let d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... in) + , spe_call_wrapper = call_wrapper + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig - = do { ds_call <- zapUnspecables $ -- zapUnspecables: see - dsLExpr the_call -- Note [Desugaring RULE left hand sides] + = do { ds_call <- unsetGOptM Opt_EnableRewriteRules $ -- Note [Desugaring RULE left hand sides] + unsetWOptM Opt_WarnIdentities $ + zapUnspecables $ + dsLExpr the_call - -- Simplify the (desugared) call; see wrinkle (SP1) - -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - - ; case prepareSpecLHS poly_id bndrs core_call of { + ; let + -- See (SP1) in Note [Desugaring SPECIALISE pragmas] + simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + ; case collectSpecArgs poly_id core_call of { Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - - Just (bndr_set, spec_const_binds, lhs_args) -> - - do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) - all_bndrs = bndr_set `unionVarSet` const_bndrs - -- all_bndrs: all binders in core_call that should be quantified - - -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] - rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) - spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs - - mk_spec_body fn_body = mkLets spec_const_binds $ - mkCoreApps fn_body lhs_args - - ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id - , text "bndrs" <+> ppr bndrs - , text "all_bndrs" <+> ppr all_bndrs - , text "const_bndrs" <+> ppr const_bndrs - , text "ds_call" <+> ppr ds_call - , text "core_call" <+> ppr core_call - , text "core_call fvs" <+> ppr (exprFreeVars core_call) - , text "spec_const_binds" <+> ppr spec_const_binds ]) - + ; return Nothing } ; + Just rule_lhs_args -> + do { let + -- BLUE binders, in correspondence with the LHS of the blue bindings + spec_evvars = + map evBindVar (bagToList rule_evbinds) + -- Yes: rule_evbinds and not call_evbinds. + -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] + -- if this is not clear. + + -- The rule binders, including the RED binders d1, ..., d4 + rule_bndrs = scopedSort $ bndrs ++ rule_evvars + -- The specialised $sf binders, including the BLUE binders sd1, sd2 + spec_bndrs = scopedSort $ bndrs ++ spec_evvars + + ; dsHsWrapper call_wrapper $ \ wrap_call -> + do { let mk_spec_body fn_rhs = wrap_call $ mkCoreApps fn_rhs rule_lhs_args + ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id + , text "bndrs:" <+> ppr bndrs + , text "ds_call:" <+> ppr ds_call + , text "core_call:" <+> ppr core_call + , text "rule_evbinds:" <+> ppr rule_evbinds + , text (replicate 40 '-') + , text "rule_evvars:" <+> ppr rule_evvars + , text "spec_evvars:" <+> ppr spec_evvars + , text "rule_bndrs:" <+> ppr rule_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs + , text "rule_lhs_args:" <+> ppr rule_lhs_args + ]) ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id lhs_args - spec_bndrs mk_spec_body inl } } } + rule_bndrs poly_id rule_lhs_args + spec_bndrs mk_spec_body inl + + } } } } +dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" -prepareSpecLHS :: Id -> [EvVar] -> CoreExpr - -> Maybe (VarSet, [CoreBind], [CoreExpr]) +collectSpecArgs :: Id -> CoreExpr + -> Maybe [CoreExpr] -- See (SP2) in Note [Desugaring SPECIALISE pragmas] -prepareSpecLHS poly_id evs the_call - = go (mkVarSet evs) [] the_call +-- SLD TODO: good example for this is simpl016 +collectSpecArgs poly_id the_call + = go the_call where - go :: VarSet -- Quantified variables, or dependencies thereof - -> [CoreBind] -- Reversed list of constant evidence bindings - -> CoreExpr - -> Maybe (IdSet, [CoreBind], [CoreExpr]) - go qevs acc (Cast e _) - = go qevs acc e - go qevs acc (Let bind e) - | not (all isDictId bndrs) -- A normal 'let' is too complicated - = Nothing - - | all (transfer_to_spec_rhs qevs) $ - rhssOfBind bind -- One of the `const_binds` - = go qevs (bind:acc) e - - | otherwise - = go (qevs `extendVarSetList` bndrs) acc e - where - bndrs = bindersOf bind - - go qevs acc e + go :: CoreExpr + -> Maybe [CoreExpr] + go (Cast e _) + = go e + go (Let _bind e) + = go e + go e | (Var fun, args) <- collectArgs e = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just (qevs, reverse acc, args) + Just args | otherwise = Nothing - transfer_to_spec_rhs qevs rhs - = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) - where - is_quant_id v = isId v && v `elemVarSet` qevs - -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) - finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern -> [Var] -> (CoreExpr -> CoreExpr) -> InlinePragma -- Specialised form @@ -1054,7 +1066,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because @@ -1077,7 +1089,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args | all is_nop_arg rule_args, not (isInlinePragma spec_inl) -- The specialisation does nothing. - -- But don't compliain if it is SPECIALISE INLINE (#4444) + -- But don't complain if it is SPECIALISE INLINE (#4444) = Just UselessSpecialiseNoSpecialisation | otherwise ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -50,7 +50,7 @@ import GHC.Tc.Utils.Instantiate( topInstantiate, tcInstTypeBndrs ) import GHC.Tc.Utils.Env import GHC.Tc.Types.Origin -import GHC.Tc.Types.Evidence( HsWrapper(..), (<.>), TcEvBinds(..) ) +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Constraint import GHC.Tc.Zonk.TcType @@ -720,26 +720,26 @@ We are going to use the following (perhaps somewhat contrived) example to demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah - {-# SPECIALISE forall x y z. f (x::[Int]) y y [z] True #-} + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} We want to generate: - RULE forall @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::Int) (y::p) (z :: q). - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True = let - sd1 = d2 -- - sd2 = d4 -- (*) + sd1 = d2 -- We will refer to these as the + sd2 = d4 -- "RULE RHS evidence bindings" in $sf @p @q sd1 sd2 x y z - $sf @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Int]) (y::p) (z :: q) + $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) = let(non-rec) f = in let d1 = $fEqList $fEqInt -- - d2 = sd1 -- - d3 = sd1 -- - d4 = sd2 -- (**) + d2 = sd1 -- We will refer to these as the + d3 = sd1 -- "specialised call evidence bindings" + d4 = sd2 -- in - f @[Int] @p @p @[q] d1 d2 d3 d4 x y y [z] True + f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True Key observations: @@ -754,7 +754,8 @@ Key observations: The `rule_bndrs`, over which the RULE is quantified, are all the variables free in the call to `f`, /ignoring/ all dictionary simplification. Why? Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. + match, the dictionaries should match. This is why, in the above example, + the rule binders are: rule_bndrs = @p @q (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) @@ -768,20 +769,31 @@ Key observations: - We don't assume that the dictionary for 'Eq [q]' was obtained from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - with a rule binder (d4 :: Eq q), we would either have to: + e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - generate a RULE LHS of the form + - generate a RULE of the form - forall ... @q (d5 :: Eq q). f d1 d2 d3 ($fEqList d5) + forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - find a way to "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]). + which is verboten (it matches on the structure of a dictionary), or + + - "run the instance in reverse" to extract evidence for + (Eq q) from (Eq [q]), which is impossible to do in general. "Partially solving" the Eq [q] constraint by using the instance doesn't buy us anything; we can't do anything useful with the information that an Eq [q] dictionary is of the form ($fEqList ..). - O4. + To achieve this, we solve the constraints that originated from typechecking + the expression to specialise, but in the special 'TcSSpecPrag' mode, which + ensures that: + + - We don't use instances (whether top-level instances or local instances + from quantified constraints), as those are not "reversible", + - EXCEPT that we **do** use the short-cut solver, so that we can fully + solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). + + O3. In the body of $sf, note that we: @@ -825,7 +837,7 @@ Note that How it works: -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results +* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results into a `SpecPragE` record. Nothing very exciting happens here. * `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any @@ -839,7 +851,7 @@ How it works: it should look like let in f e1 e1 e3 - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards + * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards the other dictionary bindings, and decomposes the call. * Then it can build the RULE and specialised function. @@ -1012,6 +1024,7 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) @@ -1031,33 +1044,67 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) ; wanted <- liftZonkM $ zonkWC wanted -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, residual_wanted) <- getRuleQuantCts wanted + ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted ; let qevs = map ctEvId (bagToList quant_cts) - -- (4) Emit the residual constraints, and wrap the call in the appropriate - -- bindings. - ; ev_binds_var1 <- newTcEvBinds + -- (4) Emit the residual constraints. + ; non_quant_binds <- newTcEvBinds ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var1 + ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds emptyVarSet tv_bndrs qevs - residual_wanted - ; let residual_wrap = mkLHsWrap (WpLet (TcEvBinds ev_binds_var1)) - -- The free vars in this wrapper are `qevs`, plus the explicit `rule_bndrs` - -- and any free tyvars of the above. - - ; traceTc "tcSpecPrag:SpecSigE" $ + non_quant_wc + + -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) + -- by solving "quant_cts" in the special TcSSpecPrag mode + ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ + vcat [ text "quant_cts:" <+> ppr quant_cts ] + ; (rule_rhs_wc, spec_call_binds) + <- setTcLevel rhs_tclvl $ + runTcSSpecPrag $ + solveWanteds (emptyWC { wc_simple = quant_cts }) + ; let rule_rhs_implics = wc_impl rule_rhs_wc + ; massertPpr (null rule_rhs_implics) $ + vcat [ text "tcSpecPrag: unexpected non-simple constraints" + , text "quant_cts:" <+> ppr quant_cts + , text "implics:" <+> ppr rule_rhs_implics ] + ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ + vcat [ text "quant_cts:" <+> ppr quant_cts + , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] + + -- (6) Figure out the blue bindings by solving the implication + -- [G] d1, d2, d3, d4 => [W] sd1, sd2 + ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ + vcat [ text "qevs:" <+> ppr qevs + , text "rule_rhs_wc:" <+> ppr rule_rhs_wc + ] + ; (implics, rule_rhs_binds) <- + buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs + qevs -- d1, d2, d3, d4 + rule_rhs_wc -- sd1, sd2 + ; emitImplications implics + + ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order - -- does not matter - , spe_call = lhs_call - , spe_inl = inl }] } + , text "inl:" <+> ppr inl + , text "non_quant:" <+> ppr non_quant_wc + , text (replicate 40 '-') + , text "spec_call_binds:" <+> ppr spec_call_binds + ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = rule_bndrs' + , spe_expr = tc_spec_e + , spe_rule_binds = rule_rhs_binds + , spe_call_evvars = qevs + , spe_call_wrapper = + WpLet (TcEvBinds non_quant_binds) + <.> WpLet (EvBinds spec_call_binds) + }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -727,7 +727,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +757,37 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] + , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +803,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -886,7 +892,19 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls | otherwise -- Wanted, but not cached = do { dflags <- getDynFlags ; mode <- getModeTcS - ; lkup_res <- matchClassInst dflags mode inerts cls xis dict_loc + ; case mode of + -- SLD TODO: pass mode to try_instances and have this as a top-level guard + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + { TcSSpecPrag -> + do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" + else continueWith () + } + ; _ -> + do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc ; case lkup_res of OneInst { cir_what = what } -> do { insertSafeOverlapFailureTcS what work_item @@ -894,7 +912,7 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls ; chooseInstance ev lkup_res } _ -> -- NoInstance or NotSure -- We didn't solve it; so try functional dependencies - continueWith () } + continueWith () } } } where dict_loc = ctEvLoc ev @@ -941,13 +959,11 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> TcSMode +matchClassInst :: DynFlags -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult -matchClassInst dflags mode inerts clas tys loc - | TcSSpecPrag <- mode -- See Note [Handling new-form SPECIALISE pragmas] - = return NoInstance -- in GHc.Tc.Gen.Sig +matchClassInst dflags inerts clas tys loc -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2020,7 +2020,7 @@ finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, -- and the TcSMode is TcsHoleFits mode <- getModeTcS - ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,20 +854,31 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = spec_e })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_expr = spec_e + , spe_rule_binds = rule_evbinds + , spe_call_evvars = call_evvars + , spe_call_wrapper = call_wrapper })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> + runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> + runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> + runZonkBndrT (zonkCoFn call_wrapper) $ \ call_wrapper' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_expr = spec_e' + , spe_rule_binds = rule_evbinds' + , spe_call_evvars = call_evvars' + , spe_call_wrapper = call_wrapper' + })) + }} {- ************************************************************************ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c186fb0f991d675d81f3ac7e50d6d098a6e296d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c186fb0f991d675d81f3ac7e50d6d098a6e296d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 21:58:40 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 24 Jan 2025 16:58:40 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Break out GHC.Parser.Lexer.Interface Message-ID: <67940d10d0609_5a1014797305706f@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4495e48f by Brandon Chinn at 2025-01-24T11:54:24-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 4f8fc11e by Brandon Chinn at 2025-01-24T11:54:24-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - e7ab778f by Matthew Pickering at 2025-01-24T11:55:01-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - a244d8c0 by Sylvain Henry at 2025-01-24T16:58:28-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 282aad76 by Jens Petersen at 2025-01-24T16:58:29-05:00 fixup! hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Header.hs - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/ModSummary.hs - compiler/GHC/Unit/Types.hs - compiler/ghc.cabal.in - hadrian/src/Flavour.hs - hadrian/src/Packages.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Generate.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/88e174ff8cf11589ef6106cc481d1f7dad284a6c...282aad76a9cf76dd9ff5ec1e2ec07faccd277a58 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/88e174ff8cf11589ef6106cc481d1f7dad284a6c...282aad76a9cf76dd9ff5ec1e2ec07faccd277a58 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 24 21:59:33 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 24 Jan 2025 16:59:33 -0500 Subject: [Git][ghc/ghc][wip/juhp-hp2ps-fixup2] 4 commits: Break out GHC.Parser.Lexer.Interface Message-ID: <67940d45d4563_5a10155fe60600c4@gitlab.mail> Ben Gamari pushed to branch wip/juhp-hp2ps-fixup2 at Glasgow Haskell Compiler / GHC Commits: 4495e48f by Brandon Chinn at 2025-01-24T11:54:24-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 4f8fc11e by Brandon Chinn at 2025-01-24T11:54:24-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - e7ab778f by Matthew Pickering at 2025-01-24T11:55:01-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - cfd0b338 by Jens Petersen at 2025-01-24T16:59:00-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - 20 changed files: - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/ghc.cabal.in - hadrian/src/Rules/SourceDist.hs - testsuite/tests/bytecode/T24634/Makefile - testsuite/tests/codeGen/should_compile/Makefile - testsuite/tests/count-deps/CountDepsParser.stdout - testsuite/tests/driver/j-space/jspace.hs - testsuite/tests/parser/should_run/NumericUnderscores0.hs - testsuite/tests/parser/should_run/NumericUnderscores0.stdout - + testsuite/tests/parser/should_run/T25609.hs - + testsuite/tests/parser/should_run/T25609.stdout - testsuite/tests/parser/should_run/all.T - testsuite/tests/patsyn/should_compile/T13350/Makefile - testsuite/tests/rts/Makefile - testsuite/tests/rts/T1791/Makefile - testsuite/tests/wasm/should_run/control-flow/WasmControlFlow.hs - utils/hp2ps/Utilities.c Changes: ===================================== compiler/GHC/Parser/HaddockLex.x ===================================== @@ -8,6 +8,7 @@ import GHC.Prelude import GHC.Data.FastString import GHC.Hs.Doc import GHC.Parser.Lexer +import GHC.Parser.Lexer.Interface (adjustChar) import GHC.Parser.Annotation import GHC.Types.SrcLoc import GHC.Types.SourceText ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -78,7 +78,6 @@ module GHC.Parser.Lexer ( commentToAnnotation, HdkComment(..), warnopt, - adjustChar, addPsMessage ) where @@ -132,6 +131,8 @@ import GHC.Driver.Flags import GHC.Parser.Errors.Basic import GHC.Parser.Errors.Types import GHC.Parser.Errors.Ppr () +import GHC.Parser.Lexer.Interface +import qualified GHC.Parser.Lexer.String as Lexer.String import GHC.Parser.String } @@ -622,13 +623,6 @@ $unigraphic / { isSmartQuote } { smart_quote_error } \" @stringchar* $unigraphic / { isSmartQuote } { smart_quote_error } } - { - -- Parse as much of the multiline string as possible, except for quotes - @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { tok_string_multi_content } - -- Allow bare quotes if it's not a triple quote - (\" | \"\") / ([\n .] # \") { tok_string_multi_content } -} - <0> { \'\' { token ITtyQuote } @@ -2171,11 +2165,23 @@ tok_string span buf len _buf2 = do src = SourceText $ lexemeToFastString buf len endsInHash = currentChar (offsetBytes (len - 1) buf) == '#' --- | Ideally, we would define this completely with Alex syntax, like normal strings. --- Instead, this is defined as a hybrid solution by manually invoking lex states, which --- we're doing for two reasons: --- 1. The multiline string should all be one lexical token, not multiple --- 2. We need to allow bare quotes, which can't be done with one regex +{- Note [Lexing multiline strings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Ideally, we would lex multiline strings completely with Alex syntax, like +normal strings. However, we can't because: + + 1. The multiline string should all be one lexical token, not multiple + 2. We need to allow bare quotes, which can't be done with one regex + +Instead, we'll lex them with a hybrid solution in tok_string_multi by manually +invoking lex states. This allows us to get the performance of native Alex +syntax as much as possible, and just gluing the pieces together outside of +Alex. + +Implemented in string_multi_content in GHC/Parser/Lexer/String.x +-} + +-- | See Note [Lexing multiline strings] tok_string_multi :: Action tok_string_multi startSpan startBuf _len _buf2 = do -- advance to the end of the multiline string @@ -2201,17 +2207,14 @@ tok_string_multi startSpan startBuf _len _buf2 = do pure $ L span $ ITstringMulti src (mkFastString s) where goContent i0 = - case alexScan i0 string_multi_content of - AlexToken i1 len _ + case Lexer.String.alexScan i0 Lexer.String.string_multi_content of + Lexer.String.AlexToken i1 len _ | Just i2 <- lexDelim i1 -> pure (i1, i2) | isEOF i1 -> checkSmartQuotes >> setInput i1 >> lexError LexError - -- is the next token a tab character? - -- need this explicitly because there's a global rule matching $tab - | Just ('\t', _) <- alexGetChar' i1 -> setInput i1 >> lexError LexError -- Can happen if no patterns match, e.g. an unterminated gap | len == 0 -> setInput i1 >> lexError LexError | otherwise -> goContent i1 - AlexSkip i1 _ -> goContent i1 + Lexer.String.AlexSkip i1 _ -> goContent i1 _ -> setInput i0 >> lexError LexError lexDelim = @@ -2235,11 +2238,6 @@ tok_string_multi startSpan startBuf _len _buf2 = do Just (c, loc) -> throwSmartQuoteError c loc Nothing -> pure () --- | Dummy action that should never be called. Should only be used in lex states --- that are manually lexed in tok_string_multi. -tok_string_multi_content :: Action -tok_string_multi_content = panic "tok_string_multi_content unexpectedly invoked" - lex_chars :: (String, String) -> PsSpan -> StringBuffer -> Int -> P String lex_chars (startDelim, endDelim) span buf len = either (throwStringLexError i0) pure $ @@ -2591,105 +2589,6 @@ getLastLocIncludingComments = P $ \s@(PState { prev_loc = prev_loc }) -> POk s p getLastLoc :: P PsSpan getLastLoc = P $ \s@(PState { last_loc = last_loc }) -> POk s last_loc -data AlexInput = AI !PsLoc !StringBuffer deriving (Show) - -{- -Note [Unicode in Alex] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Although newer versions of Alex support unicode, this grammar is processed with -the old style '--latin1' behaviour. This means that when implementing the -functions - - alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) - alexInputPrevChar :: AlexInput -> Char - -which Alex uses to take apart our 'AlexInput', we must - - * return a latin1 character in the 'Word8' that 'alexGetByte' expects - * return a latin1 character in 'alexInputPrevChar'. - -We handle this in 'adjustChar' by squishing entire classes of unicode -characters into single bytes. --} - -{-# INLINE adjustChar #-} -adjustChar :: Char -> Word8 -adjustChar c = adj_c - where non_graphic = 0x00 - upper = 0x01 - lower = 0x02 - digit = 0x03 - symbol = 0x04 - space = 0x05 - other_graphic = 0x06 - uniidchar = 0x07 - - adj_c - | c <= '\x07' = non_graphic - | c <= '\x7f' = fromIntegral (ord c) - -- Alex doesn't handle Unicode, so when Unicode - -- character is encountered we output these values - -- with the actual character value hidden in the state. - | otherwise = - -- NB: The logic behind these definitions is also reflected - -- in "GHC.Utils.Lexeme" - -- Any changes here should likely be reflected there. - - case generalCategory c of - UppercaseLetter -> upper - LowercaseLetter -> lower - TitlecaseLetter -> upper - ModifierLetter -> uniidchar -- see #10196 - OtherLetter -> lower -- see #1103 - NonSpacingMark -> uniidchar -- see #7650 - SpacingCombiningMark -> other_graphic - EnclosingMark -> other_graphic - DecimalNumber -> digit - LetterNumber -> digit - OtherNumber -> digit -- see #4373 - ConnectorPunctuation -> symbol - DashPunctuation -> symbol - OpenPunctuation -> other_graphic - ClosePunctuation -> other_graphic - InitialQuote -> other_graphic - FinalQuote -> other_graphic - OtherPunctuation -> symbol - MathSymbol -> symbol - CurrencySymbol -> symbol - ModifierSymbol -> symbol - OtherSymbol -> symbol - Space -> space - _other -> non_graphic - --- Getting the previous 'Char' isn't enough here - we need to convert it into --- the same format that 'alexGetByte' would have produced. --- --- See Note [Unicode in Alex] and #13986. -alexInputPrevChar :: AlexInput -> Char -alexInputPrevChar (AI _ buf) = unsafeChr (fromIntegral (adjustChar pc)) - where pc = prevChar buf '\n' - -unsafeChr :: Int -> Char -unsafeChr (I# c) = GHC.Exts.C# (GHC.Exts.chr# c) - --- backwards compatibility for Alex 2.x -alexGetChar :: AlexInput -> Maybe (Char,AlexInput) -alexGetChar inp = case alexGetByte inp of - Nothing -> Nothing - Just (b,i) -> c `seq` Just (c,i) - where c = unsafeChr $ fromIntegral b - --- See Note [Unicode in Alex] -alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) -alexGetByte (AI loc s) - | atEnd s = Nothing - | otherwise = byte `seq` loc' `seq` s' `seq` - --trace (show (ord c)) $ - Just (byte, (AI loc' s')) - where (c,s') = nextChar s - loc' = advancePsLoc loc c - byte = adjustChar c - {-# INLINE alexGetChar' #-} -- This version does not squash unicode characters, it is used when -- lexing strings. @@ -3470,6 +3369,7 @@ topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. +-- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} lexToken :: P (PsLocated Token) ===================================== compiler/GHC/Parser/Lexer/Interface.hs ===================================== @@ -0,0 +1,124 @@ +{-# LANGUAGE MagicHash #-} + +{- | +This module defines the types and functions necessary for an Alex-generated +lexer. + +https://haskell-alex.readthedocs.io/en/latest/api.html# +-} +module GHC.Parser.Lexer.Interface ( + AlexInput (..), + alexGetByte, + alexInputPrevChar, + + -- * Helpers + alexGetChar, + adjustChar, +) where + +import GHC.Prelude + +import Data.Char (GeneralCategory (..), generalCategory, ord) +import Data.Word (Word8) +import GHC.Data.StringBuffer (StringBuffer, atEnd, nextChar, prevChar) +import GHC.Exts +import GHC.Types.SrcLoc (PsLoc, advancePsLoc) + +data AlexInput = AI !PsLoc !StringBuffer deriving (Show) + +-- See Note [Unicode in Alex] +alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) +alexGetByte (AI loc s) + | atEnd s = Nothing + | otherwise = byte `seq` loc' `seq` s' `seq` + --trace (show (ord c)) $ + Just (byte, (AI loc' s')) + where (c,s') = nextChar s + loc' = advancePsLoc loc c + byte = adjustChar c + +-- Getting the previous 'Char' isn't enough here - we need to convert it into +-- the same format that 'alexGetByte' would have produced. +-- +-- See Note [Unicode in Alex] and #13986. +alexInputPrevChar :: AlexInput -> Char +alexInputPrevChar (AI _ buf) = unsafeChr (fromIntegral (adjustChar pc)) + where pc = prevChar buf '\n' + +-- backwards compatibility for Alex 2.x +alexGetChar :: AlexInput -> Maybe (Char,AlexInput) +alexGetChar inp = case alexGetByte inp of + Nothing -> Nothing + Just (b,i) -> c `seq` Just (c,i) + where c = unsafeChr $ fromIntegral b + +unsafeChr :: Int -> Char +unsafeChr (I# c) = GHC.Exts.C# (GHC.Exts.chr# c) + +{- +Note [Unicode in Alex] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Although newer versions of Alex support unicode, this grammar is processed with +the old style '--latin1' behaviour. This means that when implementing the +functions + + alexGetByte :: AlexInput -> Maybe (Word8,AlexInput) + alexInputPrevChar :: AlexInput -> Char + +which Alex uses to take apart our 'AlexInput', we must + + * return a latin1 character in the 'Word8' that 'alexGetByte' expects + * return a latin1 character in 'alexInputPrevChar'. + +We handle this in 'adjustChar' by squishing entire classes of unicode +characters into single bytes. +-} + +{-# INLINE adjustChar #-} +adjustChar :: Char -> Word8 +adjustChar c = adj_c + where non_graphic = 0x00 + upper = 0x01 + lower = 0x02 + digit = 0x03 + symbol = 0x04 + space = 0x05 + other_graphic = 0x06 + uniidchar = 0x07 + + adj_c + | c <= '\x07' = non_graphic + | c <= '\x7f' = fromIntegral (ord c) + -- Alex doesn't handle Unicode, so when Unicode + -- character is encountered we output these values + -- with the actual character value hidden in the state. + | otherwise = + -- NB: The logic behind these definitions is also reflected + -- in "GHC.Utils.Lexeme" + -- Any changes here should likely be reflected there. + + case generalCategory c of + UppercaseLetter -> upper + LowercaseLetter -> lower + TitlecaseLetter -> upper + ModifierLetter -> uniidchar -- see #10196 + OtherLetter -> lower -- see #1103 + NonSpacingMark -> uniidchar -- see #7650 + SpacingCombiningMark -> other_graphic + EnclosingMark -> other_graphic + DecimalNumber -> digit + LetterNumber -> digit + OtherNumber -> digit -- see #4373 + ConnectorPunctuation -> symbol + DashPunctuation -> symbol + OpenPunctuation -> other_graphic + ClosePunctuation -> other_graphic + InitialQuote -> other_graphic + FinalQuote -> other_graphic + OtherPunctuation -> symbol + MathSymbol -> symbol + CurrencySymbol -> symbol + ModifierSymbol -> symbol + OtherSymbol -> symbol + Space -> space + _other -> non_graphic ===================================== compiler/GHC/Parser/Lexer/String.x ===================================== @@ -0,0 +1,96 @@ +{ +{- | +This module defines lex states for strings. + +This needs to be separate from the normal lexer because the normal lexer +automatically includes rules like skipping whitespace or lexing comments, +which we don't want in these contexts. +-} +module GHC.Parser.Lexer.String ( + AlexReturn (..), + alexScan, + string_multi_content, +) where + +import GHC.Prelude + +import GHC.Parser.Lexer.Interface +import GHC.Utils.Panic (panic) +} + +-- ----------------------------------------------------------------------------- +-- Alex "Character set macros" +-- Copied from GHC/Parser/Lexer.x + +$unispace = \x05 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$nl = [\n\r\f] +$space = [\ $unispace] +$whitechar = [$nl \v $space] +$tab = \t + +$ascdigit = 0-9 +$unidigit = \x03 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$decdigit = $ascdigit -- exactly $ascdigit, no more no less. +$digit = [$ascdigit $unidigit] + +$special = [\(\)\,\;\[\]\`\{\}] +$ascsymbol = [\!\#\$\%\&\*\+\.\/\<\=\>\?\@\\\^\|\-\~\:] +$unisymbol = \x04 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$symbol = [$ascsymbol $unisymbol] # [$special \_\"\'] + +$unilarge = \x01 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$asclarge = [A-Z] +$large = [$asclarge $unilarge] + +$unismall = \x02 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$ascsmall = [a-z] +$small = [$ascsmall $unismall \_] + +$uniidchar = \x07 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$idchar = [$small $large $digit $uniidchar \'] + +$unigraphic = \x06 -- Trick Alex into handling Unicode. See Note [Unicode in Alex]. +$graphic = [$small $large $symbol $digit $idchar $special $unigraphic \"\'] +$charesc = [a b f n r t v \\ \" \' \&] + +$octit = 0-7 +$hexit = [$decdigit A-F a-f] + +-- ----------------------------------------------------------------------------- +-- Alex "Regular expression macros" +-- Copied from GHC/Parser/Lexer.x + + at numspc = _* -- numeric spacer (#14473) + at decimal = $decdigit(@numspc $decdigit)* + at octal = $octit(@numspc $octit)* + at hexadecimal = $hexit(@numspc $hexit)* + at gap = \\ $whitechar+ \\ + at cntrl = $asclarge | \@ | \[ | \\ | \] | \^ | \_ + at ascii = \^ @cntrl | "NUL" | "SOH" | "STX" | "ETX" | "EOT" | "ENQ" | "ACK" + | "BEL" | "BS" | "HT" | "LF" | "VT" | "FF" | "CR" | "SO" | "SI" | "DLE" + | "DC1" | "DC2" | "DC3" | "DC4" | "NAK" | "SYN" | "ETB" | "CAN" + | "EM" | "SUB" | "ESC" | "FS" | "GS" | "RS" | "US" | "SP" | "DEL" + at escape = \\ ( $charesc | @ascii | @decimal | o @octal | x @hexadecimal ) + at stringchar = ($graphic # [\\ \"]) | $space | @escape | @gap + +:- + +-- Define an empty rule so it compiles; callers should always explicitly specify a startcode +<0> () ; + +-- See Note [Lexing multiline strings] + { + -- Parse as much of the multiline string as possible, except for quotes + @stringchar* ($nl ([\ $tab] | @gap)* @stringchar*)* { string_multi_content_action } + -- Allow bare quotes if it's not a triple quote + (\" | \"\") / ([\n .] # \") { string_multi_content_action } +} + +-- ----------------------------------------------------------------------------- +-- Haskell actions +{ +-- | Dummy action that should never be called. Should only be used in lex states +-- that are manually lexed in tok_string_multi. +string_multi_content_action :: a +string_multi_content_action = panic "string_multi_content_action unexpectedly invoked" +} ===================================== compiler/ghc.cabal.in ===================================== @@ -646,6 +646,8 @@ Library GHC.Parser.Errors.Types GHC.Parser.Header GHC.Parser.Lexer + GHC.Parser.Lexer.Interface + GHC.Parser.Lexer.String GHC.Parser.HaddockLex GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock ===================================== hadrian/src/Rules/SourceDist.hs ===================================== @@ -185,6 +185,7 @@ prepareTree dest = do , (stage0InTree , compiler, "GHC/Cmm/Lexer.x", "GHC/Cmm/Lexer.hs") , (stage0InTree , compiler, "GHC/Parser.y", "GHC/Parser.hs") , (stage0InTree , compiler, "GHC/Parser/Lexer.x", "GHC/Parser/Lexer.hs") + , (stage0InTree , compiler, "GHC/Parser/Lexer/String.x", "GHC/Parser/Lexer/String.hs") , (stage0InTree , compiler, "GHC/Parser/HaddockLex.x", "GHC/Parser/HaddockLex.hs") , (stage0InTree , hpcBin, "src/Trace/Hpc/Parser.y", "src/Trace/Hpc/Parser.hs") , (stage0InTree , genprimopcode, "Parser.y", "Parser.hs") ===================================== testsuite/tests/bytecode/T24634/Makefile ===================================== @@ -4,14 +4,14 @@ include $(TOP)/mk/test.mk # This case loads bytecode from the interface file written in the second invocation. T24634a: - '$(TEST_HC)' -c hello_c.c -o hello_c.o - '$(TEST_HC)' -c -fbyte-code-and-object-code -fno-omit-interface-pragmas Hello.hs - '$(TEST_HC)' -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Main.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -c hello_c.c -o hello_c.o + '$(TEST_HC)' $(TEST_HC_OPTS) -c -fbyte-code-and-object-code -fno-omit-interface-pragmas Hello.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Main.hs ./Main # This case uses the bytecode generated in 'runHscBackendPhase', not involving the interface, since 'Hello' is compiled # in the same invocation as 'Main'. T24634b: - '$(TEST_HC)' -c hello_c.c -o hello_c.o - '$(TEST_HC)' -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Hello.hs Main.hs + '$(TEST_HC)' $(TEST_HC_OPTS) -c hello_c.c -o hello_c.o + '$(TEST_HC)' $(TEST_HC_OPTS) -fprefer-byte-code -fbyte-code-and-object-code -fno-ignore-interface-pragmas hello_c.o Hello.hs Main.hs ./Main ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -79,4 +79,4 @@ T17648: grep -F 'f :: T GHC.Types.Int -> () [TagSig' >/dev/null T25166: - '$(TEST_HC)' -O2 -dno-typeable-binds -ddump-cmm T25166.hs | awk '/foo_closure/{flag=1}/}]/{flag=0}flag' + '$(TEST_HC)' $(TEST_HC_OPTS) -O2 -dno-typeable-binds -ddump-cmm T25166.hs | awk '/foo_closure/{flag=1}/}]/{flag=0}flag' ===================================== testsuite/tests/count-deps/CountDepsParser.stdout ===================================== @@ -127,6 +127,8 @@ GHC.Parser.Errors.Ppr GHC.Parser.Errors.Types GHC.Parser.HaddockLex GHC.Parser.Lexer +GHC.Parser.Lexer.Interface +GHC.Parser.Lexer.String GHC.Parser.PostProcess GHC.Parser.PostProcess.Haddock GHC.Parser.String ===================================== testsuite/tests/driver/j-space/jspace.hs ===================================== @@ -23,7 +23,7 @@ initGhcM :: [String] -> Ghc () initGhcM xs = do session <- getSession df1 <- getSessionDynFlags - let cmdOpts = ["-fforce-recomp"] ++ xs + let cmdOpts = ["-fforce-recomp", "-dno-debug-output"] ++ xs (df2, leftovers, _) <- parseDynamicFlags (hsc_logger session) df1 (map noLoc cmdOpts) setSessionDynFlags df2 ghcUnitId <- case lookup "Project Unit Id" (compilerInfo df2) of ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.hs ===================================== @@ -99,3 +99,6 @@ main = do 0x_ff == 0xff, 0x__ff == 0xff ] + + -- ensure that strings are unaffected + print ["\o16_000", "\16_000", "\x16_000"] ===================================== testsuite/tests/parser/should_run/NumericUnderscores0.stdout ===================================== @@ -11,3 +11,4 @@ [True,True,True] [True,True,True] [True,True,True,True,True,True,True,True,True,True,True,True,True,True,True] +["\SO_000","\DLE_000","\SYN_000"] ===================================== testsuite/tests/parser/should_run/T25609.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE MultilineStrings #-} + +main :: IO () +main = do + -- strings with comment tokens + print """{- asdf -}""" + print """a {- asdf -} b""" + print """-- asdf""" + print """{-""" + + -- strings with haddock comments + print """{- | test -}""" + print """{- * test -}""" + print """{- ^ test -}""" + print """{- $ test -}""" + print """-- | test""" + print """-- * test""" + print """-- ^ test""" + print """-- $ test""" + + -- strings with only whitespace + print """ """ + print """ + + + """ + + -- strings with unicode + print """ + ★ + ★ + ★ + ★ + """ ===================================== testsuite/tests/parser/should_run/T25609.stdout ===================================== @@ -0,0 +1,15 @@ +"{- asdf -}" +"a {- asdf -} b" +"-- asdf" +"{-" +"{- | test -}" +"{- * test -}" +"{- ^ test -}" +"{- $ test -}" +"-- | test" +"-- * test" +"-- ^ test" +"-- $ test" +" " +"\n" +" \9733\n\9733\n \9733\n\9733" ===================================== testsuite/tests/parser/should_run/all.T ===================================== @@ -21,6 +21,9 @@ test('RecordDotSyntax3', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compil test('RecordDotSyntax4', [extra_files(['RecordDotSyntaxA.hs'])], multimod_compile_and_run, ['RecordDotSyntax4', '']) test('RecordDotSyntax5', normal, compile_and_run, ['']) test('ListTuplePunsConstraints', extra_files(['ListTuplePunsConstraints.hs']), ghci_script, ['ListTuplePunsConstraints.script']) + +# Multiline strings test('MultilineStrings', normal, compile_and_run, ['']) test('MultilineStringsOverloaded', normal, compile_and_run, ['']) test('T25375', normal, compile_and_run, ['']) +test('T25609', normal, compile_and_run, ['']) ===================================== testsuite/tests/patsyn/should_compile/T13350/Makefile ===================================== @@ -7,7 +7,7 @@ LOCAL_PKGCONF=local.package.conf T13350: "$(GHC_PKG)" init $(LOCAL_PKGCONF) cd boolean && "$(TEST_HC)" $(TEST_HC_OPTS) -v0 --make Setup.hs - cd boolean && ./Setup configure -v0 --with-compiler="$(TEST_HC)" --with-hc-pkg="$(GHC_PKG)" --package-db=../$(LOCAL_PKGCONF) + cd boolean && ./Setup configure -v0 --with-compiler="$(TEST_HC)" --ghc-options='$(filter-out -rtsopts,$(TEST_HC_OPTS))' --with-hc-pkg="$(GHC_PKG)" --package-db=../$(LOCAL_PKGCONF) cd boolean && ./Setup build -v0 cd boolean && ./Setup register -v0 --inplace "$(TEST_HC)" $(TEST_HC_OPTS) -c T13350.hs -package-db $(LOCAL_PKGCONF) ===================================== testsuite/tests/rts/Makefile ===================================== @@ -82,7 +82,7 @@ T10296a: .PHONY: T11788 T11788: - "$(TEST_HC)" -c T11788.c -o T11788_obj.o + "$(TEST_HC)" $(TEST_HC_OPTS) -c T11788.c -o T11788_obj.o "$(AR)" rsT libT11788.a T11788_obj.o 2> /dev/null echo main | "$(TEST_HC)" $(filter-out -rtsopts, $(TEST_HC_OPTS_INTERACTIVE)) T11788.hs -lT11788 -L"$(PWD)" @@ -101,13 +101,13 @@ T14695: .PHONY: InternalCounters InternalCounters: - "$(TEST_HC)" +RTS -s --internal-counters -RTS 2>&1 | grep "Internal Counters" - -"$(TEST_HC)" +RTS -s -RTS 2>&1 | grep "Internal Counters" + "$(TEST_HC)" $(TEST_HC_OPTS) +RTS -s --internal-counters -RTS 2>&1 | grep "Internal Counters" + -"$(TEST_HC)" $(TEST_HC_OPTS) +RTS -s -RTS 2>&1 | grep "Internal Counters" .PHONY: KeepCafsFail KeepCafsFail: - "$(TEST_HC)" -c -g -v0 KeepCafsBase.hs KeepCafs1.hs KeepCafs2.hs - "$(TEST_HC)" -g -v0 KeepCafsMain.hs KeepCafsBase.o -debug -rdynamic -fwhole-archive-hs-libs $(KEEPCAFS) + "$(TEST_HC)" $(TEST_HC_OPTS) -c -g -v0 KeepCafsBase.hs KeepCafs1.hs KeepCafs2.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -g -v0 KeepCafsMain.hs KeepCafsBase.o -debug -rdynamic -fwhole-archive-hs-libs $(KEEPCAFS) ./KeepCafsMain 2>&1 || echo "exit($$?)" .PHONY: KeepCafs @@ -116,37 +116,37 @@ KeepCafs: .PHONY: EventlogOutput1 EventlogOutput1: - "$(TEST_HC)" -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -v0 EventlogOutput.hs ./EventlogOutput +RTS -l -olhello.eventlog ls hello.eventlog >/dev/null .PHONY: EventlogOutput2 EventlogOutput2: - "$(TEST_HC)" -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -v0 EventlogOutput.hs ./EventlogOutput +RTS -l ls EventlogOutput.eventlog >/dev/null .PHONY: EventlogOutputNull EventlogOutputNull: - "$(TEST_HC)" -rtsopts -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -rtsopts -v0 EventlogOutput.hs ./EventlogOutput +RTS -l --null-eventlog-writer test ! -e EventlogOutput.eventlog .PHONY: T20199 T20199: - "$(TEST_HC)" -no-hs-main -optcxx-std=c++11 -v0 T20199.cpp -o T20199 + "$(TEST_HC)" $(TEST_HC_OPTS) -no-hs-main -optcxx-std=c++11 -v0 T20199.cpp -o T20199 ./T20199 .PHONY: EventlogOutput_IPE EventlogOutput_IPE: - "$(TEST_HC)" -debug -finfo-table-map -v0 EventlogOutput.hs + "$(TEST_HC)" $(TEST_HC_OPTS) -debug -finfo-table-map -v0 EventlogOutput.hs ./EventlogOutput +RTS -va 2> EventlogOutput_IPE.stderr.log grep "IPE:" EventlogOutput_IPE.stderr.log .PHONY: T23142 T23142: # Test that the -Di output contains different frames - "$(TEST_HC)" --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log + "$(TEST_HC)" $(TEST_HC_OPTS) --run -ignore-dot-ghci T23142.hs +RTS -Di -RTS 2> T23142.log grep -m1 -c "ATOMICALLY_FRAME" T23142.log grep -m1 -c "CATCH_RETRY_FRAME" T23142.log grep -m1 -c "CATCH_STM_FRAME" T23142.log ===================================== testsuite/tests/rts/T1791/Makefile ===================================== @@ -3,4 +3,4 @@ include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk T1791: - '$(TEST_HC)' T1791.hs -o T1791 -O -rtsopts + '$(TEST_HC)' $(TEST_HC_OPTS) T1791.hs -o T1791 -O -rtsopts ===================================== testsuite/tests/wasm/should_run/control-flow/WasmControlFlow.hs ===================================== @@ -41,6 +41,7 @@ main = do `xopt_set` LangExt.StandaloneKindSignatures `xopt_set` LangExt.UnliftedDatatypes `xopt_set` LangExt.DataKinds + `dopt_set` Opt_D_no_debug_output setSessionDynFlags dflags groups <- mapM loadPath files liftIO $ do ===================================== utils/hp2ps/Utilities.c ===================================== @@ -3,7 +3,7 @@ #include #include "Error.h" -extern void* malloc(long unsigned int); +extern void* malloc(size_t); char* Basename(char *name) @@ -89,7 +89,7 @@ void * xrealloc(void *p, size_t n) { void *r; - extern void *realloc(void *, long unsigned int); + extern void *realloc(void *, size_t); r = realloc(p, n); if (!r) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b8e8664bfa45fdc351de23f2277262487635647...cfd0b33860039d4b60693a73fb189440bcc10bd8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7b8e8664bfa45fdc351de23f2277262487635647...cfd0b33860039d4b60693a73fb189440bcc10bd8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 00:32:28 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 24 Jan 2025 19:32:28 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: Merge ghc-prim's modules into ghc-internal (#24453) Message-ID: <6794311c57d33_b809fc5a08188fc@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6b3cd72f by Sylvain Henry at 2025-01-24T19:32:06-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - b75dd114 by Jens Petersen at 2025-01-24T19:32:06-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser/Header.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/ModSummary.hs - compiler/GHC/Unit/Types.hs - hadrian/src/Flavour.hs - hadrian/src/Packages.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Packages.hs - hadrian/src/Settings/Warnings.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-experimental/ghc-experimental.cabal.in - libraries/ghc-experimental/src/Data/Sum/Experimental.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/282aad76a9cf76dd9ff5ec1e2ec07faccd277a58...b75dd11435c7038a18098e147e26642f01c1d405 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/282aad76a9cf76dd9ff5ec1e2ec07faccd277a58...b75dd11435c7038a18098e147e26642f01c1d405 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 00:55:58 2025 From: gitlab at gitlab.haskell.org (Serge S. Gulin (@gulin.serge)) Date: Fri, 24 Jan 2025 19:55:58 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T24603 Message-ID: <6794369e23e1f_b809f921c4c215ad@gitlab.mail> Serge S. Gulin pushed new branch wip/T24603 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T24603 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 02:13:42 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Fri, 24 Jan 2025 21:13:42 -0500 Subject: [Git][ghc/ghc][wip/T25623] Fix for alex-3.5.2.0 (#25623) Message-ID: <679448d61561f_b809f1503ccc3718a@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 4aefca34 by Brandon Chinn at 2025-01-24T18:13:33-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 1 changed file: - compiler/GHC/Parser/Lexer.x Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3467,10 +3468,12 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. {-# INLINE alexScanUser #-} +#endif lexToken :: P (PsLocated Token) lexToken = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4aefca346244e071943fa981ecaf91c5507fab80 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4aefca346244e071943fa981ecaf91c5507fab80 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 04:12:42 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 24 Jan 2025 23:12:42 -0500 Subject: [Git][ghc/ghc][master] Merge ghc-prim's modules into ghc-internal (#24453) Message-ID: <679464baad13f_103ecd134bf8835789@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c3593101 by Sylvain Henry at 2025-01-24T23:12:20-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser/Header.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/ModSummary.hs - compiler/GHC/Unit/Types.hs - hadrian/src/Flavour.hs - hadrian/src/Packages.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Packages.hs - hadrian/src/Settings/Warnings.hs - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-experimental/ghc-experimental.cabal.in - libraries/ghc-experimental/src/Data/Sum/Experimental.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c3593101c85f90aeb0e9aa171a179bc2598d69ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c3593101c85f90aeb0e9aa171a179bc2598d69ad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 04:13:27 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Fri, 24 Jan 2025 23:13:27 -0500 Subject: [Git][ghc/ghc][master] hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Message-ID: <679464e7d84e2_103ecd14aee98385ee@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 70f7741a by Jens Petersen at 2025-01-24T23:12:58-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - 1 changed file: - utils/hp2ps/Utilities.c Changes: ===================================== utils/hp2ps/Utilities.c ===================================== @@ -3,7 +3,7 @@ #include #include "Error.h" -extern void* malloc(long unsigned int); +extern void* malloc(size_t); char* Basename(char *name) @@ -89,7 +89,7 @@ void * xrealloc(void *p, size_t n) { void *r; - extern void *realloc(void *, long unsigned int); + extern void *realloc(void *, size_t); r = realloc(p, n); if (!r) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/70f7741acd9d50a6cc07553aeaae600afe4a72b8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/70f7741acd9d50a6cc07553aeaae600afe4a72b8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 10:12:16 2025 From: gitlab at gitlab.haskell.org (Serge S. Gulin (@gulin.serge)) Date: Sat, 25 Jan 2025 05:12:16 -0500 Subject: [Git][ghc/ghc][wip/T24603] Support for ARM64 Windows (LLVM-enabled) (fixes #24603) Message-ID: <6794b900318f5_1fa6cf9f65c8117244@gitlab.mail> Serge S. Gulin pushed to branch wip/T24603 at Glasgow Haskell Compiler / GHC Commits: 2f77bef5 by Serge S. Gulin at 2025-01-25T13:01:17+03:00 Support for ARM64 Windows (LLVM-enabled) (fixes #24603) submodule Co-authored-by: Cheng Shao <terrorjack at type.dance> Co-authored-by: Dmitrii Egorov <egorov.d.i at icloud.com> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> - - - - - 13 changed files: - hadrian/cabal.project - libraries/Cabal - libraries/Win32 - libraries/base/src/System/CPUTime/Windows.hsc - libraries/directory - libraries/haskeline - libraries/process - libraries/unix - llvm-targets - rts/StgCRun.c - rts/win32/veh_excn.c - utils/hsc2hs - utils/llvm-targets/gen-data-layout.sh Changes: ===================================== hadrian/cabal.project ===================================== @@ -8,7 +8,7 @@ index-state: 2024-10-30T22:56:00Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 -allow-newer: unordered-containers:template-haskell +allow-newer: unordered-containers:template-haskell, splitmix:base, hashable:base, cryptohash-sha256:base -- N.B. Compile with -O0 since this is not a performance-critical executable -- and the Cabal takes nearly twice as long to build with -O1. See #16817. ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 269fd808e5d80223a229b6b19edfe6f5b109007a +Subproject commit 682c54a9e8127c79e714545dbf493bb5de470945 ===================================== libraries/Win32 ===================================== @@ -1 +1 @@ -Subproject commit 027cbcf0de25d681823ea92fb545a2604c3a6a8b +Subproject commit f340d2c3d846fce73117dd2548ad1bf0c56ceb9d ===================================== libraries/base/src/System/CPUTime/Windows.hsc ===================================== @@ -60,7 +60,7 @@ type HANDLE = () #if defined(i386_HOST_ARCH) foreign import stdcall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import stdcall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt -#elif defined(x86_64_HOST_ARCH) +#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) foreign import ccall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import ccall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt #else ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 005fa061171a55d35ce8dfe936cf3703525a8616 +Subproject commit eb40bbebcaf86153bbc60772fb2e0466d35c95c4 ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 5f4bf62bf1f4846ad0b8d1fa9d45f902e3934511 +Subproject commit 05d83f5f061e2fe8beb0ac23519aa3df0ee22d6f ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 9c3bfc214c72bbd0c8a30a1c41465deed0feaf47 +Subproject commit fbbe60718736999db701c12528c85cbc605ab4fb ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 74ae1c0d9dd1518434f7d6cd3e63d7769599e0f9 +Subproject commit 9208d3a5809476e64b9a387a6000821083d1ebfd ===================================== llvm-targets ===================================== @@ -1,4 +1,5 @@ [("x86_64-unknown-windows-gnu", ("e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "")) +,("aarch64-unknown-windows-gnu", ("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32", "generic", "+v8a +fp-armv8 +neon")) ,("arm-unknown-linux-gnueabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm7tdmi", "+strict-align")) ,("arm-unknown-linux-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ,("arm-unknown-linux-musleabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ===================================== rts/StgCRun.c ===================================== @@ -863,8 +863,12 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { */ "br %1\n\t" +#if defined(mingw32_HOST_OS) + ".globl " STG_RETURN "\n" +#else ".globl " STG_RETURN "\n\t" -#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) +#endif +#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) && !defined(mingw32_HOST_OS) ".type " STG_RETURN ", %%function\n" #endif STG_RETURN ":\n\t" ===================================== rts/win32/veh_excn.c ===================================== @@ -287,6 +287,16 @@ void generateStack (EXCEPTION_POINTERS* pExceptionPointers) stackFrame.AddrStack.Offset = context->Rsp; stackFrame.AddrStack.Mode = AddrModeFlat; +#elif defined(aarch64_HOST_ARCH) + machineType = IMAGE_FILE_MACHINE_ARM64; + stackFrame.AddrPC.Offset = context->Pc; + stackFrame.AddrPC.Mode = AddrModeFlat; + + stackFrame.AddrFrame.Offset = context->Fp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + + stackFrame.AddrStack.Offset = context->Sp; + stackFrame.AddrStack.Mode = AddrModeFlat; #endif fprintf (stderr, "\n Attempting to reconstruct a stack trace...\n\n"); if (!SymInitialize (GetCurrentProcess (), NULL, true)) ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit c3b21800a67366c9591dc85a471d1dfdb1efcf29 +Subproject commit 2fab2f4cdffef12afe561ef03f5ebdace7dbae67 ===================================== utils/llvm-targets/gen-data-layout.sh ===================================== @@ -27,6 +27,7 @@ TARGETS=( # Windows "x86_64-unknown-windows-gnu" + "aarch64-unknown-windows-gnu" ######################### # Linux View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2f77bef5fb9da0acce7a7734eef8eb5230f14906 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2f77bef5fb9da0acce7a7734eef8eb5230f14906 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 14:32:47 2025 From: gitlab at gitlab.haskell.org (Serge S. Gulin (@gulin.serge)) Date: Sat, 25 Jan 2025 09:32:47 -0500 Subject: [Git][ghc/ghc][wip/T24603] Support for ARM64 Windows (LLVM-enabled) (fixes #24603) Message-ID: <6794f60f17f5a_26b27810b9b8083f1@gitlab.mail> Serge S. Gulin pushed to branch wip/T24603 at Glasgow Haskell Compiler / GHC Commits: 612da63c by Serge S. Gulin at 2025-01-25T17:32:20+03:00 Support for ARM64 Windows (LLVM-enabled) (fixes #24603) submodule Co-authored-by: Cheng Shao <terrorjack at type.dance> Co-authored-by: Dmitrii Egorov <egorov.d.i at icloud.com> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> - - - - - 13 changed files: - hadrian/cabal.project - libraries/Cabal - libraries/Win32 - libraries/base/src/System/CPUTime/Windows.hsc - libraries/directory - libraries/haskeline - libraries/process - libraries/unix - llvm-targets - rts/StgCRun.c - rts/win32/veh_excn.c - utils/hsc2hs - utils/llvm-targets/gen-data-layout.sh Changes: ===================================== hadrian/cabal.project ===================================== @@ -8,7 +8,7 @@ index-state: 2024-10-30T22:56:00Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 -allow-newer: unordered-containers:template-haskell +allow-newer: unordered-containers:template-haskell, splitmix:base, hashable:base, cryptohash-sha256:base -- N.B. Compile with -O0 since this is not a performance-critical executable -- and the Cabal takes nearly twice as long to build with -O1. See #16817. ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 269fd808e5d80223a229b6b19edfe6f5b109007a +Subproject commit 682c54a9e8127c79e714545dbf493bb5de470945 ===================================== libraries/Win32 ===================================== @@ -1 +1 @@ -Subproject commit 027cbcf0de25d681823ea92fb545a2604c3a6a8b +Subproject commit f340d2c3d846fce73117dd2548ad1bf0c56ceb9d ===================================== libraries/base/src/System/CPUTime/Windows.hsc ===================================== @@ -60,7 +60,7 @@ type HANDLE = () #if defined(i386_HOST_ARCH) foreign import stdcall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import stdcall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt -#elif defined(x86_64_HOST_ARCH) +#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) foreign import ccall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import ccall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt #else ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 005fa061171a55d35ce8dfe936cf3703525a8616 +Subproject commit eb40bbebcaf86153bbc60772fb2e0466d35c95c4 ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 5f4bf62bf1f4846ad0b8d1fa9d45f902e3934511 +Subproject commit 5f1a790a5db1cb3708d105d4f532c32fcbeb4296 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 9c3bfc214c72bbd0c8a30a1c41465deed0feaf47 +Subproject commit fbbe60718736999db701c12528c85cbc605ab4fb ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 74ae1c0d9dd1518434f7d6cd3e63d7769599e0f9 +Subproject commit 9208d3a5809476e64b9a387a6000821083d1ebfd ===================================== llvm-targets ===================================== @@ -1,4 +1,5 @@ [("x86_64-unknown-windows-gnu", ("e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "")) +,("aarch64-unknown-windows-gnu", ("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32", "generic", "+v8a +fp-armv8 +neon")) ,("arm-unknown-linux-gnueabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm7tdmi", "+strict-align")) ,("arm-unknown-linux-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ,("arm-unknown-linux-musleabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ===================================== rts/StgCRun.c ===================================== @@ -863,8 +863,12 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { */ "br %1\n\t" +#if defined(mingw32_HOST_OS) + ".globl " STG_RETURN "\n" +#else ".globl " STG_RETURN "\n\t" -#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) +#endif +#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) && !defined(mingw32_HOST_OS) ".type " STG_RETURN ", %%function\n" #endif STG_RETURN ":\n\t" ===================================== rts/win32/veh_excn.c ===================================== @@ -287,6 +287,16 @@ void generateStack (EXCEPTION_POINTERS* pExceptionPointers) stackFrame.AddrStack.Offset = context->Rsp; stackFrame.AddrStack.Mode = AddrModeFlat; +#elif defined(aarch64_HOST_ARCH) + machineType = IMAGE_FILE_MACHINE_ARM64; + stackFrame.AddrPC.Offset = context->Pc; + stackFrame.AddrPC.Mode = AddrModeFlat; + + stackFrame.AddrFrame.Offset = context->Fp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + + stackFrame.AddrStack.Offset = context->Sp; + stackFrame.AddrStack.Mode = AddrModeFlat; #endif fprintf (stderr, "\n Attempting to reconstruct a stack trace...\n\n"); if (!SymInitialize (GetCurrentProcess (), NULL, true)) ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit c3b21800a67366c9591dc85a471d1dfdb1efcf29 +Subproject commit 2fab2f4cdffef12afe561ef03f5ebdace7dbae67 ===================================== utils/llvm-targets/gen-data-layout.sh ===================================== @@ -27,6 +27,7 @@ TARGETS=( # Windows "x86_64-unknown-windows-gnu" + "aarch64-unknown-windows-gnu" ######################### # Linux View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/612da63c1dc13a4d9a8ee1cefcf6c3343581d5ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/612da63c1dc13a4d9a8ee1cefcf6c3343581d5ea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 16:35:55 2025 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Sat, 25 Jan 2025 11:35:55 -0500 Subject: [Git][ghc/ghc][wip/supersven/riscv-vectors] 12 commits: Add comment about vector registers in allocatableRegs Message-ID: <679512eb42694_2e40e75915a010447@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-vectors at Glasgow Haskell Compiler / GHC Commits: 80022d79 by Sven Tennie at 2025-01-10T18:19:00+01:00 Add comment about vector registers in allocatableRegs - - - - - 3312b409 by Sven Tennie at 2025-01-10T18:19:29+01:00 Formatting - - - - - 5c1e6851 by Sven Tennie at 2025-01-10T18:48:04+01:00 Adjust TODO - - - - - a51c11f8 by Sven Tennie at 2025-01-19T16:14:29+01:00 Delete unused function - - - - - b2fd45e2 by Sven Tennie at 2025-01-25T15:05:34+01:00 WIP: Use Format instead of Width in OpReg Operand Ints, floats and vectors are very different things. So, it is very helpful to know to which of this three an OpReg Operand relates. - - - - - 4bcb4ddd by Sven Tennie at 2025-01-25T15:15:27+01:00 Simplify VID - - - - - 4ddc51ae by Sven Tennie at 2025-01-25T15:23:27+01:00 Simplify VMV - - - - - 153016bd by Sven Tennie at 2025-01-25T15:37:48+01:00 Simplify VMERGE - - - - - 90cea4e6 by Sven Tennie at 2025-01-25T15:42:54+01:00 Simplify VSLIDEDOWN - - - - - 52b65116 by Sven Tennie at 2025-01-25T15:56:41+01:00 Simplify other vector instructions - - - - - c2fb7c65 by Sven Tennie at 2025-01-25T16:02:39+01:00 Simplify VFMA - - - - - 715a80b1 by Sven Tennie at 2025-01-25T17:34:57+01:00 regUsageOfInstr with correct format - - - - - 6 changed files: - compiler/GHC/CmmToAsm/Format.hs - compiler/GHC/CmmToAsm/RV64.hs - compiler/GHC/CmmToAsm/RV64/CodeGen.hs - compiler/GHC/CmmToAsm/RV64/Instr.hs - compiler/GHC/CmmToAsm/RV64/Ppr.hs - compiler/GHC/CmmToAsm/RV64/Regs.hs Changes: ===================================== compiler/GHC/CmmToAsm/Format.hs ===================================== @@ -22,6 +22,8 @@ module GHC.CmmToAsm.Format ( intScalarFormat, isFloatFormat, vecFormat, + floatVecFormat, + intVecFormat, isVecFormat, cmmTypeFormat, formatToWidth, @@ -210,6 +212,12 @@ vecFormat ty = W64 -> VecFormat l FmtInt64 _ -> pprPanic "Incorrect vector element width" (ppr elemTy) +floatVecFormat :: Int -> Width -> Format +floatVecFormat length width = vecFormat (cmmVec length (cmmFloat width)) + +intVecFormat :: Int -> Width -> Format +intVecFormat length width = vecFormat (cmmVec length (cmmBits width)) + -- | Check if a format represents a vector isVecFormat :: Format -> Bool isVecFormat (VecFormat {}) = True ===================================== compiler/GHC/CmmToAsm/RV64.hs ===================================== @@ -49,7 +49,7 @@ instance Instruction RV64.Instr where mkLoadInstr = RV64.mkLoadInstr takeDeltaInstr = RV64.takeDeltaInstr isMetaInstr = RV64.isMetaInstr - mkRegRegMoveInstr _ _ = RV64.mkRegRegMoveInstr + mkRegRegMoveInstr _ = RV64.mkRegRegMoveInstr takeRegRegMoveInstr _ = RV64.takeRegRegMoveInstr mkJumpInstr = RV64.mkJumpInstr mkStackAllocInstr = RV64.mkStackAllocInstr ===================================== compiler/GHC/CmmToAsm/RV64/CodeGen.hs ===================================== @@ -290,13 +290,13 @@ genSwitch config expr targets = do `appOL` toOL [ COMMENT (ftext "Jump table for switch"), -- index to offset into the table (relative to tableReg) - annExpr expr (SLL (OpReg (formatToWidth fmt1) reg) (OpReg (formatToWidth fmt1) reg) (OpImm (ImmInt 3))), + annExpr expr (SLL (OpReg fmt1 reg) (OpReg fmt1 reg) (OpImm (ImmInt 3))), -- calculate table entry address - ADD (OpReg W64 targetReg) (OpReg (formatToWidth fmt1) reg) (OpReg (formatToWidth fmt2) tableReg), + ADD (OpReg II64 targetReg) (OpReg fmt1 reg) (OpReg fmt2 tableReg), -- load table entry (relative offset from tableReg (first entry) to target label) - LDRU II64 (OpReg W64 targetReg) (OpAddr (AddrRegImm targetReg (ImmInt 0))), + LDRU II64 (OpReg II64 targetReg) (OpAddr (AddrRegImm targetReg (ImmInt 0))), -- calculate absolute address of the target label - ADD (OpReg W64 targetReg) (OpReg W64 targetReg) (OpReg W64 tableReg), + ADD (OpReg II64 targetReg) (OpReg II64 targetReg) (OpReg II64 tableReg), -- prepare jump to target label J_TBL ids (Just lbl) targetReg ] @@ -575,80 +575,93 @@ getRegister' config plat expr = -- narrowU is important: Negative immediates may be -- sign-extended on load! let imm = OpImm . ImmInteger $ narrowU w i - in pure (Any (intFormat w) (\dst -> unitOL $ annExpr expr (MOV (OpReg w dst) imm))) + format = intFormat w + in pure $ Any format (\dst -> unitOL $ annExpr expr (MOV (OpReg format dst) imm)) CmmFloat 0 w -> do let op = litToImm' lit - pure (Any (floatFormat w) (\dst -> unitOL $ annExpr expr (MOV (OpReg w dst) op))) + format = floatFormat w + pure $ Any format (\dst -> unitOL $ annExpr expr (MOV (OpReg format dst) op)) CmmFloat _f W8 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for bytes" (pdoc plat expr) CmmFloat _f W16 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for halfs" (pdoc plat expr) CmmFloat f W32 -> do + -- TODO: Besides width, much duplication with the W64 case! let word = castFloatToWord32 (fromRational f) :: Word32 - intReg <- getNewRegNat (intFormat W32) + format_int = intFormat W32 + format_dst = floatFormat W32 + intReg <- getNewRegNat format_int return ( Any - (floatFormat W32) + format_dst ( \dst -> toOL [ annExpr expr - $ MOV (OpReg W32 intReg) (OpImm (ImmInteger (fromIntegral word))), - MOV (OpReg W32 dst) (OpReg W32 intReg) + $ MOV (OpReg format_int intReg) (OpImm (ImmInteger (fromIntegral word))), + MOV (OpReg format_dst dst) (OpReg format_int intReg) ] ) ) CmmFloat f W64 -> do let word = castDoubleToWord64 (fromRational f) :: Word64 - intReg <- getNewRegNat (intFormat W64) + format_int = intFormat W64 + format_dst = floatFormat W64 + intReg <- getNewRegNat format_int return ( Any - (floatFormat W64) + format_dst ( \dst -> toOL [ annExpr expr - $ MOV (OpReg W64 intReg) (OpImm (ImmInteger (fromIntegral word))), - MOV (OpReg W64 dst) (OpReg W64 intReg) + $ MOV (OpReg format_int intReg) (OpImm (ImmInteger (fromIntegral word))), + MOV (OpReg format_dst dst) (OpReg format_int intReg) ] ) ) CmmFloat _f _w -> pprPanic "getRegister' (CmmLit:CmmFloat), unsupported float lit" (pdoc plat expr) - - CmmVec lits | - VecFormat l sFmt <- cmmTypeFormat $ cmmLitType plat lit - , (f:fs) <- lits - , all (== f) fs -> do + CmmVec lits + | VecFormat l sFmt <- cmmTypeFormat $ cmmLitType plat lit, + (f : fs) <- lits, + all (== f) fs -> do -- All vector elements are equal literals -> broadcast (splat) let w = scalarWidth sFmt - broadcast = if isFloatScalarFormat sFmt - then MO_VF_Broadcast l w - else MO_V_Broadcast l w + broadcast = + if isFloatScalarFormat sFmt + then MO_VF_Broadcast l w + else MO_V_Broadcast l w fmt = cmmTypeFormat $ cmmLitType plat lit - (reg, format,code) <- getSomeReg $ CmmMachOp broadcast [CmmLit f] - return $ Any fmt (\dst -> code `snocOL` annExpr expr - (MOV (OpReg w dst) (OpReg (formatToWidth format) reg))) - + (reg, format, code) <- getSomeReg $ CmmMachOp broadcast [CmmLit f] + return + $ Any + fmt + ( \dst -> + code + `snocOL` annExpr + expr + (MOV (OpReg fmt dst) (OpReg format reg)) + ) CmmVec _lits -> pprPanic "getRegister' (CmmLit:CmmVec): " (pdoc plat expr) CmmLabel lbl -> do let op = OpImm (ImmCLbl lbl) rep = cmmLitType plat lit format = cmmTypeFormat rep - return (Any format (\dst -> unitOL $ annExpr expr (LDR format (OpReg (formatToWidth format) dst) op))) + return (Any format (\dst -> unitOL $ annExpr expr (LDR format (OpReg format dst) op))) CmmLabelOff lbl off | isNbitEncodeable 12 (fromIntegral off) -> do let op = OpImm (ImmIndex lbl off) rep = cmmLitType plat lit format = cmmTypeFormat rep - return (Any format (\dst -> unitOL $ LDR format (OpReg (formatToWidth format) dst) op)) + return (Any format (\dst -> unitOL $ LDR format (OpReg format dst) op)) CmmLabelOff lbl off -> do let op = litToImm' (CmmLabel lbl) rep = cmmLitType plat lit format = cmmTypeFormat rep width = typeWidth rep - (off_r, _off_format, off_code) <- getSomeReg $ CmmLit (CmmInt (fromIntegral off) width) + (off_r, off_format, off_code) <- getSomeReg $ CmmLit (CmmInt (fromIntegral off) width) return ( Any format ( \dst -> off_code - `snocOL` LDR format (OpReg (formatToWidth format) dst) op - `snocOL` ADD (OpReg width dst) (OpReg width dst) (OpReg width off_r) + `snocOL` LDR format (OpReg format dst) op + `snocOL` ADD (OpReg format dst) (OpReg format dst) (OpReg off_format off_r) ) ) CmmLabelDiffOff {} -> pprPanic "getRegister' (CmmLit:CmmLabelOff): " (pdoc plat expr) @@ -670,7 +683,7 @@ getRegister' config plat expr = annExpr expr -- We pattern match on the format in the pretty-printer. -- So, we can here simply emit LDRU for all vectors. - (LDRU format (OpReg width dst) (OpAddr addr)) + (LDRU format (OpReg format dst) (OpAddr addr)) ) ) (w, _f) @@ -681,7 +694,7 @@ getRegister' config plat expr = format ( \dst -> addr_code - `snocOL` LDRU format (OpReg width dst) (OpAddr addr) + `snocOL` LDRU format (OpReg format dst) (OpAddr addr) ) ) _ -> pprPanic ("Width too big! Cannot load: " ++ show width) (pdoc plat expr) @@ -700,15 +713,16 @@ getRegister' config plat expr = where width = typeWidth (cmmRegType reg) CmmRegOff reg off -> do - (off_r, _off_format, off_code) <- getSomeReg $ CmmLit (CmmInt (fromIntegral off) width) - (reg, _format, code) <- getSomeReg $ CmmReg reg + (off_r, off_format, off_code) <- getSomeReg $ CmmLit (CmmInt (fromIntegral off) width) + (reg, reg_format, code) <- getSomeReg $ CmmReg reg + let dst_format = intFormat width return $ Any - (intFormat width) + dst_format ( \dst -> off_code `appOL` code - `snocOL` ADD (OpReg width dst) (OpReg width reg) (OpReg width off_r) + `snocOL` ADD (OpReg dst_format dst) (OpReg reg_format reg) (OpReg off_format off_r) ) where width = typeWidth (cmmRegType reg) @@ -720,134 +734,159 @@ getRegister' config plat expr = -- for MachOps, see GHC.Cmm.MachOp -- For CmmMachOp, see GHC.Cmm.Expr CmmMachOp op [e] -> do - (reg, _format, code) <- getSomeReg e + (e_reg, e_format, e_code) <- getSomeReg e case op of - MO_Not w -> return $ Any (intFormat w) $ \dst -> - let w' = opRegWidth w - in code - `snocOL` - -- pseudo instruction `not` is `xori rd, rs, -1` - ann (text "not") (XORI (OpReg w' dst) (OpReg w' reg) (OpImm (ImmInt (-1)))) - `appOL` truncateReg w' w dst -- See Note [Signed arithmetic on RISCV64] - MO_S_Neg w -> negate code w reg + MO_Not w -> + let format_dst = intFormat w + in pure $ Any format_dst $ \dst -> + let w' = opRegWidth w + in e_code + `snocOL` + -- pseudo instruction `not` is `xori rd, rs, -1` + ann (text "not") (XORI (OpReg format_dst dst) (OpReg e_format e_reg) (OpImm (ImmInt (-1)))) + `appOL` truncateReg w' w dst -- See Note [Signed arithmetic on RISCV64] + MO_S_Neg w -> negate e_code w e_reg MO_F_Neg w -> - return - $ Any - (floatFormat w) - ( \dst -> - code - `snocOL` NEG (OpReg w dst) (OpReg w reg) - ) + let format = floatFormat w + in return + $ Any + format + ( \dst -> + e_code + `snocOL` NEG (OpReg format dst) (OpReg e_format e_reg) + ) -- TODO: Can this case happen? MO_SF_Round from to | from < W32 -> do -- extend to the smallest available representation - (reg_x, code_x) <- signExtendReg from W32 reg + (reg_x, code_x) <- signExtendReg from W32 e_reg + let format = floatFormat to pure $ Any - (floatFormat to) + format ( \dst -> - code + e_code `appOL` code_x - `snocOL` annExpr expr (FCVT IntToFloat (OpReg to dst) (OpReg from reg_x)) -- (Signed ConVerT Float) + `snocOL` annExpr expr (FCVT IntToFloat (OpReg format dst) (OpReg (intFormat from) reg_x)) -- (Signed ConVerT Float) ) MO_SF_Round from to -> - pure - $ Any - (floatFormat to) - ( \dst -> - code - `snocOL` annExpr expr (FCVT IntToFloat (OpReg to dst) (OpReg from reg)) -- (Signed ConVerT Float) - ) + let toFmt = floatFormat to + fromFmt = intFormat from + in pure + $ Any + (floatFormat to) + ( \dst -> + e_code + `snocOL` annExpr expr (FCVT IntToFloat (OpReg toFmt dst) (OpReg fromFmt e_reg)) -- (Signed ConVerT Float) + ) -- TODO: Can this case happen? MO_FS_Truncate from to | to < W32 -> - pure + let toFmt = intFormat to + fromFmt = floatFormat from + in pure + $ Any + toFmt + ( \dst -> + e_code + `snocOL` + -- W32 is the smallest width to convert to. Decrease width afterwards. + annExpr expr (FCVT FloatToInt (OpReg II32 dst) (OpReg fromFmt e_reg)) + `appOL` signExtendAdjustPrecission W32 to dst dst -- (float convert (-> zero) signed) + ) + MO_FS_Truncate from to -> + let toFmt = intFormat to + fromFmt = floatFormat from + in pure $ Any - (intFormat to) + toFmt ( \dst -> - code - `snocOL` - -- W32 is the smallest width to convert to. Decrease width afterwards. - annExpr expr (FCVT FloatToInt (OpReg W32 dst) (OpReg from reg)) - `appOL` signExtendAdjustPrecission W32 to dst dst -- (float convert (-> zero) signed) + e_code + `snocOL` annExpr expr (FCVT FloatToInt (OpReg toFmt dst) (OpReg fromFmt e_reg)) + `appOL` truncateReg from to dst -- (float convert (-> zero) signed) ) - MO_FS_Truncate from to -> - pure - $ Any - (intFormat to) - ( \dst -> - code - `snocOL` annExpr expr (FCVT FloatToInt (OpReg to dst) (OpReg from reg)) - `appOL` truncateReg from to dst -- (float convert (-> zero) signed) - ) MO_UU_Conv from to | from <= to -> - pure + let toFmt = intFormat to + fromFmt = intFormat from + in pure + $ Any + toFmt + ( \dst -> + e_code + `snocOL` annExpr e (MOV (OpReg toFmt dst) (OpReg fromFmt e_reg)) + ) + MO_UU_Conv from to -> + let toFmt = intFormat to + fromFmt = intFormat from + in pure $ Any - (intFormat to) + toFmt ( \dst -> - code - `snocOL` annExpr e (MOV (OpReg to dst) (OpReg from reg)) + e_code + `snocOL` annExpr e (MOV (OpReg fromFmt dst) (OpReg fromFmt e_reg)) + `appOL` truncateReg from to dst ) - MO_UU_Conv from to -> - pure - $ Any - (intFormat to) - ( \dst -> - code - `snocOL` annExpr e (MOV (OpReg from dst) (OpReg from reg)) - `appOL` truncateReg from to dst - ) - MO_SS_Conv from to -> ss_conv from to reg code - MO_FF_Conv from to -> return $ Any (floatFormat to) (\dst -> code `snocOL` annExpr e (FCVT FloatToFloat (OpReg to dst) (OpReg from reg))) - MO_WF_Bitcast w -> return $ Any (floatFormat w) (\dst -> code `snocOL` MOV (OpReg w dst) (OpReg w reg)) - MO_FW_Bitcast w -> return $ Any (intFormat w) (\dst -> code `snocOL` MOV (OpReg w dst) (OpReg w reg)) - + MO_SS_Conv from to -> ss_conv from to e_reg e_code + MO_FF_Conv from to -> + let toFmt = floatFormat to + fromFmt = floatFormat from + in pure $ Any toFmt (\dst -> e_code `snocOL` annExpr e (FCVT FloatToFloat (OpReg toFmt dst) (OpReg fromFmt e_reg))) + MO_WF_Bitcast w -> + let toFmt = floatFormat w + fromFmt = intFormat w + in pure $ Any toFmt (\dst -> e_code `snocOL` MOV (OpReg toFmt dst) (OpReg fromFmt e_reg)) + MO_FW_Bitcast w -> + let toFmt = intFormat w + fromFmt = floatFormat w + in pure $ Any toFmt (\dst -> e_code `snocOL` MOV (OpReg toFmt dst) (OpReg fromFmt e_reg)) -- Conversions -- TODO: Duplication with MO_UU_Conv MO_XX_Conv from to | to < from -> - pure - $ Any - (intFormat to) - ( \dst -> - code - `snocOL` annExpr e (MOV (OpReg from dst) (OpReg from reg)) - `appOL` truncateReg from to dst - ) + let toFmt = intFormat to + fromFmt = intFormat from + in pure + $ Any + toFmt + ( \dst -> + e_code + `snocOL` annExpr e (MOV (OpReg fromFmt dst) (OpReg fromFmt e_reg)) + `appOL` truncateReg from to dst + ) MO_XX_Conv _from to -> swizzleRegisterRep (intFormat to) <$> getRegister e MO_AlignmentCheck align wordWidth -> do reg <- getRegister' config plat e addAlignmentCheck align wordWidth reg - --TODO: MO_V_Broadcast with immediate: If the right value is a literal, + -- TODO: MO_V_Broadcast with immediate: If the right value is a literal, -- it may use vmv.v.i (simpler) -- TODO: Duplication with MO_VF_Broadcast MO_V_Broadcast length w -> do (reg_val, format_val, code_val) <- getSomeReg e - let w_val = formatToWidth format_val - pure $ Any (vecFormat (cmmVec length (cmmBits w))) $ \dst -> - code_val `snocOL` - annExpr expr - (VMV (VecFormat length (intScalarFormat w)) (OpReg w dst) (OpReg w_val reg_val)) - + let toFmt = VecFormat length (intScalarFormat w) + pure $ Any toFmt $ \dst -> + code_val + `snocOL` annExpr + expr + (VMV (OpReg toFmt dst) (OpReg format_val reg_val)) MO_VF_Broadcast length w -> do (reg_val, format_val, code_val) <- getSomeReg e - let w_val = formatToWidth format_val + let toFmt = VecFormat length (floatScalarFormat w) pure $ Any (vecFormat (cmmVec length (cmmFloat w))) $ \dst -> - code_val `snocOL` - annExpr expr - (VMV (VecFormat length (floatScalarFormat w)) (OpReg w dst) (OpReg w_val reg_val)) + code_val + `snocOL` annExpr + expr + (VMV (OpReg toFmt dst) (OpReg format_val reg_val)) -- TODO: NO MO_V_Neg? Why? MO_VF_Neg length w -> do (reg_v, format_v, code_v) <- getSomeReg e - let w_v = formatToWidth format_v - pure $ Any (vecFormat (cmmVec length (cmmFloat w))) $ \dst -> - code_v `snocOL` - annExpr expr - (VNEG (VecFormat length (floatScalarFormat w)) (OpReg w dst) (OpReg w_v reg_v)) - + let toFmt = VecFormat length (floatScalarFormat w) + pure $ Any toFmt $ \dst -> + code_v + `snocOL` annExpr + expr + (VNEG (OpReg toFmt dst) (OpReg format_v reg_v)) x -> pprPanic ("getRegister' (monadic CmmMachOp): " ++ show x) (pdoc plat expr) where -- In the case of 16- or 8-bit values we need to sign-extend to 32-bits @@ -855,10 +894,11 @@ getRegister' config plat expr = negate code w reg = do let w' = opRegWidth w (reg', code_sx) <- signExtendReg w w' reg - return $ Any (intFormat w) $ \dst -> + let fmt = intFormat w + return $ Any fmt $ \dst -> code `appOL` code_sx - `snocOL` NEG (OpReg w' dst) (OpReg w' reg') + `snocOL` NEG (OpReg fmt dst) (OpReg fmt reg') `appOL` truncateReg w' w dst ss_conv from to reg code @@ -868,20 +908,23 @@ getRegister' config plat expr = `appOL` signExtend from to reg dst `appOL` truncateReg from to dst | from > to = - pure $ Any (intFormat to) $ \dst -> - code - `appOL` toOL - [ ann - (text "MO_SS_Conv: narrow register signed" <+> ppr reg <+> ppr from <> text "->" <> ppr to) - (SLL (OpReg to dst) (OpReg from reg) (OpImm (ImmInt shift))), - -- signed right shift - SRA (OpReg to dst) (OpReg to dst) (OpImm (ImmInt shift)) - ] - `appOL` truncateReg from to dst + let fromFmt = intFormat from + toFmt = intFormat to + in pure $ Any toFmt $ \dst -> + code + `appOL` toOL + [ ann + (text "MO_SS_Conv: narrow register signed" <+> ppr reg <+> ppr from <> text "->" <> ppr to) + (SLL (OpReg toFmt dst) (OpReg fromFmt reg) (OpImm (ImmInt shift))), + -- signed right shift + SRA (OpReg toFmt dst) (OpReg toFmt dst) (OpImm (ImmInt shift)) + ] + `appOL` truncateReg from to dst | otherwise = -- No conversion necessary: Just copy. - pure $ Any (intFormat from) $ \dst -> - code `snocOL` MOV (OpReg from dst) (OpReg from reg) + let fmt = intFormat from + in pure $ Any fmt $ \dst -> + code `snocOL` MOV (OpReg fmt dst) (OpReg fmt reg) where shift = 64 - (widthInBits from - widthInBits to) @@ -901,29 +944,32 @@ getRegister' config plat expr = -- 1. Compute Reg +/- n directly. -- For Add/Sub we can directly encode 12bits, or 12bits lsl #12. CmmMachOp (MO_Add w) [CmmReg reg, CmmLit (CmmInt n _)] - | fitsIn12bitImm n -> return $ Any (intFormat w) (\d -> unitOL $ annExpr expr (ADD (OpReg w d) (OpReg w' r') (OpImm (ImmInteger n)))) + | fitsIn12bitImm n -> return $ Any toFmt (\d -> unitOL $ annExpr expr (ADD (OpReg toFmt d) (OpReg fromFmt r') (OpImm (ImmInteger n)))) where -- TODO: 12bits lsl #12; e.g. lower 12 bits of n are 0; shift n >> 12, and set lsl to #12. - w' = formatToWidth (cmmTypeFormat (cmmRegType reg)) r' = getRegisterReg plat reg + toFmt = intFormat w + fromFmt = cmmTypeFormat (cmmRegType reg) CmmMachOp (MO_Sub w) [CmmReg reg, CmmLit (CmmInt n _)] - | fitsIn12bitImm n -> return $ Any (intFormat w) (\d -> unitOL $ annExpr expr (SUB (OpReg w d) (OpReg w' r') (OpImm (ImmInteger n)))) + | fitsIn12bitImm n -> return $ Any toFmt (\d -> unitOL $ annExpr expr (SUB (OpReg toFmt d) (OpReg fromFmt r') (OpImm (ImmInteger n)))) where -- TODO: 12bits lsl #12; e.g. lower 12 bits of n are 0; shift n >> 12, and set lsl to #12. - w' = formatToWidth (cmmTypeFormat (cmmRegType reg)) r' = getRegisterReg plat reg + toFmt = intFormat w + fromFmt = cmmTypeFormat (cmmRegType reg) CmmMachOp (MO_U_Quot w) [x, y] | w == W8 || w == W16 -> do (reg_x, format_x, code_x) <- getSomeReg x (reg_y, format_y, code_y) <- getSomeReg y + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x `appOL` truncateReg (formatToWidth format_x) w reg_x `appOL` code_y `appOL` truncateReg (formatToWidth format_y) w reg_y - `snocOL` annExpr expr (DIVU (OpReg w dst) (OpReg w reg_x) (OpReg w reg_y)) + `snocOL` annExpr expr (DIVU (OpReg toFmt dst) (OpReg format_x reg_x) (OpReg format_y reg_y)) ) -- 2. Shifts. x << n, x >> n. @@ -931,129 +977,140 @@ getRegister' config plat expr = | w == W32, 0 <= n, n < 32 -> do - (reg_x, _format_x, code_x) <- getSomeReg x + (reg_x, format_x, code_x) <- getSomeReg x + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x - `snocOL` annExpr expr (SLL (OpReg w dst) (OpReg w reg_x) (OpImm (ImmInteger n))) + `snocOL` annExpr expr (SLL (OpReg toFmt dst) (OpReg format_x reg_x) (OpImm (ImmInteger n))) `appOL` truncateReg w w dst ) CmmMachOp (MO_Shl w) [x, CmmLit (CmmInt n _)] | w == W64, 0 <= n, n < 64 -> do - (reg_x, _format_x, code_x) <- getSomeReg x + (reg_x, format_x, code_x) <- getSomeReg x + let toFmt = intFormat w return $ Any (intFormat w) ( \dst -> code_x - `snocOL` annExpr expr (SLL (OpReg w dst) (OpReg w reg_x) (OpImm (ImmInteger n))) + `snocOL` annExpr expr (SLL (OpReg toFmt dst) (OpReg format_x reg_x) (OpImm (ImmInteger n))) `appOL` truncateReg w w dst ) CmmMachOp (MO_S_Shr w) [x, CmmLit (CmmInt n _)] | fitsIn12bitImm n -> do (reg_x, format_x, code_x) <- getSomeReg x (reg_x', code_x') <- signExtendReg (formatToWidth format_x) w reg_x + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x `appOL` code_x' - `snocOL` annExpr expr (SRA (OpReg w dst) (OpReg w reg_x') (OpImm (ImmInteger n))) + `snocOL` annExpr expr (SRA (OpReg toFmt dst) (OpReg format_x reg_x') (OpImm (ImmInteger n))) ) CmmMachOp (MO_S_Shr w) [x, y] -> do (reg_x, format_x, code_x) <- getSomeReg x - (reg_y, _format_y, code_y) <- getSomeReg y + (reg_y, format_y, code_y) <- getSomeReg y (reg_x', code_x') <- signExtendReg (formatToWidth format_x) w reg_x + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x `appOL` code_x' `appOL` code_y - `snocOL` annExpr expr (SRA (OpReg w dst) (OpReg w reg_x') (OpReg w reg_y)) + `snocOL` annExpr expr (SRA (OpReg toFmt dst) (OpReg format_x reg_x') (OpReg format_y reg_y)) ) CmmMachOp (MO_U_Shr w) [x, CmmLit (CmmInt n _)] | w == W8, 0 <= n, n < 8 -> do (reg_x, format_x, code_x) <- getSomeReg x + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x `appOL` truncateReg (formatToWidth format_x) w reg_x - `snocOL` annExpr expr (SRL (OpReg w dst) (OpReg w reg_x) (OpImm (ImmInteger n))) + `snocOL` annExpr expr (SRL (OpReg toFmt dst) (OpReg toFmt reg_x) (OpImm (ImmInteger n))) ) CmmMachOp (MO_U_Shr w) [x, CmmLit (CmmInt n _)] | w == W16, 0 <= n, n < 16 -> do (reg_x, format_x, code_x) <- getSomeReg x + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x `appOL` truncateReg (formatToWidth format_x) w reg_x - `snocOL` annExpr expr (SRL (OpReg w dst) (OpReg w reg_x) (OpImm (ImmInteger n))) + `snocOL` annExpr expr (SRL (OpReg toFmt dst) (OpReg toFmt reg_x) (OpImm (ImmInteger n))) ) CmmMachOp (MO_U_Shr w) [x, y] | w == W8 || w == W16 -> do (reg_x, format_x, code_x) <- getSomeReg x - (reg_y, _format_y, code_y) <- getSomeReg y + (reg_y, format_y, code_y) <- getSomeReg y + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x `appOL` code_y `appOL` truncateReg (formatToWidth format_x) w reg_x - `snocOL` annExpr expr (SRL (OpReg w dst) (OpReg w reg_x) (OpReg w reg_y)) + `snocOL` annExpr expr (SRL (OpReg toFmt dst) (OpReg format_x reg_x) (OpReg format_y reg_y)) ) CmmMachOp (MO_U_Shr w) [x, CmmLit (CmmInt n _)] | w == W32, 0 <= n, n < 32 -> do - (reg_x, _format_x, code_x) <- getSomeReg x + (reg_x, format_x, code_x) <- getSomeReg x + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x - `snocOL` annExpr expr (SRL (OpReg w dst) (OpReg w reg_x) (OpImm (ImmInteger n))) + `snocOL` annExpr expr (SRL (OpReg toFmt dst) (OpReg format_x reg_x) (OpImm (ImmInteger n))) ) CmmMachOp (MO_U_Shr w) [x, CmmLit (CmmInt n _)] | w == W64, 0 <= n, n < 64 -> do - (reg_x, _format_x, code_x) <- getSomeReg x + (reg_x, format_x, code_x) <- getSomeReg x + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x - `snocOL` annExpr expr (SRL (OpReg w dst) (OpReg w reg_x) (OpImm (ImmInteger n))) + `snocOL` annExpr expr (SRL (OpReg toFmt dst) (OpReg format_x reg_x) (OpImm (ImmInteger n))) ) -- 3. Logic &&, || CmmMachOp (MO_And w) [CmmReg reg, CmmLit (CmmInt n _)] | fitsIn12bitImm n -> - return $ Any (intFormat w) (\d -> unitOL $ annExpr expr (AND (OpReg w d) (OpReg w' r') (OpImm (ImmInteger n)))) + return $ Any toFmt (\d -> unitOL $ annExpr expr (AND (OpReg toFmt d) (OpReg fromFmt r') (OpImm (ImmInteger n)))) where - w' = formatToWidth (cmmTypeFormat (cmmRegType reg)) r' = getRegisterReg plat reg + toFmt = intFormat w + fromFmt = (cmmTypeFormat (cmmRegType reg)) CmmMachOp (MO_Or w) [CmmReg reg, CmmLit (CmmInt n _)] | fitsIn12bitImm n -> - return $ Any (intFormat w) (\d -> unitOL $ annExpr expr (ORI (OpReg w d) (OpReg w' r') (OpImm (ImmInteger n)))) + return $ Any toFmt (\d -> unitOL $ annExpr expr (ORI (OpReg toFmt d) (OpReg fromFmt r') (OpImm (ImmInteger n)))) where w' = formatToWidth (cmmTypeFormat (cmmRegType reg)) r' = getRegisterReg plat reg - + toFmt = intFormat w + fromFmt = (cmmTypeFormat (cmmRegType reg)) -- Generic binary case. CmmMachOp op [x, y] -> do let -- A "plain" operation. @@ -1064,13 +1121,14 @@ getRegister' config plat expr = (reg_x, format_x, code_x) <- getSomeReg x (reg_y, format_y, code_y) <- getSomeReg y massertPpr (isIntFormat format_x == isIntFormat format_y) $ text "bitOp: incompatible" + let toFmt = intFormat w return $ Any - (intFormat w) + toFmt ( \dst -> code_x `appOL` code_y - `appOL` op (OpReg w dst) (OpReg w reg_x) (OpReg w reg_y) + `appOL` op (OpReg toFmt dst) (OpReg format_x reg_x) (OpReg format_y reg_y) ) -- A (potentially signed) integer operation. @@ -1087,6 +1145,7 @@ getRegister' config plat expr = -- This is the width of the registers on which the operation -- should be performed. let w' = opRegWidth w + fmt' = intFormat w' signExt r | not is_signed = return (r, nilOL) | otherwise = signExtendReg w w' r @@ -1099,19 +1158,20 @@ getRegister' config plat expr = -- sign-extend both operands code_x_sx `appOL` code_y_sx - `appOL` op (OpReg w' dst) (OpReg w' reg_x_sx) (OpReg w' reg_y_sx) + `appOL` op (OpReg fmt' dst) (OpReg fmt' reg_x_sx) (OpReg fmt' reg_y_sx) `appOL` truncateReg w' w dst -- truncate back to the operand's original width floatOp w op = do (reg_fx, format_x, code_fx) <- getFloatReg x (reg_fy, format_y, code_fy) <- getFloatReg y massertPpr (isFloatFormat format_x && isFloatFormat format_y) $ text "floatOp: non-float" + let format_dst = floatFormat w return $ Any - (floatFormat w) + format_dst ( \dst -> code_fx `appOL` code_fy - `appOL` op (OpReg w dst) (OpReg w reg_fx) (OpReg w reg_fy) + `appOL` op (OpReg format_dst dst) (OpReg format_x reg_fx) (OpReg format_x reg_fy) ) -- need a special one for conditionals, as they return ints @@ -1119,25 +1179,29 @@ getRegister' config plat expr = (reg_fx, format_x, code_fx) <- getFloatReg x (reg_fy, format_y, code_fy) <- getFloatReg y massertPpr (isFloatFormat format_x && isFloatFormat format_y) $ text "floatCond: non-float" + let format_dst = intFormat w return $ Any - (intFormat w) + format_dst ( \dst -> code_fx `appOL` code_fy - `appOL` op (OpReg w dst) (OpReg w reg_fx) (OpReg w reg_fy) + `appOL` op (OpReg format_dst dst) (OpReg format_x reg_fx) (OpReg format_y reg_fy) ) - vecOp length w op = do + vecOp format op = do (reg_x, format_x, code_x) <- getSomeReg x (reg_y, format_y, code_y) <- getSomeReg y - massertPpr (isVecFormat format_x && isVecFormat format_y) $ - text "vecOp: non-vector operand. operands: " <+> ppr format_x <+> ppr format_y - pure $ Any (vecFormat (cmmVec length (cmmFloat w))) $ \dst -> - code_x `appOL` - code_y `snocOL` - annExpr expr - (op (OpReg w dst) (OpReg w reg_x) (OpReg w reg_y)) + massertPpr (isVecFormat format_x && isVecFormat format_y) + $ text "vecOp: non-vector operand. operands: " + <+> ppr format_x + <+> ppr format_y + pure $ Any format $ \dst -> + code_x + `appOL` code_y + `snocOL` annExpr + expr + (op (OpReg format dst) (OpReg format_x reg_x) (OpReg format_y reg_y)) case op of -- Integer operations @@ -1194,56 +1258,56 @@ getRegister' config plat expr = MO_VF_Extract length w -> do (reg_v, format_v, code_v) <- getSomeReg x (reg_idx, format_idx, code_idx) <- getSomeReg y - let tmpFormat = VecFormat length (floatScalarFormat w) - width_v = formatToWidth format_v - tmp <- getNewRegNat tmpFormat - pure $ Any (floatFormat w) $ \dst -> - code_v `appOL` - code_idx `snocOL` - -- Setup - -- TODO: Use width - annExpr expr - -- Move selected element to index 0 - -- vslidedown.vi v8, v9, 2 - (VSLIDEDOWN (VecFormat length (floatScalarFormat w)) (OpReg width_v tmp) (OpReg width_v reg_v) (OpReg (formatToWidth format_idx) reg_idx)) `snocOL` - -- Move to float register - -- vmv.x.s a0, v8 - VMV (VecFormat length (floatScalarFormat w)) (OpReg w dst) (OpReg (formatToWidth tmpFormat) tmp) + let format_dst = floatFormat w + tmp <- getNewRegNat format_v + pure $ Any format_dst $ \dst -> + code_v + `appOL` code_idx + `snocOL` + -- Setup + -- TODO: Use width + annExpr + expr + -- Move selected element to index 0 + -- vslidedown.vi v8, v9, 2 + (VSLIDEDOWN (OpReg format_v tmp) (OpReg format_v reg_v) (OpReg format_idx reg_idx)) + `snocOL` + -- Move to float register + -- vmv.x.s a0, v8 + VMV (OpReg format_dst dst) (OpReg format_v tmp) -- TODO: Duplication with MO_VF_Extract MO_V_Extract length w -> do (reg_v, format_v, code_v) <- getSomeReg x (reg_idx, format_idx, code_idx) <- getSomeReg y - let tmpFormat = VecFormat length (intScalarFormat w) - width_v = formatToWidth format_v - tmp <- getNewRegNat tmpFormat - pure $ Any (intFormat w) $ \dst -> - code_v `appOL` - code_idx `snocOL` - -- Setup - -- TODO: Use width - annExpr expr - -- Move selected element to index 0 - -- vslidedown.vi v8, v9, 2 - (VSLIDEDOWN (VecFormat length (intScalarFormat w)) (OpReg width_v tmp) (OpReg width_v reg_v) (OpReg (formatToWidth format_idx) reg_idx)) `snocOL` - -- Move to float register - -- vmv.x.s a0, v8 - VMV (VecFormat length (intScalarFormat w)) (OpReg w dst) (OpReg (formatToWidth tmpFormat) tmp) - - MO_VF_Add length w -> vecOp length w (\d x y -> (VADD (VecFormat length (floatScalarFormat w)) d x y)) - MO_VF_Sub length w -> vecOp length w (\d x y -> (VSUB (VecFormat length (floatScalarFormat w)) d x y)) - MO_VF_Mul length w -> vecOp length w (\d x y -> (VMUL (VecFormat length (floatScalarFormat w)) d x y)) - MO_VF_Quot length w -> vecOp length w (\d x y -> (VQUOT (VecFormat length (floatScalarFormat w)) d x y)) - + tmp <- getNewRegNat format_v + let format_dst = floatFormat w + pure $ Any format_dst $ \dst -> + code_v + `appOL` code_idx + `snocOL` + -- Setup + -- TODO: Use width + annExpr + expr + -- Move selected element to index 0 + -- vslidedown.vi v8, v9, 2 + (VSLIDEDOWN (OpReg format_v tmp) (OpReg format_v reg_v) (OpReg format_idx reg_idx)) + `snocOL` + -- Move to float register + -- vmv.x.s a0, v8 + VMV (OpReg format_dst dst) (OpReg format_v tmp) + MO_VF_Add length w -> vecOp (floatVecFormat length w) (\d x y -> (VADD d x y)) + MO_VF_Sub length w -> vecOp (floatVecFormat length w) (\d x y -> (VSUB d x y)) + MO_VF_Mul length w -> vecOp (floatVecFormat length w) (\d x y -> (VMUL d x y)) + MO_VF_Quot length w -> vecOp (floatVecFormat length w) (\d x y -> (VQUOT d x y)) -- See https://godbolt.org/z/PvcWKMKoW - MO_VS_Min length w -> vecOp length w (\d x y -> (VSMIN (VecFormat length (intScalarFormat w)) d x y)) - MO_VS_Max length w -> vecOp length w (\d x y -> (VSMAX (VecFormat length (intScalarFormat w)) d x y)) - MO_VU_Min length w -> vecOp length w (\d x y -> (VUMIN (VecFormat length (intScalarFormat w)) d x y)) - MO_VU_Max length w -> vecOp length w (\d x y -> (VUMAX (VecFormat length (intScalarFormat w)) d x y)) - MO_VF_Min length w -> vecOp length w (\d x y -> (VFMIN (VecFormat length (floatScalarFormat w)) d x y)) - MO_VF_Max length w -> vecOp length w (\d x y -> (VFMAX (VecFormat length (floatScalarFormat w)) d x y)) - - + MO_VS_Min length w -> vecOp (intVecFormat length w) (\d x y -> (VSMIN d x y)) + MO_VS_Max length w -> vecOp (intVecFormat length w) (\d x y -> (VSMAX d x y)) + MO_VU_Min length w -> vecOp (intVecFormat length w) (\d x y -> (VUMIN d x y)) + MO_VU_Max length w -> vecOp (intVecFormat length w) (\d x y -> (VUMAX d x y)) + MO_VF_Min length w -> vecOp (floatVecFormat length w) (\d x y -> (VFMIN d x y)) + MO_VF_Max length w -> vecOp (floatVecFormat length w) (\d x y -> (VFMAX d x y)) _e -> panic $ "Missing operation " ++ show expr -- Vectors @@ -1282,23 +1346,23 @@ getRegister' config plat expr = -- x86 fnmadd - x * y + z <=> RISCV64 fmsub : d = - r1 * r2 + r3 -- x86 fnmsub - x * y - z <=> RISCV64 fnmadd: d = - r1 * r2 - r3 MO_FMA var length w - | length == 1 - -> float3Op w (\d n m a -> unitOL $ FMA var d n m a) + | length == 1 -> + float3Op w (\d n m a -> unitOL $ FMA var d n m a) | otherwise -> do - (reg_x, format_x, code_x) <- getSomeReg x - (reg_y, format_y, code_y) <- getSomeReg y - (reg_z, format_z, code_z) <- getSomeReg z - let targetFormat = VecFormat length (floatScalarFormat w) - width_z = formatToWidth format_z - negate_z = if var `elem` [FNMAdd, FNMSub] then unitOL (VNEG format_z (OpReg width_z reg_z) (OpReg width_z reg_z)) else nilOL - pure $ Any targetFormat $ \dst -> - code_x `appOL` - code_y `appOL` - code_z `appOL` - negate_z `snocOL` - annExpr expr - (VMV (VecFormat length (floatScalarFormat w)) (OpReg w dst) (OpReg (formatToWidth format_x) reg_x)) `snocOL` - VFMA var format_x (OpReg w dst) (OpReg (formatToWidth format_y) reg_y) (OpReg (formatToWidth format_z) reg_z) + (reg_x, format_x, code_x) <- getSomeReg x + (reg_y, format_y, code_y) <- getSomeReg y + (reg_z, format_z, code_z) <- getSomeReg z + let targetFormat = VecFormat length (floatScalarFormat w) + negate_z = if var `elem` [FNMAdd, FNMSub] then unitOL (VNEG (OpReg format_z reg_z) (OpReg format_z reg_z)) else nilOL + pure $ Any targetFormat $ \dst -> + code_x + `appOL` code_y + `appOL` code_z + `appOL` negate_z + `snocOL` annExpr + expr + (VMV (OpReg targetFormat dst) (OpReg format_x reg_x)) + `snocOL` VFMA var (OpReg targetFormat dst) (OpReg format_y reg_y) (OpReg format_z reg_z) -- TODO: Implement length as immediate @@ -1311,40 +1375,60 @@ getRegister' config plat expr = -- ret -- -- https://godbolt.org/z/sEG8MrM8P - MO_VF_Insert length width ->vecInsert floatScalarFormat length width - - MO_V_Insert length width -> vecInsert intScalarFormat length width - + MO_VF_Insert length width -> vecInsert floatVecFormat length width + MO_V_Insert length width -> vecInsert intVecFormat length width _ -> pprPanic "getRegister' (unhandled ternary CmmMachOp): " $ pprMachOp op <+> text "in" <+> pdoc plat expr where - vecInsert :: (Width -> ScalarFormat) -> Int -> Width -> NatM Register - vecInsert widthToScalarFormat length width = - do - let targetVecFormat = VecFormat length (widthToScalarFormat width) - (reg_v, format_v, code_v) <- getSomeReg x - (reg_f, format_f, code_f) <- getSomeReg y - (reg_idx, format_idx, code_idx) <- getSomeReg z - tmp <- getNewRegNat targetVecFormat - pure $ Any targetVecFormat $ \dst -> - code_v `appOL` - code_f `appOL` - code_idx `snocOL` - annExpr expr - -- 1. fill elements with index numbers - -- TODO: The Width is made up - -- TODO: Is it safe to use v0 (default mask register) here? Instructions may be shuffled around... - -- Can we use an explicitly fetched register as mask (depends on instructions)? - (VID targetVecFormat (OpReg W8 v0Reg)) `snocOL` + vecInsert :: (Int -> Width -> Format) -> Int -> Width -> NatM Register + vecInsert toFormat length width = + do + (reg_v, format_v, code_v) <- getSomeReg x + (reg_f, format_f, code_f) <- getSomeReg y + (reg_idx, format_idx, code_idx) <- getSomeReg z + let format = toFormat length width + format_mask = intVecFormat length W8 -- Actually, W1 (one bit) would be correct, but that does not exist. + format_vid = intVecFormat length vidWidth + vidReg <- getNewRegNat format_vid + tmp <- getNewRegNat format + pure $ Any format $ \dst -> + code_v + `appOL` code_f + `appOL` code_idx + `snocOL` annExpr + expr + -- 1. fill elements with index numbers + -- TODO: The Width is made up + -- TODO: Is it safe to use v0 (default mask register) here? Instructions may be shuffled around... + -- Can we use an explicitly fetched register as mask (depends on instructions)? + (VID (OpReg format_vid vidReg)) + `snocOL` -- 2. Build mask - VMSEQ targetVecFormat(OpReg W8 v0Reg) (OpReg W8 v0Reg) (OpReg (formatToWidth format_idx) reg_idx) `snocOL` + VMSEQ (OpReg format_mask v0Reg) (OpReg format_vid vidReg) (OpReg format_idx reg_idx) + `snocOL` -- 3. Splat value into tmp vector - VMV targetVecFormat (OpReg width tmp) (OpReg (formatToWidth format_f) reg_f) `snocOL` + VMV (OpReg format tmp) (OpReg format_f reg_f) + `snocOL` -- 4. Merge with mask -> set element at index - VMERGE targetVecFormat (OpReg width dst) (OpReg (formatToWidth format_v) reg_v) (OpReg width tmp) (OpReg W8 v0Reg) + VMERGE (OpReg format dst) (OpReg format_v reg_v) (OpReg format tmp) (OpReg format_mask v0Reg) + where + -- Which element width do I need in my vector to store indexes in it? + vidWidth = case bitWidthFixed (fromIntegral length :: Word) of + x + | x <= widthInBits W8 -> W8 + | x <= widthInBits W16 -> W16 + | x <= widthInBits W32 -> W32 + | x <= widthInBits W64 -> W64 + | x <= widthInBits W128 -> W128 + | x <= widthInBits W256 -> W256 + | x <= widthInBits W512 -> W512 + e -> panic $ "length " ++ show length ++ "not representable in a single element's Width (" ++ show e ++ ")" + bitWidthFixed :: Word -> Int + bitWidthFixed 0 = 1 + bitWidthFixed n = finiteBitSize n - countLeadingZeros n float3Op w op = do (reg_fx, format_x, code_fx) <- getFloatReg x @@ -1352,13 +1436,14 @@ getRegister' config plat expr = (reg_fz, format_z, code_fz) <- getFloatReg z massertPpr (isFloatFormat format_x && isFloatFormat format_y && isFloatFormat format_z) $ text "float3Op: non-float" + let format_dst = floatFormat w pure - $ Any (floatFormat w) + $ Any format_dst $ \dst -> code_fx `appOL` code_fy `appOL` code_fz - `appOL` op (OpReg w dst) (OpReg w reg_fx) (OpReg w reg_fy) (OpReg w reg_fz) + `appOL` op (OpReg format_dst dst) (OpReg format_x reg_fx) (OpReg format_x reg_fy) (OpReg format_z reg_fz) CmmMachOp _op _xs -> pprPanic "getRegister' (variadic CmmMachOp): " (pdoc plat expr) where @@ -1372,26 +1457,27 @@ getRegister' config plat expr = (reg_x, format_x, code_x) <- getSomeReg x (reg_y, format_y, code_y) <- getSomeReg y -- TODO: Can't we clobber reg_x and reg_y to save registers? - lo <- getNewRegNat II64 - hi <- getNewRegNat II64 + let format = II64 + lo <- getNewRegNat format + hi <- getNewRegNat format -- TODO: Overhaul CSET: 3rd operand isn't needed for SNEZ let nonSense = OpImm (ImmInt 0) pure $ Any - (intFormat w) + format ( \dst -> code_x `appOL` signExtend (formatToWidth format_x) W64 reg_x reg_x `appOL` code_y `appOL` signExtend (formatToWidth format_y) W64 reg_y reg_y `appOL` toOL - [ annExpr expr (MULH (OpReg w hi) (OpReg w reg_x) (OpReg w reg_y)), - MUL (OpReg w lo) (OpReg w reg_x) (OpReg w reg_y), - SRA (OpReg w lo) (OpReg w lo) (OpImm (ImmInt (widthInBits W64 - 1))), + [ annExpr expr (MULH (OpReg format hi) (OpReg format_x reg_x) (OpReg format_y reg_y)), + MUL (OpReg format lo) (OpReg format_x reg_x) (OpReg format_y reg_y), + SRA (OpReg format lo) (OpReg format lo) (OpImm (ImmInt (widthInBits (formatToWidth format) - 1))), ann (text "Set flag if result of MULH contains more than sign bits.") - (XOR (OpReg w hi) (OpReg w hi) (OpReg w lo)), - CSET (OpReg w dst) (OpReg w hi) nonSense NE + (XOR (OpReg format hi) (OpReg format hi) (OpReg format lo)), + CSET (OpReg format dst) (OpReg format hi) nonSense NE ] ) do_mul_may_oflo w x y = do @@ -1399,16 +1485,17 @@ getRegister' config plat expr = (reg_y, format_y, code_y) <- getSomeReg y let width_x = formatToWidth format_x width_y = formatToWidth format_y + format = intFormat w if w > width_x && w > width_y then pure $ Any - (intFormat w) + format ( \dst -> -- 8bit * 8bit cannot overflow 16bit -- 16bit * 16bit cannot overflow 32bit -- 32bit * 32bit cannot overflow 64bit - unitOL $ annExpr expr (ADD (OpReg w dst) zero (OpImm (ImmInt 0))) + unitOL $ annExpr expr (ADD (OpReg format dst) zero (OpImm (ImmInt 0))) ) else do let use32BitMul = w <= W32 && width_x <= W32 && width_y <= W32 @@ -1418,19 +1505,19 @@ getRegister' config plat expr = narrowedReg <- getNewRegNat II64 pure $ Any - (intFormat w) + format ( \dst -> code_x `appOL` signExtend (formatToWidth format_x) W32 reg_x reg_x `appOL` code_y `appOL` signExtend (formatToWidth format_y) W32 reg_y reg_y - `snocOL` annExpr expr (MUL (OpReg W32 dst) (OpReg W32 reg_x) (OpReg W32 reg_y)) + `snocOL` annExpr expr (MUL (OpReg II32 dst) (OpReg II32 reg_x) (OpReg II32 reg_y)) `appOL` signExtendAdjustPrecission W32 w dst narrowedReg `appOL` toOL [ ann (text "Check if the multiplied value fits in the narrowed register") - (SUB (OpReg w dst) (OpReg w dst) (OpReg w narrowedReg)), - CSET (OpReg w dst) (OpReg w dst) nonSense NE + (SUB (OpReg format dst) (OpReg format dst) (OpReg II32 narrowedReg)), + CSET (OpReg format dst) (OpReg format dst) nonSense NE ] ) else @@ -1439,7 +1526,7 @@ getRegister' config plat expr = (intFormat w) ( \dst -> -- Do not handle this unlikely case. Just tell that it may overflow. - unitOL $ annExpr expr (ADD (OpReg w dst) zero (OpImm (ImmInt 1))) + unitOL $ annExpr expr (ADD (OpReg format dst) zero (OpImm (ImmInt 1))) ) -- TODO: Missing MachOps: @@ -1471,21 +1558,21 @@ signExtend :: Width -> Width -> Reg -> Reg -> OrdList Instr signExtend w w' _r _r' | w > w' = pprPanic "This is not a sign extension, but a truncation." $ ppr w <> text "->" <+> ppr w' signExtend w w' _r _r' | w > W64 || w' > W64 = pprPanic "Unexpected width (max is 64bit):" $ ppr w <> text "->" <+> ppr w' signExtend w w' r r' | w == W64 && w' == W64 && r == r' = nilOL -signExtend w w' r r' | w == W64 && w' == W64 = unitOL $ MOV (OpReg w' r') (OpReg w r) +signExtend w w' r r' | w == W64 && w' == W64 = unitOL $ MOV (OpReg (intFormat w') r') (OpReg (intFormat w) r) signExtend w w' r r' | w == W32 && w' == W64 = unitOL $ ann (text "sign-extend register (SEXT.W)" <+> ppr r <+> ppr w <> text "->" <> ppr w') -- `ADDIW r r 0` is the pseudo-op SEXT.W - (ADD (OpReg w' r') (OpReg w r) (OpImm (ImmInt 0))) + (ADD (OpReg (intFormat w') r') (OpReg (intFormat w) r) (OpImm (ImmInt 0))) signExtend w w' r r' = toOL [ ann (text "narrow register signed" <+> ppr r <> char ':' <> ppr w <> text "->" <> ppr r <> char ':' <> ppr w') - (SLL (OpReg w' r') (OpReg w r) (OpImm (ImmInt shift))), + (SLL (OpReg (intFormat w') r') (OpReg (intFormat w) r) (OpImm (ImmInt shift))), -- signed (arithmetic) right shift - SRA (OpReg w' r') (OpReg w' r') (OpImm (ImmInt shift)) + SRA (OpReg (intFormat w') r') (OpReg (intFormat w') r') (OpImm (ImmInt shift)) ] where shift = 64 - widthInBits w @@ -1497,22 +1584,22 @@ signExtend w w' r r' = signExtendAdjustPrecission :: Width -> Width -> Reg -> Reg -> OrdList Instr signExtendAdjustPrecission w w' _r _r' | w > W64 || w' > W64 = pprPanic "Unexpected width (max is 64bit):" $ ppr w <> text "->" <+> ppr w' signExtendAdjustPrecission w w' r r' | w == W64 && w' == W64 && r == r' = nilOL -signExtendAdjustPrecission w w' r r' | w == W64 && w' == W64 = unitOL $ MOV (OpReg w' r') (OpReg w r) +signExtendAdjustPrecission w w' r r' | w == W64 && w' == W64 = unitOL $ MOV (OpReg (intFormat w') r') (OpReg (intFormat w) r) signExtendAdjustPrecission w w' r r' | w == W32 && w' == W64 = unitOL $ ann (text "sign-extend register (SEXT.W)" <+> ppr r <+> ppr w <> text "->" <> ppr w') -- `ADDIW r r 0` is the pseudo-op SEXT.W - (ADD (OpReg w' r') (OpReg w r) (OpImm (ImmInt 0))) + (ADD (OpReg (intFormat w') r') (OpReg (intFormat w) r) (OpImm (ImmInt 0))) signExtendAdjustPrecission w w' r r' | w > w' = toOL [ ann (text "narrow register signed" <+> ppr r <> char ':' <> ppr w <> text "->" <> ppr r <> char ':' <> ppr w') - (SLL (OpReg w' r') (OpReg w r) (OpImm (ImmInt shift))), + (SLL (OpReg (intFormat w') r') (OpReg (intFormat w) r) (OpImm (ImmInt shift))), -- signed (arithmetic) right shift - SRA (OpReg w' r') (OpReg w' r') (OpImm (ImmInt shift)) + SRA (OpReg (intFormat w') r') (OpReg (intFormat w') r') (OpImm (ImmInt shift)) ] where shift = 64 - widthInBits w' @@ -1520,9 +1607,9 @@ signExtendAdjustPrecission w w' r r' = toOL [ ann (text "sign extend register" <+> ppr r <> char ':' <> ppr w <> text "->" <> ppr r <> char ':' <> ppr w') - (SLL (OpReg w' r') (OpReg w r) (OpImm (ImmInt shift))), + (SLL (OpReg (intFormat w') r') (OpReg (intFormat w) r) (OpImm (ImmInt shift))), -- signed (arithmetic) right shift - SRA (OpReg w' r') (OpReg w' r') (OpImm (ImmInt shift)) + SRA (OpReg (intFormat w') r') (OpReg (intFormat w') r') (OpImm (ImmInt shift)) ] where shift = 64 - widthInBits w @@ -1540,9 +1627,9 @@ truncateReg w w' r = toOL [ ann (text "truncate register" <+> ppr r <+> ppr w <> text "->" <> ppr w') - (SLL (OpReg w' r) (OpReg w r) (OpImm (ImmInt shift))), + (SLL (OpReg (intFormat w') r) (OpReg (intFormat w) r) (OpImm (ImmInt shift))), -- SHL ignores signedness! - SRL (OpReg w' r) (OpReg w r) (OpImm (ImmInt shift)) + SRL (OpReg (intFormat w') r) (OpReg (intFormat w) r) (OpImm (ImmInt shift)) ] where shift = 64 - widthInBits w' @@ -1561,18 +1648,17 @@ addAlignmentCheck align wordWidth reg = do where check :: Format -> Reg -> Reg -> BlockId -> Reg -> InstrBlock check fmt jumpReg cmpReg okayLblId reg = - let width = formatToWidth fmt - in assert (not $ isFloatFormat fmt) - $ toOL - [ ann - (text "Alignment check - alignment: " <> int align <> text ", word width: " <> text (show wordWidth)) - (AND (OpReg width cmpReg) (OpReg width reg) (OpImm $ ImmInt $ align - 1)), - BCOND EQ (OpReg width cmpReg) zero (TBlock okayLblId), - COMMENT (text "Alignment check failed"), - LDR II64 (OpReg W64 jumpReg) (OpImm $ ImmCLbl mkBadAlignmentLabel), - B (TReg jumpReg), - NEWBLOCK okayLblId - ] + assert (not $ isFloatFormat fmt) + $ toOL + [ ann + (text "Alignment check - alignment: " <> int align <> text ", word width: " <> text (show wordWidth)) + (AND (OpReg fmt cmpReg) (OpReg fmt reg) (OpImm $ ImmInt $ align - 1)), + BCOND EQ (OpReg fmt cmpReg) zero (TBlock okayLblId), + COMMENT (text "Alignment check failed"), + LDR II64 (OpReg II64 jumpReg) (OpImm $ ImmCLbl mkBadAlignmentLabel), + B (TReg jumpReg), + NEWBLOCK okayLblId + ] -- ----------------------------------------------------------------------------- -- The 'Amode' type: Memory addressing modes passed up the tree. @@ -1609,18 +1695,18 @@ getAmode _platform _ (CmmMachOp (MO_Add _w) [expr, CmmLit (CmmInt off _w')]) | fitsIn12bitImm off = do (reg, _format, code) <- getSomeReg expr - return $ Amode (AddrRegImm reg (ImmInteger off)) $ COMMENT (text "getAmode generic" <+> (text . show) expr) `consOL` code + return $ Amode (AddrRegImm reg (ImmInteger off)) $ COMMENT (text "getAmode generic" <+> (text . show) expr) `consOL` code getAmode _platform _ (CmmMachOp (MO_Sub _w) [expr, CmmLit (CmmInt off _w')]) | fitsIn12bitImm (-off) = do (reg, _format, code) <- getSomeReg expr - return $ Amode (AddrRegImm reg (ImmInteger (-off))) $ COMMENT (text "getAmode generic" <+> (text . show) expr) `consOL` code + return $ Amode (AddrRegImm reg (ImmInteger (-off))) $ COMMENT (text "getAmode generic" <+> (text . show) expr) `consOL` code -- Generic case getAmode _platform _ expr = do (reg, _format, code) <- getSomeReg expr - return $ Amode (AddrReg reg) $ COMMENT (text "getAmode generic" <+> (text . show) expr) `consOL` code + return $ Amode (AddrReg reg) $ COMMENT (text "getAmode generic" <+> (text . show) expr) `consOL` code -- ----------------------------------------------------------------------------- -- Generating assignments @@ -1637,14 +1723,14 @@ getAmode _platform _ expr = assignMem :: Format -> CmmExpr -> CmmExpr -> NatM InstrBlock assignMem rep addrE srcE = do - (src_reg, _format, code) <- getSomeReg srcE + (src_reg, src_format, code) <- getSomeReg srcE platform <- getPlatform let w = formatToWidth rep Amode addr addr_code <- getAmode platform w addrE return $ COMMENT (text "CmmStore" <+> parens (text (show addrE)) <+> parens (text (show srcE))) `consOL` ( code `appOL` addr_code - `snocOL` STR rep (OpReg w src_reg) (OpAddr addr) + `snocOL` STR rep (OpReg src_format src_reg) (OpAddr addr) ) assignReg :: Format -> CmmReg -> CmmExpr -> NatM InstrBlock @@ -1660,7 +1746,7 @@ assignReg _ reg src = Fixed format freg fcode -> COMMENT (text "CmmAssign" <+> parens (text (show reg)) <+> parens (text (show src))) `consOL` ( fcode - `snocOL` MOV (OpReg (formatToWidth format) dst) (OpReg (formatToWidth format) freg) + `snocOL` MOV (OpReg format dst) (OpReg format freg) ) -- ----------------------------------------------------------------------------- @@ -1697,22 +1783,23 @@ genCondJump bid expr = do case expr of -- Optimized == 0 case. CmmMachOp (MO_Eq w) [x, CmmLit (CmmInt 0 _)] -> do - (reg_x, _format_x, code_x) <- getSomeReg x - return $ code_x `snocOL` annExpr expr (BCOND EQ zero (OpReg w reg_x) (TBlock bid)) + (reg_x, format_x, code_x) <- getSomeReg x + return $ code_x `snocOL` annExpr expr (BCOND EQ zero (OpReg format_x reg_x) (TBlock bid)) -- Optimized /= 0 case. CmmMachOp (MO_Ne w) [x, CmmLit (CmmInt 0 _)] -> do - (reg_x, _format_x, code_x) <- getSomeReg x - return $ code_x `snocOL` annExpr expr (BCOND NE zero (OpReg w reg_x) (TBlock bid)) + (reg_x, format_x, code_x) <- getSomeReg x + return $ code_x `snocOL` annExpr expr (BCOND NE zero (OpReg format_x reg_x) (TBlock bid)) -- Generic case. CmmMachOp mop [x, y] -> do - let ubcond w cmp = do + let ubcond :: Width -> Cond -> NatM (OrdList Instr) + ubcond w cmp = do -- compute both sides. (reg_x, format_x, code_x) <- getSomeReg x (reg_y, format_y, code_y) <- getSomeReg y - let x' = OpReg w reg_x - y' = OpReg w reg_y + let x' = OpReg format_x reg_x + y' = OpReg format_y reg_y return $ case w of w | w == W8 || w == W16 -> @@ -1727,12 +1814,13 @@ genCondJump bid expr = do `appOL` code_y `snocOL` annExpr expr (BCOND cmp x' y' (TBlock bid)) + sbcond :: Width -> Cond -> NatM (OrdList Instr) sbcond w cmp = do -- compute both sides. (reg_x, format_x, code_x) <- getSomeReg x (reg_y, format_y, code_y) <- getSomeReg y - let x' = OpReg w reg_x - y' = OpReg w reg_y + let x' = OpReg format_x reg_x + y' = OpReg format_y reg_y return $ case w of w | w `elem` [W8, W16, W32] -> @@ -1743,17 +1831,18 @@ genCondJump bid expr = do `appOL` unitOL (annExpr expr (BCOND cmp x' y' (TBlock bid))) _ -> code_x `appOL` code_y `appOL` unitOL (annExpr expr (BCOND cmp x' y' (TBlock bid))) + fbcond :: Width -> Cond -> NatM (OrdList Instr) fbcond w cmp = do -- ensure we get float regs - (reg_fx, _format_fx, code_fx) <- getFloatReg x - (reg_fy, _format_fy, code_fy) <- getFloatReg y - condOpReg <- OpReg W64 <$> getNewRegNat II64 + (reg_fx, format_fx, code_fx) <- getFloatReg x + (reg_fy, format_fy, code_fy) <- getFloatReg y + condOpReg <- OpReg II64 <$> getNewRegNat II64 oneReg <- getNewRegNat II64 return $ code_fx `appOL` code_fy - `snocOL` annExpr expr (CSET condOpReg (OpReg w reg_fx) (OpReg w reg_fy) cmp) - `snocOL` MOV (OpReg W64 oneReg) (OpImm (ImmInt 1)) - `snocOL` BCOND EQ condOpReg (OpReg w oneReg) (TBlock bid) + `snocOL` annExpr expr (CSET condOpReg (OpReg format_fx reg_fx) (OpReg format_fy reg_fy) cmp) + `snocOL` MOV (OpReg II64 oneReg) (OpImm (ImmInt 1)) + `snocOL` BCOND EQ condOpReg (OpReg II64 oneReg) (TBlock bid) case mop of MO_F_Eq w -> fbcond w EQ @@ -1850,7 +1939,7 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do moveStackDown i = toOL [ PUSH_STACK_FRAME, - SUB (OpReg W64 spMachReg) (OpReg W64 spMachReg) (OpImm (ImmInt (8 * i))), + SUB (OpReg II64 spMachReg) (OpReg II64 spMachReg) (OpImm (ImmInt (8 * i))), DELTA (-8 * i - 16) ] moveStackUp 0 = @@ -1861,7 +1950,7 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do moveStackUp i | odd i = moveStackUp (i + 1) moveStackUp i = toOL - [ ADD (OpReg W64 spMachReg) (OpReg W64 spMachReg) (OpImm (ImmInt (8 * i))), + [ ADD (OpReg II64 spMachReg) (OpReg II64 spMachReg) (OpImm (ImmInt (8 * i))), POP_STACK_FRAME, DELTA 0 ] @@ -1869,7 +1958,7 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do let code = call_target_code -- compute the label (possibly into a register) `appOL` moveStackDown stackSpaceWords - `snocOL` COMMENT ((text . show) (map (\(a,b,_c,_d) -> (a,b)) arg_regs'')) + `snocOL` COMMENT ((text . show) (map (\(a, b, _c, _d) -> (a, b)) arg_regs'')) `snocOL` COMMENT ((text . show) stackSpaceWords <+> (text . show) passRegs) `appOL` passArgumentsCode -- put the arguments into x0, ... `snocOL` COMMENT (text "CCALL") @@ -1897,7 +1986,7 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do else toOL [ COMMENT (text "Pass gp argument sign-extended (SignedHint): " <> ppr r), - MOV (OpReg w gpReg) (OpReg w r) + MOV (OpReg format gpReg) (OpReg format r) ] accumCode' = accumCode @@ -1907,8 +1996,7 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do -- Still have FP regs, and we want to pass an FP argument. passArguments gpRegs (fpReg : fpRegs) vRegs ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isFloatFormat format = do - let w = formatToWidth format - mov = MOV (OpReg w fpReg) (OpReg w r) + let mov = MOV (OpReg format fpReg) (OpReg format r) accumCode' = accumCode `appOL` code_r @@ -1919,7 +2007,7 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do passArguments [] [] vRegs ((r, format, hint, code_r) : args) stackSpaceWords accumRegs accumCode | not (isVecFormat format) = do let w = formatToWidth format spOffet = 8 * stackSpaceWords - str = STR format (OpReg w r) (OpAddr (AddrRegImm spMachReg (ImmInt spOffet))) + str = STR format (OpReg format r) (OpAddr (AddrRegImm spMachReg (ImmInt spOffet))) stackCode = if hint == SignedHint then @@ -1935,7 +2023,7 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do passArguments [] fpRegs vRegs ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isIntFormat format = do let w = formatToWidth format spOffet = 8 * stackSpaceWords - str = STR format (OpReg w r) (OpAddr (AddrRegImm spMachReg (ImmInt spOffet))) + str = STR format (OpReg format r) (OpAddr (AddrRegImm spMachReg (ImmInt spOffet))) stackCode = code_r `snocOL` ann (text "Pass argument (size " <> ppr w <> text ") on the stack: " <> ppr r) str @@ -1943,8 +2031,8 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do -- Still have gpRegs left, but want to pass a FP argument. Must be passed in gpReg then. passArguments (gpReg : gpRegs) [] vRegs ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isFloatFormat format = do - let w = formatToWidth format - mov = MOV (OpReg w gpReg) (OpReg w r) + let gp_format = (intFormat . formatToWidth) format + mov = MOV (OpReg gp_format gpReg) (OpReg format r) accumCode' = accumCode `appOL` code_r @@ -1953,8 +2041,7 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do -- Still have vector regs, and we want to pass a vector argument. passArguments gpRegs fpRegs (vReg : vRegs) ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isVecFormat format = do - let w = formatToWidth format - mov = MOV (OpReg w vReg) (OpReg w r) + let mov = MOV (OpReg format vReg) (OpReg format r) accumCode' = accumCode `appOL` code_r @@ -1962,9 +2049,9 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do passArguments gpRegs fpRegs vRegs args stackSpaceWords (vReg : accumRegs) accumCode' -- No more vector regs, and we want to pass a vector argument. - passArguments gpRegs fpRegs (vReg : vRegs) ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode | isVecFormat format = - pprPanic "passArguments" (text "TODO: Implement and test vector argument passing on the stack.") - + passArguments gpRegs fpRegs (vReg : vRegs) ((r, format, _hint, code_r) : args) stackSpaceWords accumRegs accumCode + | isVecFormat format = + pprPanic "passArguments" (text "TODO: Implement and test vector argument passing on the stack.") passArguments _ _ _ _ _ _ _ = pprPanic "passArguments" (text "invalid state") readResults :: [Reg] -> [Reg] -> [Reg] -> [LocalReg] -> [Reg] -> InstrBlock -> NatM InstrBlock @@ -1986,30 +2073,28 @@ genCCall target@(ForeignTarget expr _cconv) dest_regs arg_regs = do w = cmmRegWidth (CmmLocal dst) r_dst = getRegisterReg platform (CmmLocal dst) case format of - format | isFloatFormat format - -> readResults (gpReg : gpRegs) fpRegs (vReg: vRegs) dsts (fpReg : accumRegs) (accumCode `snocOL` MOV (OpReg w r_dst) (OpReg w fpReg)) - | isVecFormat format - -> readResults (gpReg : gpRegs) (fpReg: fpRegs) vRegs dsts (vReg : accumRegs) (accumCode `snocOL` MOV (OpReg w r_dst) (OpReg w vReg)) - | otherwise -> - readResults gpRegs (fpReg : fpRegs) (vReg: vRegs) dsts (gpReg : accumRegs) - $ accumCode - `snocOL` MOV (OpReg w r_dst) (OpReg w gpReg) - `appOL` - -- truncate, otherwise an unexpectedly big value might be used in upfollowing calculations - -- truncate, otherwise an unexpectedly big value might be used in upfollowing calculations - -- truncate, otherwise an unexpectedly big value might be used in upfollowing calculations - -- truncate, otherwise an unexpectedly big value might be used in upfollowing calculations - truncateReg W64 w r_dst + format + | isFloatFormat format -> + readResults (gpReg : gpRegs) fpRegs (vReg : vRegs) dsts (fpReg : accumRegs) (accumCode `snocOL` MOV (OpReg format r_dst) (OpReg format fpReg)) + | isVecFormat format -> + readResults (gpReg : gpRegs) (fpReg : fpRegs) vRegs dsts (vReg : accumRegs) (accumCode `snocOL` MOV (OpReg format r_dst) (OpReg format vReg)) + | otherwise -> + readResults gpRegs (fpReg : fpRegs) (vReg : vRegs) dsts (gpReg : accumRegs) + $ accumCode + `snocOL` MOV (OpReg format r_dst) (OpReg format gpReg) + `appOL` + -- truncate, otherwise an unexpectedly big value might be used in upfollowing calculations + truncateReg W64 w r_dst genCCall (PrimTarget mop) dest_regs arg_regs = do case mop of MO_F32_Fabs | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs -> - unaryFloatOp W32 (\d x -> unitOL $ FABS d x) arg_reg dest_reg + unaryFloatOp FF32 (\d x -> unitOL $ FABS d x) arg_reg dest_reg MO_F64_Fabs | [arg_reg] <- arg_regs, [dest_reg] <- dest_regs -> - unaryFloatOp W64 (\d x -> unitOL $ FABS d x) arg_reg dest_reg + unaryFloatOp FF64 (\d x -> unitOL $ FABS d x) arg_reg dest_reg -- 64 bit float ops MO_F64_Pwr -> mkCCall "pow" MO_F64_Sin -> mkCCall "sin" @@ -2133,22 +2218,23 @@ genCCall (PrimTarget mop) dest_regs arg_regs = do -- __atomic_load_n(&a, __ATOMIC_ACQUIRE); -- __atomic_load_n(&a, __ATOMIC_SEQ_CST); let instrs = case ord of - MemOrderRelaxed -> unitOL $ ann moDescr (LDR (intFormat w) (OpReg w dst) (OpAddr $ AddrReg p)) + MemOrderRelaxed -> unitOL $ ann moDescr (LDR format (OpReg format dst) (OpAddr $ AddrReg p)) MemOrderAcquire -> toOL - [ ann moDescr (LDR (intFormat w) (OpReg w dst) (OpAddr $ AddrReg p)), + [ ann moDescr (LDR format (OpReg format dst) (OpAddr $ AddrReg p)), FENCE FenceRead FenceReadWrite ] MemOrderSeqCst -> toOL [ ann moDescr (FENCE FenceReadWrite FenceReadWrite), - LDR (intFormat w) (OpReg w dst) (OpAddr $ AddrReg p), + LDR format (OpReg format dst) (OpAddr $ AddrReg p), FENCE FenceRead FenceReadWrite ] MemOrderRelease -> panic $ "Unexpected MemOrderRelease on an AtomicRead: " ++ show mo dst = getRegisterReg platform (CmmLocal dst_reg) moDescr = (text . show) mo code = code_p `appOL` instrs + format = intFormat w return code | otherwise -> panic "mal-formed AtomicRead" mo@(MO_AtomicWrite w ord) @@ -2161,17 +2247,17 @@ genCCall (PrimTarget mop) dest_regs arg_regs = do -- __atomic_store_n(&a, 23, __ATOMIC_SEQ_CST); -- __atomic_store_n(&a, 23, __ATOMIC_RELEASE); let instrs = case ord of - MemOrderRelaxed -> unitOL $ ann moDescr (STR fmt_val (OpReg w val) (OpAddr $ AddrReg p)) + MemOrderRelaxed -> unitOL $ ann moDescr (STR fmt_val (OpReg fmt_val val) (OpAddr $ AddrReg p)) MemOrderSeqCst -> toOL [ ann moDescr (FENCE FenceReadWrite FenceWrite), - STR fmt_val (OpReg w val) (OpAddr $ AddrReg p), + STR fmt_val (OpReg fmt_val val) (OpAddr $ AddrReg p), FENCE FenceReadWrite FenceReadWrite ] MemOrderRelease -> toOL [ ann moDescr (FENCE FenceReadWrite FenceWrite), - STR fmt_val (OpReg w val) (OpAddr $ AddrReg p) + STR fmt_val (OpReg fmt_val val) (OpAddr $ AddrReg p) ] MemOrderAcquire -> panic $ "Unexpected MemOrderAcquire on an AtomicWrite" ++ show mo moDescr = (text . show) mo @@ -2204,11 +2290,12 @@ genCCall (PrimTarget mop) dest_regs arg_regs = do let cconv = ForeignConvention CCallConv [NoHint] [NoHint] CmmMayReturn genCCall (ForeignTarget target cconv) dest_regs arg_regs - unaryFloatOp w op arg_reg dest_reg = do + unaryFloatOp :: Format -> (Operand -> Operand -> OrdList Instr) -> CmmExpr -> LocalReg -> NatM (OrdList Instr) + unaryFloatOp fmt op arg_reg dest_reg = do platform <- getPlatform - (reg_fx, _format_x, code_fx) <- getFloatReg arg_reg + (reg_fx, format_x, code_fx) <- getFloatReg arg_reg let dst = getRegisterReg platform (CmmLocal dest_reg) - let code = code_fx `appOL` op (OpReg w dst) (OpReg w reg_fx) + let code = code_fx `appOL` op (OpReg fmt dst) (OpReg format_x reg_fx) pure code {- Note [RISCV64 far jumps] @@ -2286,7 +2373,7 @@ genCondFarJump cond op1 op2 far_target = do $ BCOND cond op1 op2 (TBlock jmp_lbl_id), B (TBlock skip_lbl_id), NEWBLOCK jmp_lbl_id, - LDR II64 (OpReg W64 tmpReg) (OpImm (ImmCLbl (blockLbl far_target))), + LDR II64 (OpReg II64 tmpReg) (OpImm (ImmCLbl (blockLbl far_target))), B (TReg tmpReg), NEWBLOCK skip_lbl_id ] @@ -2300,7 +2387,7 @@ genFarJump far_target = return $ toOL [ ann (text "Unconditional far jump to: " <> ppr far_target) - $ LDR II64 (OpReg W64 tmpReg) (OpImm (ImmCLbl (blockLbl far_target))), + $ LDR II64 (OpReg II64 tmpReg) (OpImm (ImmCLbl (blockLbl far_target))), B (TReg tmpReg) ] ===================================== compiler/GHC/CmmToAsm/RV64/Instr.hs ===================================== @@ -20,8 +20,8 @@ import GHC.CmmToAsm.Utils import GHC.Data.FastString (LexicalFastString) import GHC.Platform import GHC.Platform.Reg -import GHC.Platform.Regs import GHC.Platform.Reg.Class.Separate +import GHC.Platform.Regs import GHC.Prelude import GHC.Stack import GHC.Types.Unique.DSM @@ -96,10 +96,10 @@ regUsageOfInstr platform instr = case instr of -- ORI's third operand is always an immediate ORI dst src1 _ -> usage (regOp src1, regOp dst) XORI dst src1 _ -> usage (regOp src1, regOp dst) - J_TBL _ _ t -> usage ([t], []) + J_TBL _ _ t -> usage ([(t, II64)], []) B t -> usage (regTarget t, []) BCOND _ l r t -> usage (regTarget t ++ regOp l ++ regOp r, []) - BL t ps -> usage (t : ps, callerSavedRegisters) + BL t ps -> usage ((t, II64) : map (\p -> (p, II64)) ps, callerSavedRegisters) CSET dst l r _ -> usage (regOp l ++ regOp r, regOp dst) STR _ src dst -> usage (regOp src ++ regOp dst, []) LDR _ dst src -> usage (regOp src, regOp dst) @@ -109,84 +109,76 @@ regUsageOfInstr platform instr = case instr of FABS dst src -> usage (regOp src, regOp dst) FMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) FMAX dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VMV fmt dst src1 -> usage (regOp src1, regOp dst) - VID fmt dst -> usage ([], regOp dst) - VMSEQ fmt dst src op -> usage (regOp src ++ regOp op, regOp dst) - VMERGE fmt dst op1 op2 opm -> usage (regOp op1 ++ regOp op2 ++ regOp opm, regOp dst) - VSLIDEDOWN fmt dst op1 op2 -> usage (regOp op1 ++ regOp op2, regOp dst) + VMV dst src1 -> usage (regOp src1, regOp dst) + VID dst -> usage ([], regOp dst) + VMSEQ dst src op -> usage (regOp src ++ regOp op, regOp dst) + VMERGE dst op1 op2 opm -> usage (regOp op1 ++ regOp op2 ++ regOp opm, regOp dst) + VSLIDEDOWN dst op1 op2 -> usage (regOp op1 ++ regOp op2, regOp dst) -- WARNING: VSETIVLI is a special case. It changes the interpretation of all vector registers! - VSETIVLI dst _ _ _ _ _ -> usage ([], [dst]) - VNEG fmt dst src1 -> usage (regOp src1, regOp dst) - VADD fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VSUB fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VMUL fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VQUOT fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VSMIN fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VSMAX fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VUMIN fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VUMAX fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VFMIN fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) - VFMAX fmt dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VSETIVLI (OpReg fmt reg) _ _ _ _ _ -> usage ([], [(reg, fmt)]) + VNEG dst src1 -> usage (regOp src1, regOp dst) + VADD dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VSUB dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VMUL dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VQUOT dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VSMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VSMAX dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VUMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VUMAX dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VFMIN dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) + VFMAX dst src1 src2 -> usage (regOp src1 ++ regOp src2, regOp dst) FMA _ dst src1 src2 src3 -> usage (regOp src1 ++ regOp src2 ++ regOp src3, regOp dst) - VFMA _ _fmt op1 op2 op3 -> + VFMA _ op1 op2 op3 -> usage (regOp op1 ++ regOp op2 ++ regOp op3, regOp op1) _ -> panic $ "regUsageOfInstr: " ++ instrCon instr where -- filtering the usage is necessary, otherwise the register -- allocator will try to allocate pre-defined fixed stg -- registers as well, as they show up. - usage :: ([Reg], [Reg]) -> RegUsage + usage :: ([(Reg, Format)], [(Reg, Format)]) -> RegUsage usage (srcRegs, dstRegs) = RU (map mkFmt $ filter (interesting platform) srcRegs) (map mkFmt $ filter (interesting platform) dstRegs) - -- SIMD NCG TODO: the format here is used for register spilling/unspilling. - -- As the RISCV64 NCG does not currently support SIMD registers, - -- this simple logic is OK. - mkFmt r = RegWithFormat r fmt - where - fmt = case cls of - RcInteger -> II64 - RcFloat -> FF64 - -- TODO: We're expecting 128bit vector registers here. This - -- needs to be calculated from real format. Probably, we need to - -- hand around the format instead of the width for vector regs. - RcVector -> VecFormat 2 FmtInt64 - cls = case r of - RegVirtual vr -> classOfVirtualReg (platformArch platform) vr - RegReal rr -> classOfRealReg rr - - regAddr :: AddrMode -> [Reg] - regAddr (AddrRegImm r1 _imm) = [r1] - regAddr (AddrReg r1) = [r1] - - regOp :: Operand -> [Reg] - regOp (OpReg _w r1) = [r1] + mkFmt (r, fmt) = RegWithFormat r fmt + + regAddr :: AddrMode -> [(Reg, Format)] + regAddr (AddrRegImm r1 _imm) = [(r1, II64)] + regAddr (AddrReg r1) = [(r1, II64)] + + regOp :: Operand -> [(Reg, Format)] + regOp (OpReg fmt r1) = [(r1, fmt)] regOp (OpAddr a) = regAddr a regOp (OpImm _imm) = [] - regTarget :: Target -> [Reg] + regTarget :: Target -> [(Reg, Format)] regTarget (TBlock _bid) = [] - regTarget (TReg r1) = [r1] + regTarget (TReg r1) = [(r1, II64)] -- Is this register interesting for the register allocator? - interesting :: Platform -> Reg -> Bool - interesting _ (RegVirtual _) = True - interesting platform (RegReal (RealRegSingle i)) = freeReg platform i + interesting :: Platform -> (Reg, Format) -> Bool + interesting _ ((RegVirtual _), _) = True + interesting platform ((RegReal (RealRegSingle i)), _) = freeReg platform i -- | Caller-saved registers (according to calling convention) -- -- These registers may be clobbered after a jump. -callerSavedRegisters :: [Reg] +callerSavedRegisters :: [(Reg, Format)] callerSavedRegisters = - [regSingle raRegNo] - ++ map regSingle [t0RegNo .. t2RegNo] - ++ map regSingle [a0RegNo .. a7RegNo] - ++ map regSingle [t3RegNo .. t6RegNo] - ++ map regSingle [ft0RegNo .. ft7RegNo] - ++ map regSingle [fa0RegNo .. fa7RegNo] + [(toTuple . regSingle) raRegNo] + ++ map (toTuple . regSingle) [t0RegNo .. t2RegNo] + ++ map (toTuple . regSingle) [a0RegNo .. a7RegNo] + ++ map (toTuple . regSingle) [t3RegNo .. t6RegNo] + ++ map (toTuple . regSingle) [ft0RegNo .. ft7RegNo] + ++ map (toTuple . regSingle) [fa0RegNo .. fa7RegNo] + where + toTuple :: Reg -> (Reg, Format) + toTuple r = (r, format r) + format r | isIntReg r = II64 + | isFloatReg r = FF64 + | otherwise = panic $ "Unexpected register: " ++ show r -- | Apply a given mapping to all the register references in this instruction. patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr @@ -230,27 +222,27 @@ patchRegsOfInstr instr env = case instr of FABS o1 o2 -> FABS (patchOp o1) (patchOp o2) FMIN o1 o2 o3 -> FMIN (patchOp o1) (patchOp o2) (patchOp o3) FMAX o1 o2 o3 -> FMAX (patchOp o1) (patchOp o2) (patchOp o3) - VMV fmt o1 o2 -> VMV fmt (patchOp o1) (patchOp o2) - VID fmt o1 -> VID fmt (patchOp o1) - VMSEQ fmt o1 o2 o3 -> VMSEQ fmt (patchOp o1) (patchOp o2) (patchOp o3) - VMERGE fmt o1 o2 o3 o4 -> VMERGE fmt (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) - VSLIDEDOWN fmt o1 o2 o3 -> VSLIDEDOWN fmt (patchOp o1) (patchOp o2) (patchOp o3) - VSETIVLI o1 o2 o3 o4 o5 o6 -> VSETIVLI (env o1) o2 o3 o4 o5 o6 - VNEG fmt o1 o2 -> VNEG fmt (patchOp o1) (patchOp o2) - VADD fmt o1 o2 o3 -> VADD fmt (patchOp o1) (patchOp o2) (patchOp o3) - VSUB fmt o1 o2 o3 -> VSUB fmt (patchOp o1) (patchOp o2) (patchOp o3) - VMUL fmt o1 o2 o3 -> VMUL fmt (patchOp o1) (patchOp o2) (patchOp o3) - VQUOT fmt o1 o2 o3 -> VQUOT fmt (patchOp o1) (patchOp o2) (patchOp o3) - VSMIN fmt o1 o2 o3 -> VSMIN fmt (patchOp o1) (patchOp o2) (patchOp o3) - VSMAX fmt o1 o2 o3 -> VSMAX fmt (patchOp o1) (patchOp o2) (patchOp o3) - VUMIN fmt o1 o2 o3 -> VUMIN fmt (patchOp o1) (patchOp o2) (patchOp o3) - VUMAX fmt o1 o2 o3 -> VUMAX fmt (patchOp o1) (patchOp o2) (patchOp o3) - VFMIN fmt o1 o2 o3 -> VFMIN fmt (patchOp o1) (patchOp o2) (patchOp o3) - VFMAX fmt o1 o2 o3 -> VFMAX fmt (patchOp o1) (patchOp o2) (patchOp o3) + VMV o1 o2 -> VMV (patchOp o1) (patchOp o2) + VID o1 -> VID (patchOp o1) + VMSEQ o1 o2 o3 -> VMSEQ (patchOp o1) (patchOp o2) (patchOp o3) + VMERGE o1 o2 o3 o4 -> VMERGE (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) + VSLIDEDOWN o1 o2 o3 -> VSLIDEDOWN (patchOp o1) (patchOp o2) (patchOp o3) + VSETIVLI o1 o2 o3 o4 o5 o6 -> VSETIVLI (patchOp o1) o2 o3 o4 o5 o6 + VNEG o1 o2 -> VNEG (patchOp o1) (patchOp o2) + VADD o1 o2 o3 -> VADD (patchOp o1) (patchOp o2) (patchOp o3) + VSUB o1 o2 o3 -> VSUB (patchOp o1) (patchOp o2) (patchOp o3) + VMUL o1 o2 o3 -> VMUL (patchOp o1) (patchOp o2) (patchOp o3) + VQUOT o1 o2 o3 -> VQUOT (patchOp o1) (patchOp o2) (patchOp o3) + VSMIN o1 o2 o3 -> VSMIN (patchOp o1) (patchOp o2) (patchOp o3) + VSMAX o1 o2 o3 -> VSMAX (patchOp o1) (patchOp o2) (patchOp o3) + VUMIN o1 o2 o3 -> VUMIN (patchOp o1) (patchOp o2) (patchOp o3) + VUMAX o1 o2 o3 -> VUMAX (patchOp o1) (patchOp o2) (patchOp o3) + VFMIN o1 o2 o3 -> VFMIN (patchOp o1) (patchOp o2) (patchOp o3) + VFMAX o1 o2 o3 -> VFMAX (patchOp o1) (patchOp o2) (patchOp o3) FMA s o1 o2 o3 o4 -> FMA s (patchOp o1) (patchOp o2) (patchOp o3) (patchOp o4) - VFMA s fmt o1 o2 o3 -> - VFMA s fmt (patchOp o1) (patchOp o2) (patchOp o3) + VFMA s o1 o2 o3 -> + VFMA s (patchOp o1) (patchOp o2) (patchOp o3) _ -> panic $ "patchRegsOfInstr: " ++ instrCon instr where patchOp :: Operand -> Operand @@ -362,7 +354,7 @@ mkSpillInstr _config (RegWithFormat reg fmt) delta slot = = scalarMoveFormat fmt mkStrSpImm imm = ANN (text "Spill@" <> int (off - delta)) - $ STR fmt' (OpReg W64 reg) (OpAddr (AddrRegImm spMachReg (ImmInt imm))) + $ STR fmt' (OpReg fmt' reg) (OpAddr (AddrRegImm spMachReg (ImmInt imm))) movImmToTmp imm = ANN (text "Spill: TMP <- " <> int imm) $ MOV tmp (OpImm (ImmInt imm)) @@ -371,7 +363,7 @@ mkSpillInstr _config (RegWithFormat reg fmt) delta slot = $ ADD tmp tmp sp mkStrTmp = ANN (text "Spill@" <> int (off - delta)) - $ STR fmt' (OpReg W64 reg) (OpAddr (AddrReg tmpReg)) + $ STR fmt' (OpReg fmt' reg) (OpAddr (AddrReg tmpReg)) off = spillSlotToOffset slot @@ -401,7 +393,7 @@ mkLoadInstr _config (RegWithFormat reg fmt) delta slot = = scalarMoveFormat fmt mkLdrSpImm imm = ANN (text "Reload@" <> int (off - delta)) - $ LDR fmt' (OpReg W64 reg) (OpAddr (AddrRegImm spMachReg (ImmInt imm))) + $ LDR fmt' (OpReg fmt' reg) (OpAddr (AddrRegImm spMachReg (ImmInt imm))) movImmToTmp imm = ANN (text "Reload: TMP <- " <> int imm) $ MOV tmp (OpImm (ImmInt imm)) @@ -410,7 +402,7 @@ mkLoadInstr _config (RegWithFormat reg fmt) delta slot = $ ADD tmp tmp sp mkLdrTmp = ANN (text "Reload@" <> int (off - delta)) - $ LDR fmt' (OpReg W64 reg) (OpAddr (AddrReg tmpReg)) + $ LDR fmt' (OpReg fmt' reg) (OpAddr (AddrReg tmpReg)) off = spillSlotToOffset slot @@ -444,11 +436,11 @@ isMetaInstr instr = -- | Copy the value in a register to another one. -- -- Must work for all register classes. -mkRegRegMoveInstr :: Reg -> Reg -> Instr -mkRegRegMoveInstr src dst = ANN desc instr +mkRegRegMoveInstr :: Format -> Reg -> Reg -> Instr +mkRegRegMoveInstr fmt src dst = ANN desc instr where desc = text "Reg->Reg Move: " <> ppr src <> text " -> " <> ppr dst - instr = MOV (operandFromReg dst) (operandFromReg src) + instr = MOV (operandFromReg fmt dst) (operandFromReg fmt src) -- | Take the source and destination from this (potential) reg -> reg move instruction -- @@ -675,24 +667,24 @@ data Instr FMA FMASign Operand Operand Operand Operand -- TODO: Care about the variants (.x.y) -> sum type - | VMV Format Operand Operand - | VID Format Operand - | VMSEQ Format Operand Operand Operand - | VMERGE Format Operand Operand Operand Operand - | VSLIDEDOWN Format Operand Operand Operand - | VSETIVLI Reg Word Width VectorGrouping TailAgnosticFlag MaskAgnosticFlag - | VNEG Format Operand Operand - | VADD Format Operand Operand Operand - | VSUB Format Operand Operand Operand - | VMUL Format Operand Operand Operand - | VQUOT Format Operand Operand Operand - | VSMIN Format Operand Operand Operand - | VSMAX Format Operand Operand Operand - | VUMIN Format Operand Operand Operand - | VUMAX Format Operand Operand Operand - | VFMIN Format Operand Operand Operand - | VFMAX Format Operand Operand Operand - | VFMA FMASign Format Operand Operand Operand + | VMV Operand Operand + | VID Operand + | VMSEQ Operand Operand Operand + | VMERGE Operand Operand Operand Operand + | VSLIDEDOWN Operand Operand Operand + | VSETIVLI Operand Word Width VectorGrouping TailAgnosticFlag MaskAgnosticFlag + | VNEG Operand Operand + | VADD Operand Operand Operand + | VSUB Operand Operand Operand + | VMUL Operand Operand Operand + | VQUOT Operand Operand Operand + | VSMIN Operand Operand Operand + | VSMAX Operand Operand Operand + | VUMIN Operand Operand Operand + | VUMAX Operand Operand Operand + | VFMIN Operand Operand Operand + | VFMAX Operand Operand Operand + | VFMA FMASign Operand Operand Operand -- | Operand of a FENCE instruction (@r@, @w@ or @rw@) data FenceType = FenceRead | FenceWrite | FenceReadWrite @@ -780,7 +772,7 @@ instrCon i = FMSub -> "FMSUB" FNMAdd -> "FNMADD" FNMSub -> "FNMSUB" - VFMA variant _ _ _ _ -> + VFMA variant _ _ _ -> case variant of FMAdd -> "VFMADD" FMSub -> "VFMSUB" @@ -791,152 +783,132 @@ data Target = TBlock BlockId | TReg Reg --- TODO: OpReg should carry the format, not only the width. This would unify OpReg and OpVecReg. data Operand = -- | register - OpReg Width Reg + OpReg Format Reg | -- | immediate value OpImm Imm | -- | memory reference OpAddr AddrMode deriving (Eq, Show) -operandFromReg :: Reg -> Operand -operandFromReg = OpReg W64 +-- TODO: This just wraps a constructor... Inline? +operandFromReg :: Format -> Reg -> Operand +operandFromReg = OpReg -operandFromRegNo :: RegNo -> Operand -operandFromRegNo = operandFromReg . regSingle +operandFromRegNo :: Format -> RegNo -> Operand +operandFromRegNo fmt = operandFromReg fmt . regSingle zero, ra, sp, gp, tp, fp, tmp :: Operand -zero = operandFromReg zeroReg -ra = operandFromReg raReg -sp = operandFromReg spMachReg -gp = operandFromRegNo 3 -tp = operandFromRegNo 4 -fp = operandFromRegNo 8 -tmp = operandFromReg tmpReg +zero = operandFromReg II64 zeroReg +ra = operandFromReg II64 raReg +sp = operandFromReg II64 spMachReg +gp = operandFromRegNo II64 3 +tp = operandFromRegNo II64 4 +fp = operandFromRegNo II64 8 +tmp = operandFromReg II64 tmpReg x0, x1, x2, x3, x4, x5, x6, x7 :: Operand x8, x9, x10, x11, x12, x13, x14, x15 :: Operand x16, x17, x18, x19, x20, x21, x22, x23 :: Operand x24, x25, x26, x27, x28, x29, x30, x31 :: Operand -x0 = operandFromRegNo x0RegNo -x1 = operandFromRegNo 1 -x2 = operandFromRegNo 2 -x3 = operandFromRegNo 3 -x4 = operandFromRegNo 4 -x5 = operandFromRegNo x5RegNo -x6 = operandFromRegNo 6 -x7 = operandFromRegNo x7RegNo - -x8 = operandFromRegNo 8 - -x9 = operandFromRegNo 9 - -x10 = operandFromRegNo x10RegNo - -x11 = operandFromRegNo 11 - -x12 = operandFromRegNo 12 - -x13 = operandFromRegNo 13 - -x14 = operandFromRegNo 14 - -x15 = operandFromRegNo 15 - -x16 = operandFromRegNo 16 - -x17 = operandFromRegNo x17RegNo - -x18 = operandFromRegNo 18 - -x19 = operandFromRegNo 19 - -x20 = operandFromRegNo 20 - -x21 = operandFromRegNo 21 - -x22 = operandFromRegNo 22 - -x23 = operandFromRegNo 23 - -x24 = operandFromRegNo 24 - -x25 = operandFromRegNo 25 - -x26 = operandFromRegNo 26 - -x27 = operandFromRegNo 27 - -x28 = operandFromRegNo x28RegNo - -x29 = operandFromRegNo 29 - -x30 = operandFromRegNo 30 - -x31 = operandFromRegNo x31RegNo +x0 = operandFromRegNo II64 x0RegNo +x1 = operandFromRegNo II64 1 +x2 = operandFromRegNo II64 2 +x3 = operandFromRegNo II64 3 +x4 = operandFromRegNo II64 4 +x5 = operandFromRegNo II64 x5RegNo +x6 = operandFromRegNo II64 6 +x7 = operandFromRegNo II64 x7RegNo + +x8 = operandFromRegNo II64 8 + +x9 = operandFromRegNo II64 9 + +x10 = operandFromRegNo II64 x10RegNo + +x11 = operandFromRegNo II64 11 +x12 = operandFromRegNo II64 12 +x13 = operandFromRegNo II64 13 +x14 = operandFromRegNo II64 14 +x15 = operandFromRegNo II64 15 +x16 = operandFromRegNo II64 16 +x17 = operandFromRegNo II64 x17RegNo +x18 = operandFromRegNo II64 18 +x19 = operandFromRegNo II64 19 +x20 = operandFromRegNo II64 20 +x21 = operandFromRegNo II64 21 +x22 = operandFromRegNo II64 22 +x23 = operandFromRegNo II64 23 +x24 = operandFromRegNo II64 24 +x25 = operandFromRegNo II64 25 +x26 = operandFromRegNo II64 26 +x27 = operandFromRegNo II64 27 +x28 = operandFromRegNo II64 x28RegNo +x29 = operandFromRegNo II64 29 +x30 = operandFromRegNo II64 30 +x31 = operandFromRegNo II64 x31RegNo d0, d1, d2, d3, d4, d5, d6, d7 :: Operand d8, d9, d10, d11, d12, d13, d14, d15 :: Operand d16, d17, d18, d19, d20, d21, d22, d23 :: Operand d24, d25, d26, d27, d28, d29, d30, d31 :: Operand -d0 = operandFromRegNo d0RegNo -d1 = operandFromRegNo 33 -d2 = operandFromRegNo 34 -d3 = operandFromRegNo 35 -d4 = operandFromRegNo 36 -d5 = operandFromRegNo 37 -d6 = operandFromRegNo 38 -d7 = operandFromRegNo d7RegNo +d0 = operandFromRegNo FF64 d0RegNo +d1 = operandFromRegNo FF64 33 +d2 = operandFromRegNo FF64 34 +d3 = operandFromRegNo FF64 35 +d4 = operandFromRegNo FF64 36 +d5 = operandFromRegNo FF64 37 +d6 = operandFromRegNo FF64 38 +d7 = operandFromRegNo FF64 d7RegNo -d8 = operandFromRegNo 40 +d8 = operandFromRegNo FF64 40 -d9 = operandFromRegNo 41 +d9 = operandFromRegNo FF64 41 -d10 = operandFromRegNo d10RegNo +d10 = operandFromRegNo FF64 d10RegNo -d11 = operandFromRegNo 43 +d11 = operandFromRegNo FF64 43 -d12 = operandFromRegNo 44 +d12 = operandFromRegNo FF64 44 -d13 = operandFromRegNo 45 +d13 = operandFromRegNo FF64 45 -d14 = operandFromRegNo 46 +d14 = operandFromRegNo FF64 46 -d15 = operandFromRegNo 47 +d15 = operandFromRegNo FF64 47 -d16 = operandFromRegNo 48 +d16 = operandFromRegNo FF64 48 -d17 = operandFromRegNo d17RegNo +d17 = operandFromRegNo FF64 d17RegNo -d18 = operandFromRegNo 50 +d18 = operandFromRegNo FF64 50 -d19 = operandFromRegNo 51 +d19 = operandFromRegNo FF64 51 -d20 = operandFromRegNo 52 +d20 = operandFromRegNo FF64 52 -d21 = operandFromRegNo 53 +d21 = operandFromRegNo FF64 53 -d22 = operandFromRegNo 54 +d22 = operandFromRegNo FF64 54 -d23 = operandFromRegNo 55 +d23 = operandFromRegNo FF64 55 -d24 = operandFromRegNo 56 +d24 = operandFromRegNo FF64 56 -d25 = operandFromRegNo 57 +d25 = operandFromRegNo FF64 57 -d26 = operandFromRegNo 58 +d26 = operandFromRegNo FF64 58 -d27 = operandFromRegNo 59 +d27 = operandFromRegNo FF64 59 -d28 = operandFromRegNo 60 +d28 = operandFromRegNo FF64 60 -d29 = operandFromRegNo 61 +d29 = operandFromRegNo FF64 61 -d30 = operandFromRegNo 62 +d30 = operandFromRegNo FF64 62 -d31 = operandFromRegNo d31RegNo +d31 = operandFromRegNo FF64 d31RegNo fitsIn12bitImm :: (Num a, Ord a) => a -> Bool fitsIn12bitImm off = off >= intMin12bit && off <= intMax12bit @@ -957,7 +929,7 @@ isEncodeableInWidth :: Width -> Integer -> Bool isEncodeableInWidth = isNbitEncodeable . widthInBits isIntRegOp :: Operand -> Bool -isIntRegOp (OpReg _ reg) | isIntReg reg = True +isIntRegOp (OpReg fmt reg) | isIntReg reg = assertFmtReg fmt reg $ True isIntRegOp _ = False isIntImmOp :: Operand -> Bool @@ -969,7 +941,7 @@ isIntOp :: Operand -> Bool isIntOp op = isIntRegOp op || isIntImmOp op isFloatRegOp :: Operand -> Bool -isFloatRegOp (OpReg _ reg) | isFloatReg reg = True +isFloatRegOp (OpReg fmt reg) | isFloatReg reg = assertFmtReg fmt reg $ True isFloatRegOp _ = False isFloatImmOp :: Operand -> Bool @@ -980,8 +952,21 @@ isFloatImmOp _ = False isFloatOp :: Operand -> Bool isFloatOp op = isFloatRegOp op || isFloatImmOp op +-- TODO: Hide OpReg (Operand) constructor and use this guard to ensure only sane fmt/reg combinations can be used +assertFmtReg :: HasCallStack => Format -> Reg -> a -> a +assertFmtReg fmt reg| fmtRegCombinationIsSane fmt reg = id +assertFmtReg fmt reg = pprPanic + "Format does not fit to register." + (text "fmt" <> colon <+> ppr fmt <+> text "reg" <> colon <+> ppr reg) + +fmtRegCombinationIsSane :: Format -> Reg -> Bool +fmtRegCombinationIsSane fmt reg = + (isFloatFormat fmt && isFloatReg reg) || + (isIntFormat fmt && isIntReg reg) || + (isVecFormat fmt && isVectorReg reg) + isVectorRegOp :: Operand -> Bool -isVectorRegOp (OpReg _ reg) | isVectorReg reg = True +isVectorRegOp (OpReg fmt reg) | isVectorReg reg = assertFmtReg fmt reg $ True isVectorRegOp _ = False isFloatReg :: Reg -> Bool ===================================== compiler/GHC/CmmToAsm/RV64/Ppr.hs ===================================== @@ -320,20 +320,20 @@ pprOp :: (IsLine doc) => Platform -> Operand -> doc pprOp plat op = case op of OpReg w r -> pprReg w r OpImm im -> pprOpImm plat im - OpAddr (AddrRegImm r1 im) -> pprOpImm plat im <> char '(' <> pprReg W64 r1 <> char ')' - OpAddr (AddrReg r1) -> text "0(" <+> pprReg W64 r1 <+> char ')' + OpAddr (AddrRegImm r1 im) -> pprOpImm plat im <> char '(' <> pprReg II64 r1 <> char ')' + OpAddr (AddrReg r1) -> text "0(" <+> pprReg II64 r1 <+> char ')' -- | Pretty print register with calling convention name -- -- This representation makes it easier to reason about the emitted assembly -- code. -pprReg :: forall doc. (IsLine doc) => Width -> Reg -> doc -pprReg w r = case r of +pprReg :: forall doc. (IsLine doc) => Format -> Reg -> doc +pprReg fmt r = assertFmtReg fmt r $ case r of RegReal (RealRegSingle i) -> ppr_reg_no i -- virtual regs should not show up, but this is helpful for debugging. RegVirtual (VirtualRegI u) -> text "%vI_" <> pprUniqueAlways u RegVirtual (VirtualRegD u) -> text "%vD_" <> pprUniqueAlways u - _ -> pprPanic "RiscV64.pprReg" (text (show r) <+> ppr w) + _ -> pprPanic "RiscV64.pprReg" (text (show r) <+> ppr fmt) where ppr_reg_no :: Int -> doc -- General Purpose Registers @@ -435,19 +435,19 @@ pprReg w r = case r of ppr_reg_no 94 = text "v30" ppr_reg_no 95 = text "v31" ppr_reg_no i - | i < 0 = pprPanic "Unexpected register number (min is 0)" (ppr w <+> int i) - | i > 95 = pprPanic "Unexpected register number (max is 95)" (ppr w <+> int i) + | i < 0 = pprPanic "Unexpected register number (min is 0)" (ppr fmt <+> int i) + | i > 95 = pprPanic "Unexpected register number (max is 95)" (ppr fmt <+> int i) -- no support for widths > W64. - | otherwise = pprPanic "Unsupported width in register (max is 95)" (ppr w <+> int i) + | otherwise = pprPanic "Unsupported width in register (max is 95)" (ppr fmt <+> int i) -- | Single precission `Operand` (floating-point) isSingleOp :: Operand -> Bool -isSingleOp (OpReg W32 _) = True +isSingleOp (OpReg FF32 _) = True isSingleOp _ = False -- | Double precission `Operand` (floating-point) isDoubleOp :: Operand -> Bool -isDoubleOp (OpReg W64 _) = True +isDoubleOp (OpReg FF64 _) = True isDoubleOp _ = False -- | `Operand` is an immediate value @@ -508,7 +508,7 @@ pprInstr platform instr = case instr of ADD o1 o2 o3 | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 -> op3 (text "\tfadd." <> if isSingleOp o1 then text "s" else text "d") o1 o2 o3 -- This case is used for sign extension: SEXT.W op - | OpReg W64 _ <- o1, OpReg W32 _ <- o2, isImmOp o3 -> op3 (text "\taddiw") o1 o2 o3 + | OpReg II64 _ <- o1, OpReg II32 _ <- o2, isImmOp o3 -> op3 (text "\taddiw") o1 o2 o3 | otherwise -> op3 (text "\tadd") o1 o2 o3 MUL o1 o2 o3 | isFloatOp o1 && isFloatOp o2 && isFloatOp o3 -> op3 (text "\tfmul." <> if isSingleOp o1 then text "s" else text "d") o1 o2 o3 @@ -580,8 +580,8 @@ pprInstr platform instr = case instr of XORI o1 o2 o3 -> op3 (text "\txori") o1 o2 o3 J_TBL _ _ r -> pprInstr platform (B (TReg r)) B l | isLabel l -> line $ text "\tjal" <+> pprOp platform x0 <> comma <+> getLabel platform l - B (TReg r) -> line $ text "\tjalr" <+> pprOp platform x0 <> comma <+> pprReg W64 r <> comma <+> text "0" - BL r _ -> line $ text "\tjalr" <+> text "x1" <> comma <+> pprReg W64 r <> comma <+> text "0" + B (TReg r) -> line $ text "\tjalr" <+> pprOp platform x0 <> comma <+> pprReg II64 r <> comma <+> text "0" + BL r _ -> line $ text "\tjalr" <+> text "x1" <> comma <+> pprReg II64 r <> comma <+> text "0" BCOND c l r t | isLabel t -> line $ text "\t" <> pprBcond c <+> pprOp platform l <> comma <+> pprOp platform r <> comma <+> getLabel platform t @@ -699,22 +699,22 @@ pprInstr platform instr = case instr of LDRU fmt@(VecFormat _ FmtDouble) o1 o2 -> configVec fmt $$ op2 (text "\tvle64.v") o1 o2 LDRU f o1 o2 -> pprPanic "Unsupported unsigned load" ((text . show) f <+> pprOp platform o1 <+> pprOp platform o2) FENCE r w -> line $ text "\tfence" <+> pprFenceType r <> char ',' <+> pprFenceType w - FCVT FloatToFloat o1@(OpReg W32 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.s.d") o1 o2 - FCVT FloatToFloat o1@(OpReg W64 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.d.s") o1 o2 + FCVT FloatToFloat o1@(OpReg FF32 _) o2@(OpReg FF64 _) -> op2 (text "\tfcvt.s.d") o1 o2 + FCVT FloatToFloat o1@(OpReg FF64 _) o2@(OpReg FF32 _) -> op2 (text "\tfcvt.d.s") o1 o2 FCVT FloatToFloat o1 o2 -> pprPanic "RV64.pprInstr - impossible float to float conversion" $ line (pprOp platform o1 <> text "->" <> pprOp platform o2) - FCVT IntToFloat o1@(OpReg W32 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.s.w") o1 o2 - FCVT IntToFloat o1@(OpReg W32 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.s.l") o1 o2 - FCVT IntToFloat o1@(OpReg W64 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.d.w") o1 o2 - FCVT IntToFloat o1@(OpReg W64 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.d.l") o1 o2 + FCVT IntToFloat o1@(OpReg FF32 _) o2@(OpReg II32 _) -> op2 (text "\tfcvt.s.w") o1 o2 + FCVT IntToFloat o1@(OpReg FF32 _) o2@(OpReg II64 _) -> op2 (text "\tfcvt.s.l") o1 o2 + FCVT IntToFloat o1@(OpReg FF64 _) o2@(OpReg II32 _) -> op2 (text "\tfcvt.d.w") o1 o2 + FCVT IntToFloat o1@(OpReg FF64 _) o2@(OpReg II64 _) -> op2 (text "\tfcvt.d.l") o1 o2 FCVT IntToFloat o1 o2 -> pprPanic "RV64.pprInstr - impossible integer to float conversion" $ line (pprOp platform o1 <> text "->" <> pprOp platform o2) - FCVT FloatToInt o1@(OpReg W32 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.w.s") o1 o2 - FCVT FloatToInt o1@(OpReg W32 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.w.d") o1 o2 - FCVT FloatToInt o1@(OpReg W64 _) o2@(OpReg W32 _) -> op2 (text "\tfcvt.l.s") o1 o2 - FCVT FloatToInt o1@(OpReg W64 _) o2@(OpReg W64 _) -> op2 (text "\tfcvt.l.d") o1 o2 + FCVT FloatToInt o1@(OpReg II32 _) o2@(OpReg FF32 _) -> op2 (text "\tfcvt.w.s") o1 o2 + FCVT FloatToInt o1@(OpReg II32 _) o2@(OpReg FF64 _) -> op2 (text "\tfcvt.w.d") o1 o2 + FCVT FloatToInt o1@(OpReg II64 _) o2@(OpReg FF32 _) -> op2 (text "\tfcvt.l.s") o1 o2 + FCVT FloatToInt o1@(OpReg II64 _) o2@(OpReg FF64 _) -> op2 (text "\tfcvt.l.d") o1 o2 FCVT FloatToInt o1 o2 -> pprPanic "RV64.pprInstr - impossible float to integer conversion" $ line (pprOp platform o1 <> text "->" <> pprOp platform o2) @@ -733,7 +733,7 @@ pprInstr platform instr = case instr of FNMAdd -> text "\tfnmadd" <> dot <> floatPrecission d FNMSub -> text "\tfnmsub" <> dot <> floatPrecission d in op4 fma d r1 r2 r3 - VFMA variant fmt o1 o2 o3 | VecFormat l fmt' <- fmt -> + VFMA variant o1@(OpReg fmt _reg) o2 o3 | VecFormat l fmt' <- fmt -> let formatString = if (isFloatFormat . scalarFormatFormat) fmt' then text "f" else text "" prefix = text "v" <> formatString suffix = text "vv" @@ -743,26 +743,31 @@ pprInstr platform instr = case instr of FNMAdd -> text "nmadd" -- TODO: Works only for floats! FNMSub -> text "nmsub" in op3 (tab <> prefix <> fma <> dot <> suffix) o1 o2 o3 - VMV fmt o1 o2 | isFloatOp o1 && isVectorRegOp o2 -> configVec fmt $$ op2 (text "\tvfmv" <> dot <> text "f" <> dot <> text "s") o1 o2 + VFMA _variant o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VFMA can only target registers." (pprOp platform o1) + VMV o1@(OpReg fmt _reg) o2 | isFloatOp o1 && isVectorRegOp o2 -> configVec fmt $$ op2 (text "\tvfmv" <> dot <> text "f" <> dot <> text "s") o1 o2 | isFloatOp o2 -> configVec fmt $$ op2 (text "\tvfmv" <> dot <> opToVInstrSuffix o1 <> dot <> text "f") o1 o2 | isIntRegOp o1 && isVectorRegOp o2 -> configVec fmt $$ op2 (text "\tvmv" <> dot <> text "x" <> dot <> text "s") o1 o2 | isIntRegOp o2 -> configVec fmt $$ op2 (text "\tvmv" <> dot <> opToVInstrSuffix o1 <> dot <> text "x") o1 o2 | isVectorRegOp o1 && isVectorRegOp o2 -> configVec fmt $$ op2 (text "\tvmv" <> dot <> opToVInstrSuffix o1 <> dot <> text "v") o1 o2 | True -> pprPanic "RV64.pprInstr - impossible vector move (VMV)" (pprOp platform o1 <+> pprOp platform o2 <+> text "fmt" <> colon <> (text . show) fmt) - -- TODO: Remove o2 from constructor - VID fmt o1 -> configVec fmt $$ op1 (text "\tvid.v") o1 + VMV o1 _o2 -> pprPanic "RV64.pprInstr - VMV can only target registers." (pprOp platform o1) + VID op@(OpReg fmt _reg) -> configVec fmt $$ op1 (text "\tvid.v") op + VID op -> pprPanic "RV64.pprInstr - VID can only target registers." (pprOp platform op) -- TODO: This expects int register as third operand: Generalize by calculating -- the instruction suffix (".vx") - VMSEQ fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvmseq.vx") o1 o2 o3 + VMSEQ o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvmseq.vx") o1 o2 o3 + VMSEQ o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VMSEQ can only target registers." (pprOp platform o1) -- TODO: All operands need to be vector registers. Make this more general or -- validate this constraint. - VMERGE fmt o1 o2 o3 o4 -> configVec fmt $$ op4 (text "\tvmerge.vvm") o1 o2 o3 o4 - VSLIDEDOWN fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvslidedown.vx") o1 o2 o3 - -- TODO: Use configVec, adjust VSETIVLI to contain only format? - VSETIVLI dst len width grouping ta ma -> + VMERGE o1@(OpReg fmt _reg) o2 o3 o4 -> configVec fmt $$ op4 (text "\tvmerge.vvm") o1 o2 o3 o4 + VMERGE o1 _o2 _o3 _o4 -> pprPanic "RV64.pprInstr - VMERGE can only target registers." (pprOp platform o1) + VSLIDEDOWN o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvslidedown.vx") o1 o2 o3 + VSLIDEDOWN o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VSLIDEDOWN can only target registers." (pprOp platform o1) + -- TODO: adjust VSETIVLI to contain only format? + VSETIVLI (OpReg fmt dst) len width grouping ta ma -> line $ text "\tvsetivli" - <+> pprReg W64 dst + <+> pprReg fmt dst <> comma <+> (text . show) len <> comma @@ -773,17 +778,29 @@ pprInstr platform instr = case instr of <+> pprTA ta <> comma <+> pprMasking ma - VNEG fmt o1 o2 -> configVec fmt $$ op2 (text "\tvfneg.v") o1 o2 - VADD fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvfadd.vv") o1 o2 o3 - VSUB fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvfsub.vv") o1 o2 o3 - VMUL fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvfmul.vv") o1 o2 o3 - VQUOT fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvfdiv.vv") o1 o2 o3 - VSMIN fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvmin.vv") o1 o2 o3 - VSMAX fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvmax.vv") o1 o2 o3 - VUMIN fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvminu.vv") o1 o2 o3 - VUMAX fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvmaxu.vv") o1 o2 o3 - VFMIN fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvfmin.vv") o1 o2 o3 - VFMAX fmt o1 o2 o3 -> configVec fmt $$ op3 (text "\tvfmax.vv") o1 o2 o3 + VSETIVLI o1 _ _ _ _ _ -> pprPanic "RV64.pprInstr - VSETIVLI can only target registers." (pprOp platform o1) + VNEG o1@(OpReg fmt _reg) o2 -> configVec fmt $$ op2 (text "\tvfneg.v") o1 o2 + VNEG o1 _o2 -> pprPanic "RV64.pprInstr - VNEG can only target registers." (pprOp platform o1) + VADD o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfadd.vv") o1 o2 o3 + VADD o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VADD can only target registers." (pprOp platform o1) + VSUB o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfsub.vv") o1 o2 o3 + VSUB o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VSUB can only target registers." (pprOp platform o1) + VMUL o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfmul.vv") o1 o2 o3 + VMUL o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VMUL can only target registers." (pprOp platform o1) + VQUOT o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfdiv.vv") o1 o2 o3 + VQUOT o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VQUOT can only target registers." (pprOp platform o1) + VSMIN o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvmin.vv") o1 o2 o3 + VSMIN o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VSMIN can only target registers." (pprOp platform o1) + VSMAX o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvmax.vv") o1 o2 o3 + VSMAX o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VSMAX can only target registers." (pprOp platform o1) + VUMIN o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvminu.vv") o1 o2 o3 + VUMIN o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VUMIN can only target registers." (pprOp platform o1) + VUMAX o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvmaxu.vv") o1 o2 o3 + VUMAX o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VUMAX can only target registers." (pprOp platform o1) + VFMIN o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfmin.vv") o1 o2 o3 + VFMIN o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VFMIN can only target registers." (pprOp platform o1) + VFMAX o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfmax.vv") o1 o2 o3 + VFMAX o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VFMAX can only target registers." (pprOp platform o1) instr -> panic $ "RV64.pprInstr - Unknown instruction: " ++ instrCon instr where op1 op o1 = line $ op <+> pprOp platform o1 @@ -825,15 +842,9 @@ pprInstr platform instr = case instr of opToVInstrSuffix op | isVectorRegOp op = text "v" opToVInstrSuffix op = pprPanic "Unsupported operand for vector instruction" (pprOp platform op) - -- TODO: unused? - floatWidthSuffix :: (IsLine doc) => Width -> doc - floatWidthSuffix W32 = text "s" - floatWidthSuffix W64 = text "d" - floatWidthSuffix w = pprPanic "Unsupported floating point vector operation width" (ppr w) - configVec :: (IsDoc doc) => Format -> doc configVec (VecFormat length fmt) = - pprInstr platform (VSETIVLI zeroReg (fromIntegral length) ((formatToWidth . scalarFormatFormat) fmt) M1 TA MA) + pprInstr platform (VSETIVLI (OpReg II64 zeroReg) (fromIntegral length) ((formatToWidth . scalarFormatFormat) fmt) M1 TA MA) configVec fmt = pprPanic "Unsupported vector configuration" ((text . show) fmt) floatOpPrecision :: Platform -> Operand -> Operand -> String ===================================== compiler/GHC/CmmToAsm/RV64/Regs.hs ===================================== @@ -72,7 +72,7 @@ fa7RegNo, d17RegNo :: RegNo d17RegNo = 49 fa7RegNo = d17RegNo -v0RegNo ::RegNo +v0RegNo :: RegNo v0RegNo = 64 v8RegNo :: RegNo @@ -123,7 +123,7 @@ tmpReg = regSingle tmpRegNo v0Reg :: Reg v0Reg = regSingle v0RegNo --- | All machine register numbers. +-- | All machine register numbers. Including potential vector registers. allMachRegNos :: [RegNo] allMachRegNos = intRegs ++ fpRegs ++ vRegs where @@ -137,6 +137,11 @@ allMachRegNos = intRegs ++ fpRegs ++ vRegs -- These are all registers minus those with a fixed role in RISCV ABI (zero, lr, -- sp, gp, tp, fp, tmp) and GHC RTS (Base, Sp, Hp, HpLim, R1..R8, F1..F6, -- D1..D6.) +-- +-- We pretend that vector registers are always available. If they aren't, we +-- simply don't emit instructions using them. This is much simpler than fixing +-- the register allocators which expect a configuration per platform (which we +-- can only set when GHC itself gets build.) allocatableRegs :: Platform -> [RealReg] allocatableRegs platform = let isFree = freeReg platform View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/91169343d138c1afd81ee9aaa04711b9659d731b...715a80b12d5479512c9bd0130c8070c28b65f1cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/91169343d138c1afd81ee9aaa04711b9659d731b...715a80b12d5479512c9bd0130c8070c28b65f1cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 17:51:49 2025 From: gitlab at gitlab.haskell.org (Serge S. Gulin (@gulin.serge)) Date: Sat, 25 Jan 2025 12:51:49 -0500 Subject: [Git][ghc/ghc][wip/T24603] 3 commits: Merge ghc-prim's modules into ghc-internal (#24453) Message-ID: <679524b5a387_2e40e7120163c190d7@gitlab.mail> Serge S. Gulin pushed to branch wip/T24603 at Glasgow Haskell Compiler / GHC Commits: c3593101 by Sylvain Henry at 2025-01-24T23:12:20-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 70f7741a by Jens Petersen at 2025-01-24T23:12:58-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - 002e26c0 by Serge S. Gulin at 2025-01-25T20:51:32+03:00 Support for ARM64 Windows (LLVM-enabled) (fixes #24603) submodule Co-authored-by: Cheng Shao <terrorjack at type.dance> Co-authored-by: Dmitrii Egorov <egorov.d.i at icloud.com> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser/Header.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/ModSummary.hs - compiler/GHC/Unit/Types.hs - hadrian/cabal.project - hadrian/src/Flavour.hs - hadrian/src/Packages.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Packages.hs - hadrian/src/Settings/Warnings.hs - libraries/Cabal - libraries/Win32 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/612da63c1dc13a4d9a8ee1cefcf6c3343581d5ea...002e26c0ba0415ceac14f9717eb6dc03e7f66d4a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/612da63c1dc13a4d9a8ee1cefcf6c3343581d5ea...002e26c0ba0415ceac14f9717eb6dc03e7f66d4a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 20:51:33 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sat, 25 Jan 2025 15:51:33 -0500 Subject: [Git][ghc/ghc][wip/T25623] 33 commits: Add flags for switching off speculative evaluation. Message-ID: <67954ed59a188_3956d5c0a6c746d6@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: 23099752 by Luite Stegeman at 2025-01-08T00:33:33+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 - - - - - 0161badc by Ben Gamari at 2025-01-09T17:30:05-05:00 rts/printClosure: Print IPE information for thunks and functions This makes it considerably easier to grok the structure of the heap when IPE information is available. - - - - - 023f36f5 by Rodrigo Mesquita at 2025-01-10T14:57:48-05:00 user_guide: Note -pgmP/-optP are for /Haskell/-CPP Fixes #25574 - - - - - e1c133f2 by Ben Gamari at 2025-01-10T14:58:25-05:00 dump-decls: Suppress unit-ids While the testsuite driver already normalizes these away, they are nevertheless a severe nuisance when diffing outside of the testsuite. Intriguingly, this doesn't completely eliminate the unit IDs; some wired-in names are still printed. However, this is a cheap and helpful improvement over the status quo so I am simply going to accept this. Fixes #25334. - - - - - 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 51e3ec83 by Vladislav Zavialov at 2025-01-22T20:41:32+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 85c60aea by Teo Camarasu at 2025-01-23T18:06:21-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4495e48f by Brandon Chinn at 2025-01-24T11:54:24-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 4f8fc11e by Brandon Chinn at 2025-01-24T11:54:24-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - e7ab778f by Matthew Pickering at 2025-01-24T11:55:01-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - c3593101 by Sylvain Henry at 2025-01-24T23:12:20-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 70f7741a by Jens Petersen at 2025-01-24T23:12:58-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - 2243e43c by Brandon Chinn at 2025-01-25T12:51:22-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 29 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Config/CoreToStg/Prep.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4aefca346244e071943fa981ecaf91c5507fab80...2243e43c8dd2d0bb83b09ea8783d6ca623cc14f6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4aefca346244e071943fa981ecaf91c5507fab80...2243e43c8dd2d0bb83b09ea8783d6ca623cc14f6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 23:12:15 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sat, 25 Jan 2025 18:12:15 -0500 Subject: [Git][ghc/ghc][wip/T25623] Fix for alex-3.5.2.0 (#25623) Message-ID: <67956fcf5939_3ceffd69019029273@gitlab.mail> Brandon Chinn pushed to branch wip/T25623 at Glasgow Haskell Compiler / GHC Commits: a1d92378 by Brandon Chinn at 2025-01-25T15:11:54-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 1 changed file: - compiler/GHC/Parser/Lexer.x Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3366,11 +3367,15 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#ifdef MIN_TOOL_VERSION_alex +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. -- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} +#endif +#endif lexToken :: P (PsLocated Token) lexToken = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1d923786baed5b001c523fd2a76f133be510b04 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1d923786baed5b001c523fd2a76f133be510b04 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat Jan 25 23:46:05 2025 From: gitlab at gitlab.haskell.org (Brandon Chinn (@brandonchinn178)) Date: Sat, 25 Jan 2025 18:46:05 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T21730-import Message-ID: <679577bdf8e0_3ceffdf261743032b@gitlab.mail> Brandon Chinn pushed new branch wip/T21730-import at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T21730-import You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 26 02:24:33 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sat, 25 Jan 2025 21:24:33 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Merge ghc-prim's modules into ghc-internal (#24453) Message-ID: <67959ce0da44b_3bfcd9466c8759fd@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c3593101 by Sylvain Henry at 2025-01-24T23:12:20-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 70f7741a by Jens Petersen at 2025-01-24T23:12:58-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - a1d92378 by Brandon Chinn at 2025-01-25T15:11:54-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 823f0f6e by Simon Hengel at 2025-01-25T21:24:24-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser/Header.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Unit/Finder.hs - compiler/GHC/Unit/Module/ModSummary.hs - compiler/GHC/Unit/Types.hs - docs/users_guide/diagnostics-as-json-schema-1_0.json - docs/users_guide/diagnostics-as-json-schema-1_1.json - hadrian/src/Flavour.hs - hadrian/src/Packages.hs - hadrian/src/Rules/CabalReinstall.hs - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Packages.hs - hadrian/src/Settings/Warnings.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b75dd11435c7038a18098e147e26642f01c1d405...823f0f6e9fd8b4ef3846af793c0b6efa0db8c247 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b75dd11435c7038a18098e147e26642f01c1d405...823f0f6e9fd8b4ef3846af793c0b6efa0db8c247 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 26 05:21:52 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Sun, 26 Jan 2025 00:21:52 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] 2 commits: hadrian: don't pass -this-package-name to GHC 9.2 Message-ID: <6795c6702cc5a_3bfcd2623c648329@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: aa3a51d3 by Luite Stegeman at 2025-01-26T05:27:54+01:00 hadrian: don't pass -this-package-name to GHC 9.2 it's not supported - - - - - 7f131c58 by Matthew Pickering at 2025-01-26T05:27:54+01:00 ghcup-metadata: Add --date flag to specify the release date The ghcup-metadata now has a viReleaseDay field which needs to be populated with the day of the release. (cherry picked from commit 1121bdd858b165cca41f11c57b6c821b90b7f936) - - - - - 4 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/mk-ghcup-metadata/README.mkd - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - hadrian/src/Settings/Builders/Ghc.hs Changes: ===================================== .gitlab-ci.yml ===================================== @@ -1043,7 +1043,7 @@ ghcup-metadata-nightly: artifacts: false - job: project-version script: - - nix shell --extra-experimental-features nix-command -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml" + - nix shell --extra-experimental-features nix-command -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --date="$(date -d $CI_PIPELINE_CREATED_AT +%Y-%M-%d)" --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml" rules: - if: $NIGHTLY ===================================== .gitlab/rel_eng/mk-ghcup-metadata/README.mkd ===================================== @@ -18,6 +18,7 @@ options: --release-mode Generate metadata which points to downloads folder --fragment Output the generated fragment rather than whole modified file --version VERSION Version of the GHC compiler + --date DATE Date of the compiler release ``` The script also requires the `.gitlab/jobs-metadata.yaml` file which can be generated ===================================== .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py ===================================== @@ -193,7 +193,7 @@ def mk_from_platform(pipeline_type, platform): # Generate the new metadata for a specific GHC mode etc -def mk_new_yaml(release_mode, version, pipeline_type, job_map): +def mk_new_yaml(release_mode, version, date, pipeline_type, job_map): def mk(platform): eprint("\n=== " + platform.name + " " + ('=' * (75 - len(platform.name)))) return mk_one_metadata(release_mode, version, job_map, mk_from_platform(pipeline_type, platform)) @@ -268,7 +268,13 @@ def mk_new_yaml(release_mode, version, pipeline_type, job_map): else: change_log = "https://gitlab.haskell.org" - return { "viTags": ["Latest", "TODO_base_version"] + if release_mode: + tags = ["Latest", "TODO_base_version"] + else: + tags = ["LatestNightly"] + + return { "viTags": tags + , "viReleaseDay": date # Check that this link exists , "viChangeLog": change_log , "viSourceDL": source @@ -305,6 +311,7 @@ def main() -> None: parser.add_argument('--fragment', action='store_true', help='Output the generated fragment rather than whole modified file') # TODO: We could work out the --version from the project-version CI job. parser.add_argument('--version', required=True, type=str, help='Version of the GHC compiler') + parser.add_argument('--date', required=True, type=str, help='Date of the compiler release') args = parser.parse_args() project = gl.projects.get(1, lazy=True) @@ -325,7 +332,7 @@ def main() -> None: eprint(f"Pipeline Type: {pipeline_type}") - new_yaml = mk_new_yaml(args.release_mode, args.version, pipeline_type, job_map) + new_yaml = mk_new_yaml(args.release_mode, args.version, args.date, pipeline_type, job_map) if args.fragment: print(yaml.dump({ args.version : new_yaml }, Dumper=mk_dumper(args.version))) ===================================== hadrian/src/Settings/Builders/Ghc.hs ===================================== @@ -247,10 +247,10 @@ packageGhcArgs = do , packageDatabaseArgs -- We want to pass -this-unit-id for executables as well for multi-repl to -- work with executable packages but this is buggy on GHC-9.0.2 - , (isLibrary package || (ghc_ver >= makeVersion [9,2,1])) ? mconcat - [ arg ("-this-unit-id " ++ pkgId) - , arg ("-this-package-name " ++ pkgName) - ] + , (isLibrary package || (ghc_ver >= makeVersion [9,2,1])) ? + arg ("-this-unit-id " ++ pkgId) + , (ghc_ver >= makeVersion [9,4,1]) ? + arg ("-this-package-name " ++ pkgName) , map ("-package-id " ++) <$> getContextData depIds ] includeGhcArgs :: Args View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4ccbf2ce5c1a6a9c44873f5e3067571261f40278...7f131c5873556d906c6cf46cf2d1eca31efb24d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4ccbf2ce5c1a6a9c44873f5e3067571261f40278...7f131c5873556d906c6cf46cf2d1eca31efb24d2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 26 06:06:46 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Sun, 26 Jan 2025 01:06:46 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) Message-ID: <6795d0f6d76d0_f649cc065c958cf@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4ae75288 by Simon Hengel at 2025-01-26T01:05:30-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - 2 changed files: - docs/users_guide/diagnostics-as-json-schema-1_0.json - docs/users_guide/diagnostics-as-json-schema-1_1.json Changes: ===================================== docs/users_guide/diagnostics-as-json-schema-1_0.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", ===================================== docs/users_guide/diagnostics-as-json-schema-1_1.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ae7528886c02745dc7a1f95f7db20a753167cab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ae7528886c02745dc7a1f95f7db20a753167cab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 26 06:53:34 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Sun, 26 Jan 2025 01:53:34 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] hadrian: Make sure ffi headers are built before using a compiler Message-ID: <6795dbeee1ded_1037045b12103842b@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: e69b5f63 by Matthew Pickering at 2025-01-26T07:52:38+01:00 hadrian: Make sure ffi headers are built before using a compiler When we are using ffi adjustors then we rely on `ffi.h` and `ffitarget.h` files during code generation when compiling stubs. Therefore we need to add this dependency to the build system (which this patch does). Reproducer, configure with `--enable-libffi-adjustors` and then build "_build/stage1/libraries/ghc-prim/build/GHC/Types.p_o". Observe that this fails before this patch and works afterwards. Fixes #24864 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> (cherry picked from commit 0167e472e7035d31591777983d8e35528aceefff) - - - - - 1 changed file: - hadrian/src/Builder.hs Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -241,6 +241,8 @@ instance H.Builder Builder where -- GHC from the previous stage is used to build artifacts in the -- current stage. Need the previous stage's GHC deps. ghcdeps <- ghcBinDeps (predStage stage) + libffi_adjustors <- useLibffiForAdjustors + use_system_ffi <- flag UseSystemFfi return $ [ unlitPath ] ++ ghcdeps @@ -249,6 +251,13 @@ instance H.Builder Builder where -- proxy for the entire mingw toolchain that -- we have in inplace/mingw initially, and then at -- root -/- mingw. + -- ffi.h needed by the compiler when using libffi_adjustors (#24864) + -- It would be nicer to not duplicate this logic between here + -- and needRtsLibffiTargets and libffiHeaderFiles but this doesn't change + -- very often. + ++ [ root -/- buildDir (rtsContext stage) -/- "include" -/- header + | header <- ["ffi.h", "ffitarget.h"] + , libffi_adjustors && not use_system_ffi ] Hsc2Hs stage -> (\p -> [p]) <$> templateHscPath stage Make dir -> return [dir -/- "Makefile"] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e69b5f63cb57982ac26ac5138b97ff8dbb16a407 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e69b5f63cb57982ac26ac5138b97ff8dbb16a407 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun Jan 26 12:18:43 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Sun, 26 Jan 2025 07:18:43 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] 2 commits: JS: fake support for native adjustors (#25159) Message-ID: <67962823ae1d7_1a78a77659a834481@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 1dd6f426 by Sylvain Henry at 2025-01-26T13:18:02+01:00 JS: fake support for native adjustors (#25159) The JS backend doesn't support adjustors (I believe) and in any case if it ever supports them it will be a native support, not one via libffi. (cherry picked from commit 03055c71446c8f1265de3a6ccb5bc9e09827821e) - - - - - 94794c38 by Matthew Pickering at 2025-01-26T13:18:02+01:00 hadrian: Make sure ffi headers are built before using a compiler When we are using ffi adjustors then we rely on `ffi.h` and `ffitarget.h` files during code generation when compiling stubs. Therefore we need to add this dependency to the build system (which this patch does). Reproducer, configure with `--enable-libffi-adjustors` and then build "_build/stage1/libraries/ghc-prim/build/GHC/Types.p_o". Observe that this fails before this patch and works afterwards. Fixes #24864 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> (cherry picked from commit 0167e472e7035d31591777983d8e35528aceefff) - - - - - 2 changed files: - hadrian/src/Builder.hs - m4/ghc_adjustors_method.m4 Changes: ===================================== hadrian/src/Builder.hs ===================================== @@ -241,6 +241,8 @@ instance H.Builder Builder where -- GHC from the previous stage is used to build artifacts in the -- current stage. Need the previous stage's GHC deps. ghcdeps <- ghcBinDeps (predStage stage) + libffi_adjustors <- useLibffiForAdjustors + use_system_ffi <- flag UseSystemFfi return $ [ unlitPath ] ++ ghcdeps @@ -249,6 +251,13 @@ instance H.Builder Builder where -- proxy for the entire mingw toolchain that -- we have in inplace/mingw initially, and then at -- root -/- mingw. + -- ffi.h needed by the compiler when using libffi_adjustors (#24864) + -- It would be nicer to not duplicate this logic between here + -- and needRtsLibffiTargets and libffiHeaderFiles but this doesn't change + -- very often. + ++ [ root -/- buildDir (rtsContext stage) -/- "include" -/- header + | header <- ["ffi.h", "ffitarget.h"] + , libffi_adjustors && not use_system_ffi ] Hsc2Hs stage -> (\p -> [p]) <$> templateHscPath stage Make dir -> return [dir -/- "Makefile"] ===================================== m4/ghc_adjustors_method.m4 ===================================== @@ -4,7 +4,7 @@ dnl Use libffi for adjustors? AC_DEFUN([GHC_ADJUSTORS_METHOD], [ case [$]{$1[Arch]} in - i386|x86_64) + i386|x86_64|javascript) # We have native adjustor support on these platforms HaveNativeAdjustor=yes ;; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e69b5f63cb57982ac26ac5138b97ff8dbb16a407...94794c38b62079ee0912b3561fbdbc2e6473ad89 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e69b5f63cb57982ac26ac5138b97ff8dbb16a407...94794c38b62079ee0912b3561fbdbc2e6473ad89 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 27 01:57:25 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Sun, 26 Jan 2025 20:57:25 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] 15 commits: ghcup metadata: output metadata fragment in CI Message-ID: <6796e8054fda8_2efdbc2ef95f0482e6@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 24d82823 by Zubin Duggal at 2025-01-27T02:55:36+01:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - f196f1fe by Zubin Duggal at 2025-01-27T02:55:36+01:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - a44d7518 by Zubin Duggal at 2025-01-27T02:55:36+01:00 ghcup metadata: still use centos for redhat <9 (cherry picked from commit 660b17ae6a52cbca94e15cb4e1d96f8ef9aa5a54) - - - - - 50e7fc9d by Zubin Duggal at 2025-01-27T02:55:36+01:00 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit 9084fc8824b6ec53c3fabf82b22f2c93933d01ff) - - - - - ef6261f5 by Luite Stegeman at 2025-01-27T02:55:36+01:00 CI: run ghc-in-ghci job through ci.sh to get the correct environment This ensures that CABAL_DIR and HOME are set correctly, fixing a problem where the hackage index state wasn't picked up. - - - - - 72b36c8a by Luite Stegeman at 2025-01-27T02:55:36+01:00 CI: allow both lower and upper bounds for the happy version This fixes CI when newer-than-supported happy is available in the package index. - - - - - 648ed53f by Luite Stegeman at 2025-01-27T02:55:36+01:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. based on commit 9ad346ec8bfa22a2843f8d2c8d998133d0715702 - - - - - d293481a by Zubin Duggal at 2025-01-27T02:55:36+01:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - af3e9b37 by Cheng Shao at 2025-01-27T02:55:36+01:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. (cherry picked from commit 6399d52ba10d510a94c9db6552a4ea8aae8e003b) - - - - - a38a8838 by Luite Stegeman at 2025-01-27T02:55:36+01:00 Update autoconf scripts Scripts taken from autoconf [00b15927496058d23e6258a28d8996f87cf1f191][1]. [1]: https://git.savannah.gnu.org/cgit/config.git/commit/?id=00b15927496058d23e6258a28d8996f87cf1f191 - - - - - 9962117e by Luite Stegeman at 2025-01-27T02:55:36+01:00 add 9.6.7 release notes - - - - - c43b4373 by Luite Stegeman at 2025-01-27T02:55:36+01:00 update CI images - - - - - 9ba693cb by Luite Stegeman at 2025-01-27T02:55:36+01:00 hadrian: don't pass -this-package-name to GHC 9.2 it's not supported - - - - - 4f593930 by Sylvain Henry at 2025-01-27T02:55:36+01:00 JS: fake support for native adjustors (#25159) The JS backend doesn't support adjustors (I believe) and in any case if it ever supports them it will be a native support, not one via libffi. (cherry picked from commit 03055c71446c8f1265de3a6ccb5bc9e09827821e) - - - - - f7c7f0c2 by Matthew Pickering at 2025-01-27T02:55:36+01:00 hadrian: Make sure ffi headers are built before using a compiler When we are using ffi adjustors then we rely on `ffi.h` and `ffitarget.h` files during code generation when compiling stubs. Therefore we need to add this dependency to the build system (which this patch does). Reproducer, configure with `--enable-libffi-adjustors` and then build "_build/stage1/libraries/ghc-prim/build/GHC/Types.p_o". Observe that this fails before this patch and works afterwards. Fixes #24864 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> (cherry picked from commit 0167e472e7035d31591777983d8e35528aceefff) - - - - - 13 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/rel_eng/fetch-gitlab-artifacts/fetch_gitlab.py - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - config.guess - config.sub - docs/users_guide/9.6.6-notes.rst - + docs/users_guide/9.6.7-notes.rst - docs/users_guide/release-notes.rst - hadrian/bootstrap/generate_bootstrap_plans - − hadrian/bootstrap/plan-9_2_1.json - hadrian/bootstrap/plan-9_2_2.json - hadrian/bootstrap/plan-9_2_3.json The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94794c38b62079ee0912b3561fbdbc2e6473ad89...f7c7f0c25d57887493220acf355a9544f56f3f42 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/94794c38b62079ee0912b3561fbdbc2e6473ad89...f7c7f0c25d57887493220acf355a9544f56f3f42 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 27 13:49:09 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Mon, 27 Jan 2025 08:49:09 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] 31 commits: 9.10.2 backport batch 5 - patch notes. Message-ID: <67978ed5acf68_13ae077ad5787308f@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 9278dc6c by Andreas Klebinger at 2025-01-23T11:00:54+01:00 9.10.2 backport batch 5 - patch notes. - - - - - 1f01dde2 by Andreas Klebinger at 2025-01-23T11:17:36+01:00 9.10.2: Bump base to version 4.20.1 - - - - - d96104b8 by Andreas Klebinger at 2025-01-23T11:18:35+01:00 Allow unknown fd device types for setNonBlockingMode. This allows fds with a unknown device type to have blocking mode set. This happens for example for fds from the inotify subsystem. Fixes #25199. (cherry picked from commit 620becd72ec18ca08c1ed86759d65a0e614fe43c) - - - - - f166369b by Sylvain Henry at 2025-01-23T11:18:49+01:00 Fix interaction between fork and kqueue (#24672) A kqueue file descriptor isn't inherited by a child created with fork. As such we mustn't try to close this file descriptor as we would close a random one, e.g. the one used by timerfd. Fix #24672 (cherry picked from commit e7a26d7a6faf1ea534e036c5085a0a027dbb6f5f) - - - - - 9920dc74 by Sylvain Henry at 2025-01-23T11:21:41+01:00 JS: fix h$withCStringOnHeap helper (#25288) strlen returns the length of the string without the \0 terminating byte, hence CString weren't properly allocated on the heap (ending \0 byte was missing). - - - - - 2b4ae28b by Ben Gamari at 2025-01-23T15:13:54+01:00 base: Propagate `error` CallStack to thrown exception Previously `errorCallWithCallStackException` failed to propagate its `CallStack` argument, which represents the call-chain of the preceding `error` call, to the exception that it returned. Consequently, the call-stack of `error` calls were quite useless. Unfortunately, this is the second time that I have fixed this but it seems the first must have been lost in rebasing. Fixes a bug in the implementation of CLC proposal 164 <https://github.com/haskell/core-libraries-committee/issues/164> Fixes #24807. (cherry picked from commit 5f7c20bc6b9deacabb1fb099781f00371cdb4369) - - - - - 6dcd0eb1 by Matthew Pickering at 2025-01-23T15:21:05+01:00 driver: Fix -working-dir for foreign files -working-dir definitely needs more serious testing, there are some easy ways to test this. * Modify Cabal to call ghc using -working-dir rather than changing directory. * Modify the testsuite to run ghc using `-working-dir` rather than running GHC with cwd = temporary directory. However this will have to wait until after 9.12. Fixes #25150 (cherry picked from commit c20d51867c824e32c61bd1e002680bef268e4f51) - - - - - d18ab8f4 by Matthew Pickering at 2025-01-23T15:21:58+01:00 ci: Fix variable inheritence for ghcup-metadata testing job Downstream in ghcup-ci we use the CONFIGURE_ARGS variable to determine how to setup all the different jobs. On the downstream trigger this was being inherited from the default setting in .gitlab.yml file. Therefore this led to job failures as the necessary CONFIGURE_ARGS were not being passed to the configure script when installing the bindist. See docs: * https://docs.gitlab.com/ee/ci/yaml/#inherit * https://docs.gitlab.com/ee/ci/yaml/#triggerforward 1. inherit:variables:fals - This stops the global variables being inherited into the job and hence forwarded onto the downstream job. 2. trigger:forward:* - yaml_variables: true (default) pass yaml variables to downstream, this is important to pass the upstream pipeline id to downstream. - pipeline_variables: false (default) but don't pass pipeline variables (normal environment variables). Fixes #25294 (cherry picked from commit 7cb7172eff9e18ed1c98f65a98018f76c4fcc9f6) - - - - - 8f782afa by Andreas Klebinger at 2025-01-23T15:23:26+01:00 ghc-experimental: Expose primops and ghc extensions via GHC.PrimOps This will be the new place for functions that would have gone into GHC.Exts in the past but are not stable enough to do so now. Addresses #25242 (cherry picked from commit 39497eeda74fc7f1e7ea89292de395b16f69cee2) - - - - - c7e08671 by Andreas Klebinger at 2025-01-23T15:23:43+01:00 Change versionig of ghc-experimental to follow ghc versions. Just like ghc-internal it will now use the @ProjectVersionForLib@ macro for versioning. This means for ghc=9.10.1, ghc-experimental's version will be 9.1001.0 and so on. This fixes #25289 (cherry picked from commit 2293c0b7d709df7be04f596e72c97fd2435c4134) - - - - - d573f907 by Sven Tennie at 2025-01-23T16:15:22+01:00 AArch64: Simplify BL instruction The BL constructor carried unused data in its third argument. (cherry picked from commit eb612fbc8e94d50c9895c02f3d6ee076f61b7773) - - - - - f49d91b0 by Sven Tennie at 2025-01-23T16:16:42+01:00 AArch64: Implement switch/jump tables (#19912) This improves the performance of Cmm switch statements (compared to a chain of if statements.) (cherry picked from commit 1d22611665117131d1c7c3c0287696e8efcc88f2) - - - - - 1073f959 by Andrzej Rybczak at 2025-01-23T16:17:01+01:00 Fix typo in the @since annotation of annotateIO (cherry picked from commit 55609880c3eeda2c13859c10c157d7df05496288) - - - - - 7bf87706 by Cristiano Moraes at 2025-01-23T16:17:14+01:00 configure: Find C++ probing when GCC version is the latest but G++ is old #23118 (cherry picked from commit 78ad81ecef846f73fee0f6c1a86cd6f19aa29b21) - - - - - 13bafa45 by sheaf at 2025-01-27T14:26:16+01:00 LLVM: use sse4.2 instead of sse42 LLVM expects the former instead of the latter since version 3.4. Fixes #25019 (cherry picked from commit 694489edf35c35b29fbdf09a8e3fdc404469858f) - - - - - 376ca25d by sheaf at 2025-01-27T14:26:16+01:00 LLVM: make SSE4.2 imply +popcnt For consistency with the NCG as well as with Clang and GCC, we make the SSE4.2 feature flag imply +popcnt when using the LLVM backend. Fixes #25353 (cherry picked from commit 06ae85071b95376bd1eb354f7cc7901aed45b625) - - - - - 6466acd2 by Ben Gamari at 2025-01-27T14:26:16+01:00 testsuite: Normalise trailing digits from hole fits output The type variables in the holes fit output from `abstract_refinement_hole_fits` is quite sensitive to compiler configuration. Specifically, a slight change in the inlining behavior of `throw` changes type variable naming in `(>>=)` and a few others. Ideally we would make hole fits output more deterministic but in the meantime we simply normalise this difference away as it not relevant to the test's goal. (cherry picked from commit d029f1700effa626ff622700b198ed49ee8b6c19) - - - - - 89ffc037 by Ben Gamari at 2025-01-27T14:26:16+01:00 base: Add test for #25066 (cherry picked from commit da5d7d0d8bde06a1c29612fd17b6a579fc523036) - - - - - f8cd7ade by Ben Gamari at 2025-01-27T14:26:16+01:00 base: Fix #25066 As noted in #25066, the exception backtrace proposal introduced a rather subtle performance regression due to simplification producing Core which the demand analyser concludes may diverge with a precise exception. The nature of the problem is more completely described in the new Note [Hiding precise exception signature in throw]. The (rather hacky) solution we use here hides the problematic optimisation through judicious use of `noinline`. Ultimately however we will want a more principled solution (e.g. #23847). Fixes #255066 CLC proposal: https://github.com/haskell/core-libraries-committee/issues/290 Metric Decrease: T9872d (cherry picked from commit eb7ddae1a2b3fb1be1cd635849516a6398327b29) - - - - - 182057b9 by Ben Gamari at 2025-01-27T14:26:16+01:00 base: Improve documentation of Control.Exception.Backtrace (cherry picked from commit 0060ece762d7a936daf28195676b6162c30dc845) - - - - - c2037780 by Andreas Klebinger at 2025-01-27T14:26:16+01:00 9.10.2 - more changelogs - - - - - b7573e17 by Cheng Shao at 2025-01-27T14:26:16+01:00 Revert "compiler: start deprecating cmmToRawCmmHook" This reverts commit 1c064ef1f3e1aa2afc996e962ad53effa99ec5f4. Turns out the GHC-WPC project does use it to observe Cmm in the pipeline, see #25363. (cherry picked from commit 525d451e175c7d6acfa968ce99d8d3fc7a8af0c7) - - - - - a113a83c by Cheng Shao at 2025-01-27T14:26:16+01:00 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. (cherry picked from commit 5bcfefd5bb73c18a9bad63d1813968832b696f9a) - - - - - dd01dd3e by Zubin Duggal at 2025-01-27T14:26:16+01:00 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit d83f5bd730a8aef37d8a38b3560590d9798f8e45) (cherry picked from commit 280b627869da55a22b4b9a3458e6115b06b5fff4) - - - - - 82916be2 by Zubin Duggal at 2025-01-27T14:26:16+01:00 release: copy zip files into the correct directory Fixes #25446 (cherry picked from commit 346e4cd1903b2cbcc9bb7c39652666c513eb2a59) - - - - - fbae1dc3 by Zubin Duggal at 2025-01-27T14:26:16+01:00 release: Sign .gz bindists too Fixes #25447 (cherry picked from commit bbdbe2254df1bfc9157cfb409afc93f8157712cd) - - - - - 1b0612d4 by Sebastian Graf at 2025-01-27T14:26:16+01:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. (cherry picked from commit 00d58ae18a7ce8db6b2d57261a08ba8c1c2549b5) - - - - - 80742352 by Andreas Klebinger at 2025-01-27T14:26:16+01:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 (cherry picked from commit 7f90f319531c312a074d21688b05f664f0d173fc) - - - - - d8a682a9 by Ben Gamari at 2025-01-27T14:26:16+01:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. (cherry picked from commit a104508d2ea5bbc61c4a756dca42fc043b329709) - - - - - 7bf83cf7 by Ben Gamari at 2025-01-27T14:26:16+01:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. (cherry picked from commit c3fc9b861fd00a85a4fcbd9960b8242d9fabe04b) - - - - - d7d9aa07 by Arnaud Spiwack at 2025-01-27T14:26:17+01:00 Add test for #25428 (cherry picked from commit e6c957e49260230c4cb297aeec16be3293381fb7) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Pipeline/Execute.hs - docs/users_guide/9.10.2-notes.rst - libraries/base/base.cabal - libraries/base/changelog.md - libraries/base/src/Control/Exception/Backtrace.hs - libraries/base/src/Data/Char.hs - libraries/base/src/Data/Semigroup.hs - libraries/base/src/GHC/Exts.hs - libraries/base/src/Prelude.hs - libraries/base/tests/T19288.stderr - + libraries/base/tests/T24807.hs - + libraries/base/tests/T24807.stderr - + libraries/base/tests/T25066.hs - + libraries/base/tests/T25066.stderr - libraries/base/tests/all.T - libraries/ghc-experimental/ghc-experimental.cabal - + libraries/ghc-experimental/src/GHC/PrimOps.hs - libraries/ghc-internal/src/GHC/Internal/Base.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c6e5b18825363b4a89d262de6d41a7844fab188d...d7d9aa07406a69daffeeedca3bb20969ba0b383e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c6e5b18825363b4a89d262de6d41a7844fab188d...d7d9aa07406a69daffeeedca3bb20969ba0b383e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 27 18:39:53 2025 From: gitlab at gitlab.haskell.org (Sven Tennie (@supersven)) Date: Mon, 27 Jan 2025 13:39:53 -0500 Subject: [Git][ghc/ghc][wip/supersven/riscv-vectors] 3 commits: Assert vector register width Message-ID: <6797d2f9c6a19_1b72fd18e76e06538b@gitlab.mail> Sven Tennie pushed to branch wip/supersven/riscv-vectors at Glasgow Haskell Compiler / GHC Commits: e430c7f1 by Sven Tennie at 2025-01-27T18:03:58+01:00 Assert vector register width - - - - - 2162e78f by Sven Tennie at 2025-01-27T18:48:33+01:00 Combine float lit cases - - - - - fa321f9c by Sven Tennie at 2025-01-27T19:39:22+01:00 Tighten Vector Ppr constraints - - - - - 3 changed files: - compiler/GHC/CmmToAsm/RV64/CodeGen.hs - compiler/GHC/CmmToAsm/RV64/Instr.hs - compiler/GHC/CmmToAsm/RV64/Ppr.hs Changes: ===================================== compiler/GHC/CmmToAsm/RV64/CodeGen.hs ===================================== @@ -471,8 +471,27 @@ litToImm' = OpImm . litToImm getRegister :: CmmExpr -> NatM Register getRegister e = do config <- getConfig + assertVectorRegWidth e getRegister' config (ncgPlatform config) e +assertVectorRegWidth :: CmmExpr -> NatM () +assertVectorRegWidth expr = do + config <- getConfig + let platform = ncgPlatform config + mbRegMinBits :: Maybe Int = fromIntegral <$> ncgVectorMinBits config + format = cmmTypeFormat $ cmmExprType platform expr + if isVecFormat format then + case mbRegMinBits of + Nothing -> pprPanic + "CmmExpr results in vector format, but no vector register configured (see -mvector-min-width-bits in docs)" + (pdoc platform expr) + Just regMinBits | (formatInBytes format) * 8 <= regMinBits -> pure () + | otherwise -> pprPanic + "CmmExpr results in vector format which is bigger than the configured vector register size (see -mvector-min-width-bits in docs)" + (pdoc platform expr) + else + pure () + -- | The register width to be used for an operation on the given width -- operand. opRegWidth :: Width -> Width @@ -581,29 +600,17 @@ getRegister' config plat expr = let op = litToImm' lit format = floatFormat w pure $ Any format (\dst -> unitOL $ annExpr expr (MOV (OpReg format dst) op)) - CmmFloat _f W8 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for bytes" (pdoc plat expr) - CmmFloat _f W16 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for halfs" (pdoc plat expr) - CmmFloat f W32 -> do - -- TODO: Besides width, much duplication with the W64 case! - let word = castFloatToWord32 (fromRational f) :: Word32 - format_int = intFormat W32 - format_dst = floatFormat W32 - intReg <- getNewRegNat format_int - return - ( Any - format_dst - ( \dst -> - toOL - [ annExpr expr - $ MOV (OpReg format_int intReg) (OpImm (ImmInteger (fromIntegral word))), - MOV (OpReg format_dst dst) (OpReg format_int intReg) - ] - ) - ) - CmmFloat f W64 -> do - let word = castDoubleToWord64 (fromRational f) :: Word64 - format_int = intFormat W64 - format_dst = floatFormat W64 + CmmFloat f w -> do + let + toWord :: Rational -> Integer + toWord r = case w of + W8 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for bytes" (pdoc plat expr) + W16 -> pprPanic "getRegister' (CmmLit:CmmFloat), no support for halfs" (pdoc plat expr) + W32 -> fromIntegral $ castFloatToWord32 (fromRational r) + W64 -> fromIntegral $ castDoubleToWord64 (fromRational r) + w -> pprPanic ("getRegister' (CmmLit:CmmFloat), no support for width " ++ show w) (pdoc plat expr) + format_int = intFormat w + format_dst = floatFormat w intReg <- getNewRegNat format_int return ( Any @@ -611,12 +618,11 @@ getRegister' config plat expr = ( \dst -> toOL [ annExpr expr - $ MOV (OpReg format_int intReg) (OpImm (ImmInteger (fromIntegral word))), + $ MOV (OpReg format_int intReg) (OpImm (ImmInteger (toWord f))), MOV (OpReg format_dst dst) (OpReg format_int intReg) ] ) ) - CmmFloat _f _w -> pprPanic "getRegister' (CmmLit:CmmFloat), unsupported float lit" (pdoc plat expr) CmmVec lits | VecFormat l sFmt <- cmmTypeFormat $ cmmLitType plat lit, (f : fs) <- lits, ===================================== compiler/GHC/CmmToAsm/RV64/Instr.hs ===================================== @@ -983,3 +983,6 @@ isVectorReg :: Reg -> Bool isVectorReg (RegReal (RealRegSingle i)) | isVectorRegNo i = True isVectorReg (RegVirtual (VirtualRegD _)) = True isVectorReg _ = False + +allVectorRegOps :: [Operand] -> Bool +allVectorRegOps = all isVectorRegOp ===================================== compiler/GHC/CmmToAsm/RV64/Ppr.hs ===================================== @@ -315,6 +315,9 @@ negOp (OpImm (ImmInt i)) = OpImm (ImmInt (negate i)) negOp (OpImm (ImmInteger i)) = OpImm (ImmInteger (negate i)) negOp op = pprPanic "RV64.negOp" (text $ show op) +pprOps :: (IsLine doc) => Platform -> [Operand] -> doc +pprOps platform = hsep . map (pprOp platform) + -- | Pretty print an operand pprOp :: (IsLine doc) => Platform -> Operand -> doc pprOp plat op = case op of @@ -753,16 +756,12 @@ pprInstr platform instr = case instr of VMV o1 _o2 -> pprPanic "RV64.pprInstr - VMV can only target registers." (pprOp platform o1) VID op@(OpReg fmt _reg) -> configVec fmt $$ op1 (text "\tvid.v") op VID op -> pprPanic "RV64.pprInstr - VID can only target registers." (pprOp platform op) - -- TODO: This expects int register as third operand: Generalize by calculating - -- the instruction suffix (".vx") - VMSEQ o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvmseq.vx") o1 o2 o3 - VMSEQ o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VMSEQ can only target registers." (pprOp platform o1) - -- TODO: All operands need to be vector registers. Make this more general or - -- validate this constraint. - VMERGE o1@(OpReg fmt _reg) o2 o3 o4 -> configVec fmt $$ op4 (text "\tvmerge.vvm") o1 o2 o3 o4 - VMERGE o1 _o2 _o3 _o4 -> pprPanic "RV64.pprInstr - VMERGE can only target registers." (pprOp platform o1) - VSLIDEDOWN o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvslidedown.vx") o1 o2 o3 - VSLIDEDOWN o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VSLIDEDOWN can only target registers." (pprOp platform o1) + VMSEQ o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2] && isIntOp o3 -> configVec fmt $$ op3 (text "\tvmseq.vx") o1 o2 o3 + VMSEQ o1 o2 o3 -> pprPanic "RV64.pprInstr - VMSEQ wrong operands." (pprOps platform [o1, o2, o3]) + VMERGE o1@(OpReg fmt _reg) o2 o3 o4 | allVectorRegOps [o1, o2, o3, o4] -> configVec fmt $$ op4 (text "\tvmerge.vvm") o1 o2 o3 o4 + VMERGE o1 o2 o3 o4 -> pprPanic "RV64.pprInstr - VMERGE wrong operands." (pprOps platform [o1, o2, o3, o4]) + VSLIDEDOWN o1@(OpReg fmt _reg) o2 o3 |allVectorRegOps [o1, o2] && isIntOp o3-> configVec fmt $$ op3 (text "\tvslidedown.vx") o1 o2 o3 + VSLIDEDOWN o1 o2 o3 -> pprPanic "RV64.pprInstr - VSLIDEDOWN wrong operands." (pprOps platform [o1, o2, o3]) -- TODO: adjust VSETIVLI to contain only format? VSETIVLI (OpReg fmt dst) len width grouping ta ma -> line @@ -778,29 +777,29 @@ pprInstr platform instr = case instr of <+> pprTA ta <> comma <+> pprMasking ma - VSETIVLI o1 _ _ _ _ _ -> pprPanic "RV64.pprInstr - VSETIVLI can only target registers." (pprOp platform o1) - VNEG o1@(OpReg fmt _reg) o2 -> configVec fmt $$ op2 (text "\tvfneg.v") o1 o2 - VNEG o1 _o2 -> pprPanic "RV64.pprInstr - VNEG can only target registers." (pprOp platform o1) - VADD o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfadd.vv") o1 o2 o3 - VADD o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VADD can only target registers." (pprOp platform o1) - VSUB o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfsub.vv") o1 o2 o3 - VSUB o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VSUB can only target registers." (pprOp platform o1) - VMUL o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfmul.vv") o1 o2 o3 - VMUL o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VMUL can only target registers." (pprOp platform o1) - VQUOT o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfdiv.vv") o1 o2 o3 - VQUOT o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VQUOT can only target registers." (pprOp platform o1) - VSMIN o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvmin.vv") o1 o2 o3 - VSMIN o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VSMIN can only target registers." (pprOp platform o1) - VSMAX o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvmax.vv") o1 o2 o3 - VSMAX o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VSMAX can only target registers." (pprOp platform o1) - VUMIN o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvminu.vv") o1 o2 o3 - VUMIN o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VUMIN can only target registers." (pprOp platform o1) - VUMAX o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvmaxu.vv") o1 o2 o3 - VUMAX o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VUMAX can only target registers." (pprOp platform o1) - VFMIN o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfmin.vv") o1 o2 o3 - VFMIN o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VFMIN can only target registers." (pprOp platform o1) - VFMAX o1@(OpReg fmt _reg) o2 o3 -> configVec fmt $$ op3 (text "\tvfmax.vv") o1 o2 o3 - VFMAX o1 _o2 _o3 -> pprPanic "RV64.pprInstr - VFMAX can only target registers." (pprOp platform o1) + VSETIVLI o1 _ _ _ _ _ -> pprPanic "RV64.pprInstr - VSETIVLI wrong operands." (pprOp platform o1) + VNEG o1@(OpReg fmt _reg) o2 | allVectorRegOps [o1, o2] -> configVec fmt $$ op2 (text "\tvfneg.v") o1 o2 + VNEG o1 o2 -> pprPanic "RV64.pprInstr - VNEG wrong operands." (pprOps platform [o1, o2]) + VADD o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvfadd.vv") o1 o2 o3 + VADD o1 o2 o3 -> pprPanic "RV64.pprInstr - VADD wrong operands." (pprOps platform [o1, o2, o3]) + VSUB o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvfsub.vv") o1 o2 o3 + VSUB o1 o2 o3 -> pprPanic "RV64.pprInstr - VSUB wrong operands." (pprOps platform [o1, o2, o3]) + VMUL o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvfmul.vv") o1 o2 o3 + VMUL o1 o2 o3 -> pprPanic "RV64.pprInstr - VMUL wrong operands." (pprOps platform [o1, o2, o3]) + VQUOT o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvfdiv.vv") o1 o2 o3 + VQUOT o1 o2 o3 -> pprPanic "RV64.pprInstr - VQUOT wrong operands." (pprOps platform [o1, o2, o3]) + VSMIN o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvmin.vv") o1 o2 o3 + VSMIN o1 o2 o3 -> pprPanic "RV64.pprInstr - VSMIN wrong operands." (pprOps platform [o1, o2, o3]) + VSMAX o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvmax.vv") o1 o2 o3 + VSMAX o1 o2 o3 -> pprPanic "RV64.pprInstr - VSMAX wrong operands." (pprOps platform [o1, o2, o3]) + VUMIN o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvminu.vv") o1 o2 o3 + VUMIN o1 o2 o3 -> pprPanic "RV64.pprInstr - VUMIN wrong operands." (pprOps platform [o1, o2, o3]) + VUMAX o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvmaxu.vv") o1 o2 o3 + VUMAX o1 o2 o3 -> pprPanic "RV64.pprInstr - VUMAX wrong operands." (pprOps platform [o1, o2, o3]) + VFMIN o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvfmin.vv") o1 o2 o3 + VFMIN o1 o2 o3 -> pprPanic "RV64.pprInstr - VFMIN wrong operands." (pprOps platform [o1, o2, o3]) + VFMAX o1@(OpReg fmt _reg) o2 o3 | allVectorRegOps [o1, o2, o3] -> configVec fmt $$ op3 (text "\tvfmax.vv") o1 o2 o3 + VFMAX o1 o2 o3 -> pprPanic "RV64.pprInstr - VFMAX wrong operands." (pprOps platform [o1, o2, o3]) instr -> panic $ "RV64.pprInstr - Unknown instruction: " ++ instrCon instr where op1 op o1 = line $ op <+> pprOp platform o1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/715a80b12d5479512c9bd0130c8070c28b65f1cb...fa321f9c00874feb7900690feb90cf991c4e5c63 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/715a80b12d5479512c9bd0130c8070c28b65f1cb...fa321f9c00874feb7900690feb90cf991c4e5c63 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 27 19:02:34 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 27 Jan 2025 14:02:34 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: x86 NCG: Make MOVD's output format explicit Message-ID: <6797d84a929ea_1b72fd1ce8640688f3@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 8c6730b3 by ARATA Mizuki at 2025-01-27T14:02:18-05:00 x86 NCG: Make MOVD's output format explicit The old design led to inference of a wrong format, losing upper bits of a vector register. Fixes #25659 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 8ec0a4dd by Simon Hengel at 2025-01-27T14:02:20-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - 8 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - docs/users_guide/diagnostics-as-json-schema-1_0.json - docs/users_guide/diagnostics-as-json-schema-1_1.json - + testsuite/tests/simd/should_run/T25659.hs - + testsuite/tests/simd/should_run/T25659.stdout - testsuite/tests/simd/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1171,7 +1171,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps bitcast :: Format -> Format -> CmmExpr -> NatM Register bitcast fmt rfmt expr = do (src, e_code) <- getSomeReg expr - let code = \dst -> e_code `snocOL` (MOVD fmt (OpReg src) (OpReg dst)) + let code = \dst -> e_code `snocOL` (MOVD fmt rfmt (OpReg src) (OpReg dst)) return (Any rfmt code) toI8Reg :: Width -> CmmExpr -> NatM Register @@ -1262,7 +1262,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps code dst = exp `snocOL` -- VPBROADCAST from GPR requires AVX-512, -- so we use an additional MOVD. - (MOVD movFormat (OpReg reg) (OpReg dst)) `snocOL` + (MOVD movFormat fmt (OpReg reg) (OpReg dst)) `snocOL` (VPBROADCAST fmt fmt (OpReg dst) dst) return $ Any fmt code @@ -1272,7 +1272,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 16 FmtInt8 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLBW fmt (OpReg dst) dst) `snocOL` (PUNPCKLWD (VecFormat 8 FmtInt16) (OpReg dst) dst) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) @@ -1284,7 +1284,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 8 FmtInt16 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLWD fmt (OpReg dst) dst) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) ) @@ -1295,7 +1295,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 4 FmtInt32 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) ) @@ -1305,7 +1305,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 2 FmtInt64 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II64 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLQDQ fmt (OpReg dst) dst) ) @@ -1793,16 +1793,16 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case i of 0 -> exp `snocOL` - (MOVD FF32 (OpReg r) (OpReg dst)) + (MOVD fmt II32 (OpReg r) (OpReg dst)) 1 -> exp `snocOL` (PSHUFD fmt (ImmInt 0b01_01_01_01) (OpReg r) tmp) `snocOL` -- tmp <- (r[1],r[1],r[1],r[1]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) 2 -> exp `snocOL` (PSHUFD fmt (ImmInt 0b11_10_11_10) (OpReg r) tmp) `snocOL` -- tmp <- (r[2],r[3],r[2],r[3]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) _ -> exp `snocOL` (PSHUFD fmt (ImmInt 0b11_11_11_11) (OpReg r) tmp) `snocOL` -- tmp <- (r[3],r[3],r[3],r[3]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) return (Any II32 code) vector_int32x4_extract_sse2 _ offset = pprPanic "Unsupported offset" (pdoc platform offset) @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD FF64 (OpReg r) (OpReg dst)) + (MOVD fmt II64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD FF64 (OpReg tmp) (OpReg dst)) + (MOVD fmt II64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset @@ -2103,22 +2103,22 @@ getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps = case offset of 0 -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` (MOV floatVectorFormat (OpReg tmp1) (OpReg dst)) -- MOVSS; dst <- (tmp1[0],dst[1],dst[2],dst[3]) 1 -> valExp `appOL` (vecCode tmp1) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0) (PUNPCKLQDQ vectorFormat (OpReg tmp1) dst) `snocOL` -- dst <- (dst[0],dst[1],tmp1[0],tmp1[1]) (SHUF floatVectorFormat (ImmInt 0b11_10_00_10) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[2],dst[0],tmp1[2],tmp1[3]) 2 -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) (MOVU floatVectorFormat (OpReg dst) (OpReg tmp2)) `snocOL` -- MOVUPS; tmp2 <- dst (SHUF floatVectorFormat (ImmInt 0b01_00_01_11) (OpReg tmp1) tmp2) `snocOL` -- SHUFPS; tmp2 <- (tmp2[3],tmp2[1],tmp1[0],tmp1[1]) (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp2) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp2[2],tmp2[0]) _ -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) (SHUF floatVectorFormat (ImmInt 0b11_10_01_00) (OpReg dst) tmp1) `snocOL` -- SHUFPS; tmp1 <- (tmp1[0],tmp1[1],dst[2],dst[3]) (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp1[2],tmp1[0]) return $ Any vectorFormat code @@ -2139,12 +2139,12 @@ getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps CmmInt 0 _ -> valExp `appOL` vecExp `snocOL` (MOVHLPS fmt vecReg tmp) `snocOL` - (MOVD II64 (OpReg valReg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg valReg) (OpReg dst)) `snocOL` (PUNPCKLQDQ fmt (OpReg tmp) dst) CmmInt 1 _ -> valExp `appOL` vecExp `snocOL` - (MOV II64 (OpReg vecReg) (OpReg dst)) `snocOL` - (MOVD II64 (OpReg valReg) (OpReg tmp)) `snocOL` + (MOVDQU fmt (OpReg vecReg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg valReg) (OpReg tmp)) `snocOL` (PUNPCKLQDQ fmt (OpReg tmp) dst) _ -> pprPanic "MO_V_Insert Int64X2: unsupported offset" (ppr offset) in return $ Any fmt code @@ -4083,7 +4083,7 @@ loadArgsWin config (arg:rest) = do -- arguments in both fp and integer registers. let (assign_code', regs') | isFloatFormat arg_fmt = - ( assign_code `snocOL` MOVD FF64 (OpReg freg) (OpReg ireg), + ( assign_code `snocOL` MOVD FF64 II64 (OpReg freg) (OpReg ireg), [ RegWithFormat freg FF64 , RegWithFormat ireg II64 ]) | otherwise = (assign_code, [RegWithFormat ireg II64]) ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -39,7 +39,6 @@ module GHC.CmmToAsm.X86.Instr , patchJumpInstr , isMetaInstr , isJumpishInstr - , movdOutFormat , MinOrMax(..), MinMaxType(..) ) where @@ -127,11 +126,16 @@ data Instr -- with @MOVABS@; we currently do not use this instruction in GHC. -- See https://stackoverflow.com/questions/52434073/whats-the-difference-between-the-x86-64-att-instructions-movq-and-movabsq. - | MOVD Format Operand Operand -- ^ MOVD/MOVQ SSE2 instructions - -- (bitcast between a general purpose - -- register and a float register). - -- Format is input format, output format is - -- calculated in the 'movdOutFormat' function. + -- | MOVD/MOVQ SSE2 instructions + -- (bitcast between a general purpose register and a float register). + | MOVD + Format -- ^ input format + Format -- ^ output format + Operand Operand + -- NB: MOVD stores both the input and output formats. This is because + -- neither format fully determines the other, as either might be + -- a vector format, and we need to know the exact format in order to + -- correctly spill/unspill. See #25659. | CMOV Cond Format Operand Reg | MOVZxL Format Operand Operand -- ^ The format argument is the size of operand 1 (the number of bits we keep) @@ -377,10 +381,10 @@ regUsageOfInstr platform instr -- (largely to avoid partial register stalls) | otherwise -> usageRW fmt src dst - MOVD fmt src dst -> + MOVD fmt1 fmt2 src dst -> -- NB: MOVD and MOVQ always zero any remaining upper part of destination, -- so the destination is "written" not "modified". - usageRW' fmt (movdOutFormat fmt) src dst + usageRW' fmt1 fmt2 src dst CMOV _ fmt src dst -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst] MOVZxL fmt src dst -> usageRW fmt src dst MOVSxL fmt src dst -> usageRW fmt src dst @@ -650,14 +654,6 @@ interesting :: Platform -> Reg -> Bool interesting _ (RegVirtual _) = True interesting platform (RegReal (RealRegSingle i)) = freeReg platform i -movdOutFormat :: Format -> Format -movdOutFormat format = case format of - II32 -> FF32 - II64 -> FF64 - FF32 -> II32 - FF64 -> II64 - _ -> pprPanic "X86: improper format for movd/movq" (ppr format) - -- | Applies the supplied function to all registers in instructions. -- Typically used to change virtual registers to real registers. @@ -665,7 +661,7 @@ patchRegsOfInstr :: HasDebugCallStack => Platform -> Instr -> (Reg -> Reg) -> In patchRegsOfInstr platform instr env = case instr of MOV fmt src dst -> MOV fmt (patchOp src) (patchOp dst) - MOVD fmt src dst -> patch2 (MOVD fmt) src dst + MOVD fmt1 fmt2 src dst -> patch2 (MOVD fmt1 fmt2) src dst CMOV cc fmt src dst -> CMOV cc fmt (patchOp src) (env dst) MOVZxL fmt src dst -> patch2 (MOVZxL fmt) src dst MOVSxL fmt src dst -> patch2 (MOVSxL fmt) src dst ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -657,8 +657,8 @@ pprInstr platform i = case i of CMOV cc format src dst -> pprCondOpReg (text "cmov") format cc src dst - MOVD format src dst - -> pprMovdOpOp (text "mov") format src dst + MOVD format1 format2 src dst + -> pprMovdOpOp (text "mov") format1 format2 src dst MOVZxL II32 src dst -> pprFormatOpOp (text "mov") II32 src dst @@ -1151,21 +1151,21 @@ pprInstr platform i = case i of pprOperand platform format op2 ] - pprMovdOpOp :: Line doc -> Format -> Operand -> Operand -> doc - pprMovdOpOp name format op1 op2 - = let instr = case format of + pprMovdOpOp :: Line doc -> Format -> Format -> Operand -> Operand -> doc + pprMovdOpOp name format1 format2 op1 op2 + = let instr = case (format1, format2) of -- bitcasts to/from a general purpose register to a floating point -- register require II32 or II64. - II32 -> text "d" - II64 -> text "q" - FF32 -> text "d" - FF64 -> text "q" - _ -> panic "X86.Ppr.pprMovdOpOp: improper format for movd/movq." + (II32, _) -> text "d" + (II64, _) -> text "q" + (_, II32) -> text "d" + (_, II64) -> text "q" + _ -> panic "X86.Ppr.pprMovdOpOp: improper format for movd/movq." in line $ hcat [ char '\t' <> name <> instr <> space, - pprOperand platform format op1, + pprOperand platform format1 op1, comma, - pprOperand platform (movdOutFormat format) op2 + pprOperand platform format2 op2 ] pprFormatImmRegOp :: Line doc -> Format -> Imm -> Reg -> Operand -> doc ===================================== docs/users_guide/diagnostics-as-json-schema-1_0.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", ===================================== docs/users_guide/diagnostics-as-json-schema-1_1.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", ===================================== testsuite/tests/simd/should_run/T25659.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\_ b -> b) ===================================== testsuite/tests/simd/should_run/T25659.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (22,33) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -26,6 +26,7 @@ test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation +test('T25659', [], compile_and_run, ['']) # Ensure we set the CPU features we have available. # View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4ae7528886c02745dc7a1f95f7db20a753167cab...8ec0a4dd5c4a39cc55d4013892123c93075f9590 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4ae7528886c02745dc7a1f95f7db20a753167cab...8ec0a4dd5c4a39cc55d4013892123c93075f9590 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 27 21:22:51 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 27 Jan 2025 16:22:51 -0500 Subject: [Git][ghc/ghc][master] Fix for alex-3.5.2.0 (#25623) Message-ID: <6797f92bcdd1b_21f57f1380a44244d4@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a1d92378 by Brandon Chinn at 2025-01-25T15:11:54-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 1 changed file: - compiler/GHC/Parser/Lexer.x Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3366,11 +3367,15 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#ifdef MIN_TOOL_VERSION_alex +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. -- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} +#endif +#endif lexToken :: P (PsLocated Token) lexToken = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1d923786baed5b001c523fd2a76f133be510b04 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a1d923786baed5b001c523fd2a76f133be510b04 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 27 21:23:41 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 27 Jan 2025 16:23:41 -0500 Subject: [Git][ghc/ghc][master] x86 NCG: Make MOVD's output format explicit Message-ID: <6797f95d4977e_21f57f13f107829316@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 62760367 by ARATA Mizuki at 2025-01-27T16:23:06-05:00 x86 NCG: Make MOVD's output format explicit The old design led to inference of a wrong format, losing upper bits of a vector register. Fixes #25659 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - 6 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - + testsuite/tests/simd/should_run/T25659.hs - + testsuite/tests/simd/should_run/T25659.stdout - testsuite/tests/simd/should_run/all.T Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1171,7 +1171,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps bitcast :: Format -> Format -> CmmExpr -> NatM Register bitcast fmt rfmt expr = do (src, e_code) <- getSomeReg expr - let code = \dst -> e_code `snocOL` (MOVD fmt (OpReg src) (OpReg dst)) + let code = \dst -> e_code `snocOL` (MOVD fmt rfmt (OpReg src) (OpReg dst)) return (Any rfmt code) toI8Reg :: Width -> CmmExpr -> NatM Register @@ -1262,7 +1262,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps code dst = exp `snocOL` -- VPBROADCAST from GPR requires AVX-512, -- so we use an additional MOVD. - (MOVD movFormat (OpReg reg) (OpReg dst)) `snocOL` + (MOVD movFormat fmt (OpReg reg) (OpReg dst)) `snocOL` (VPBROADCAST fmt fmt (OpReg dst) dst) return $ Any fmt code @@ -1272,7 +1272,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 16 FmtInt8 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLBW fmt (OpReg dst) dst) `snocOL` (PUNPCKLWD (VecFormat 8 FmtInt16) (OpReg dst) dst) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) @@ -1284,7 +1284,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 8 FmtInt16 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLWD fmt (OpReg dst) dst) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) ) @@ -1295,7 +1295,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 4 FmtInt32 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) ) @@ -1305,7 +1305,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 2 FmtInt64 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II64 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLQDQ fmt (OpReg dst) dst) ) @@ -1793,16 +1793,16 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case i of 0 -> exp `snocOL` - (MOVD FF32 (OpReg r) (OpReg dst)) + (MOVD fmt II32 (OpReg r) (OpReg dst)) 1 -> exp `snocOL` (PSHUFD fmt (ImmInt 0b01_01_01_01) (OpReg r) tmp) `snocOL` -- tmp <- (r[1],r[1],r[1],r[1]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) 2 -> exp `snocOL` (PSHUFD fmt (ImmInt 0b11_10_11_10) (OpReg r) tmp) `snocOL` -- tmp <- (r[2],r[3],r[2],r[3]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) _ -> exp `snocOL` (PSHUFD fmt (ImmInt 0b11_11_11_11) (OpReg r) tmp) `snocOL` -- tmp <- (r[3],r[3],r[3],r[3]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) return (Any II32 code) vector_int32x4_extract_sse2 _ offset = pprPanic "Unsupported offset" (pdoc platform offset) @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD FF64 (OpReg r) (OpReg dst)) + (MOVD fmt II64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD FF64 (OpReg tmp) (OpReg dst)) + (MOVD fmt II64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset @@ -2103,22 +2103,22 @@ getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps = case offset of 0 -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` (MOV floatVectorFormat (OpReg tmp1) (OpReg dst)) -- MOVSS; dst <- (tmp1[0],dst[1],dst[2],dst[3]) 1 -> valExp `appOL` (vecCode tmp1) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0) (PUNPCKLQDQ vectorFormat (OpReg tmp1) dst) `snocOL` -- dst <- (dst[0],dst[1],tmp1[0],tmp1[1]) (SHUF floatVectorFormat (ImmInt 0b11_10_00_10) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[2],dst[0],tmp1[2],tmp1[3]) 2 -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) (MOVU floatVectorFormat (OpReg dst) (OpReg tmp2)) `snocOL` -- MOVUPS; tmp2 <- dst (SHUF floatVectorFormat (ImmInt 0b01_00_01_11) (OpReg tmp1) tmp2) `snocOL` -- SHUFPS; tmp2 <- (tmp2[3],tmp2[1],tmp1[0],tmp1[1]) (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp2) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp2[2],tmp2[0]) _ -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) (SHUF floatVectorFormat (ImmInt 0b11_10_01_00) (OpReg dst) tmp1) `snocOL` -- SHUFPS; tmp1 <- (tmp1[0],tmp1[1],dst[2],dst[3]) (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp1[2],tmp1[0]) return $ Any vectorFormat code @@ -2139,12 +2139,12 @@ getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps CmmInt 0 _ -> valExp `appOL` vecExp `snocOL` (MOVHLPS fmt vecReg tmp) `snocOL` - (MOVD II64 (OpReg valReg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg valReg) (OpReg dst)) `snocOL` (PUNPCKLQDQ fmt (OpReg tmp) dst) CmmInt 1 _ -> valExp `appOL` vecExp `snocOL` - (MOV II64 (OpReg vecReg) (OpReg dst)) `snocOL` - (MOVD II64 (OpReg valReg) (OpReg tmp)) `snocOL` + (MOVDQU fmt (OpReg vecReg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg valReg) (OpReg tmp)) `snocOL` (PUNPCKLQDQ fmt (OpReg tmp) dst) _ -> pprPanic "MO_V_Insert Int64X2: unsupported offset" (ppr offset) in return $ Any fmt code @@ -4083,7 +4083,7 @@ loadArgsWin config (arg:rest) = do -- arguments in both fp and integer registers. let (assign_code', regs') | isFloatFormat arg_fmt = - ( assign_code `snocOL` MOVD FF64 (OpReg freg) (OpReg ireg), + ( assign_code `snocOL` MOVD FF64 II64 (OpReg freg) (OpReg ireg), [ RegWithFormat freg FF64 , RegWithFormat ireg II64 ]) | otherwise = (assign_code, [RegWithFormat ireg II64]) ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -39,7 +39,6 @@ module GHC.CmmToAsm.X86.Instr , patchJumpInstr , isMetaInstr , isJumpishInstr - , movdOutFormat , MinOrMax(..), MinMaxType(..) ) where @@ -127,11 +126,16 @@ data Instr -- with @MOVABS@; we currently do not use this instruction in GHC. -- See https://stackoverflow.com/questions/52434073/whats-the-difference-between-the-x86-64-att-instructions-movq-and-movabsq. - | MOVD Format Operand Operand -- ^ MOVD/MOVQ SSE2 instructions - -- (bitcast between a general purpose - -- register and a float register). - -- Format is input format, output format is - -- calculated in the 'movdOutFormat' function. + -- | MOVD/MOVQ SSE2 instructions + -- (bitcast between a general purpose register and a float register). + | MOVD + Format -- ^ input format + Format -- ^ output format + Operand Operand + -- NB: MOVD stores both the input and output formats. This is because + -- neither format fully determines the other, as either might be + -- a vector format, and we need to know the exact format in order to + -- correctly spill/unspill. See #25659. | CMOV Cond Format Operand Reg | MOVZxL Format Operand Operand -- ^ The format argument is the size of operand 1 (the number of bits we keep) @@ -377,10 +381,10 @@ regUsageOfInstr platform instr -- (largely to avoid partial register stalls) | otherwise -> usageRW fmt src dst - MOVD fmt src dst -> + MOVD fmt1 fmt2 src dst -> -- NB: MOVD and MOVQ always zero any remaining upper part of destination, -- so the destination is "written" not "modified". - usageRW' fmt (movdOutFormat fmt) src dst + usageRW' fmt1 fmt2 src dst CMOV _ fmt src dst -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst] MOVZxL fmt src dst -> usageRW fmt src dst MOVSxL fmt src dst -> usageRW fmt src dst @@ -650,14 +654,6 @@ interesting :: Platform -> Reg -> Bool interesting _ (RegVirtual _) = True interesting platform (RegReal (RealRegSingle i)) = freeReg platform i -movdOutFormat :: Format -> Format -movdOutFormat format = case format of - II32 -> FF32 - II64 -> FF64 - FF32 -> II32 - FF64 -> II64 - _ -> pprPanic "X86: improper format for movd/movq" (ppr format) - -- | Applies the supplied function to all registers in instructions. -- Typically used to change virtual registers to real registers. @@ -665,7 +661,7 @@ patchRegsOfInstr :: HasDebugCallStack => Platform -> Instr -> (Reg -> Reg) -> In patchRegsOfInstr platform instr env = case instr of MOV fmt src dst -> MOV fmt (patchOp src) (patchOp dst) - MOVD fmt src dst -> patch2 (MOVD fmt) src dst + MOVD fmt1 fmt2 src dst -> patch2 (MOVD fmt1 fmt2) src dst CMOV cc fmt src dst -> CMOV cc fmt (patchOp src) (env dst) MOVZxL fmt src dst -> patch2 (MOVZxL fmt) src dst MOVSxL fmt src dst -> patch2 (MOVSxL fmt) src dst ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -657,8 +657,8 @@ pprInstr platform i = case i of CMOV cc format src dst -> pprCondOpReg (text "cmov") format cc src dst - MOVD format src dst - -> pprMovdOpOp (text "mov") format src dst + MOVD format1 format2 src dst + -> pprMovdOpOp (text "mov") format1 format2 src dst MOVZxL II32 src dst -> pprFormatOpOp (text "mov") II32 src dst @@ -1151,21 +1151,21 @@ pprInstr platform i = case i of pprOperand platform format op2 ] - pprMovdOpOp :: Line doc -> Format -> Operand -> Operand -> doc - pprMovdOpOp name format op1 op2 - = let instr = case format of + pprMovdOpOp :: Line doc -> Format -> Format -> Operand -> Operand -> doc + pprMovdOpOp name format1 format2 op1 op2 + = let instr = case (format1, format2) of -- bitcasts to/from a general purpose register to a floating point -- register require II32 or II64. - II32 -> text "d" - II64 -> text "q" - FF32 -> text "d" - FF64 -> text "q" - _ -> panic "X86.Ppr.pprMovdOpOp: improper format for movd/movq." + (II32, _) -> text "d" + (II64, _) -> text "q" + (_, II32) -> text "d" + (_, II64) -> text "q" + _ -> panic "X86.Ppr.pprMovdOpOp: improper format for movd/movq." in line $ hcat [ char '\t' <> name <> instr <> space, - pprOperand platform format op1, + pprOperand platform format1 op1, comma, - pprOperand platform (movdOutFormat format) op2 + pprOperand platform format2 op2 ] pprFormatImmRegOp :: Line doc -> Format -> Imm -> Reg -> Operand -> doc ===================================== testsuite/tests/simd/should_run/T25659.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\_ b -> b) ===================================== testsuite/tests/simd/should_run/T25659.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (22,33) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -26,6 +26,7 @@ test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation +test('T25659', [], compile_and_run, ['']) # Ensure we set the CPU features we have available. # View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/62760367dca36da5828875c5423109f9a5523337 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/62760367dca36da5828875c5423109f9a5523337 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 27 21:24:24 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Mon, 27 Jan 2025 16:24:24 -0500 Subject: [Git][ghc/ghc][master] doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) Message-ID: <6797f9886e8b6_21f57f162b6543344c@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f19ab490 by Simon Hengel at 2025-01-27T16:23:45-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - 2 changed files: - docs/users_guide/diagnostics-as-json-schema-1_0.json - docs/users_guide/diagnostics-as-json-schema-1_1.json Changes: ===================================== docs/users_guide/diagnostics-as-json-schema-1_0.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", ===================================== docs/users_guide/diagnostics-as-json-schema-1_1.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f19ab49091675faba8619428a780e706ed3314fc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f19ab49091675faba8619428a780e706ed3314fc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon Jan 27 21:41:57 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Mon, 27 Jan 2025 16:41:57 -0500 Subject: [Git][ghc/ghc][wip/fix-912-bootstrap] 32 commits: Remove SDocs from ErrCtxt & ErrInfo Message-ID: <6797fda536a15_21f57f1c3e9d839720@gitlab.mail> Cheng Shao pushed to branch wip/fix-912-bootstrap at Glasgow Haskell Compiler / GHC Commits: 2e7bf446 by sheaf at 2025-01-13T10:55:26+01:00 Remove SDocs from ErrCtxt & ErrInfo This commit: - turns the SDoc used in ErrCtxt into a proper error datatype, ErrCtxtMsg, which contains all the different error contexts that can be added, - replaces ErrInfo with [ErrCtxt]. ErrInfo used to contain two SDocs; the first is replaced with [ErrCtxt], and the second is removed, with the relevant information being put in the appropriate error message constructors. Fixes #23436 - - - - - 2d62b970 by Mike Pilgrem at 2025-01-13T12:59:10-05:00 Re CLC #300 - Specify fmap for NonEmpty as map See: * https://github.com/haskell/core-libraries-committee/issues/300 Seeks to: * move existing instances for NonEmpty (except of Eq and Ord) out of GHC.Internal.Base into new GHC.Internal.Data.NonEmpty (to avoid otherwise unavoidable cycles in the module graph); * move map out of Data.List.NonEmpty (base package) into GHC.Internal.Data.NonEmpty; * define fmap as map for NonEmpty instance of Functor, avoiding code duplication; * re-export map from existing GHC.Internal.Data.List.NonEmpty; and * re-export map from Data.List.NonEmpty (base package); without breaking anything in the GHC repository. Various tests *.stdout and *.stderr files are amended also. - - - - - ab3ab3e3 by Luite Stegeman at 2025-01-13T12:59:58-05:00 compiler/coreprep: Turn off dictionary speculation by default Speculative evaluation can cause performance regressions, therefore we turn it off by default. It can be enabled again with the -fspec-eval-dictfun flag See #25284 - - - - - 3d9cacd5 by Patrick at 2025-01-14T02:34:46+08:00 Enhance kind inference for data family instances This commit improves kind inference for data family instances by kind-checking the constructors, for H98 and newtype declarations (ONLY), as well as kind-checking the result kind signature (when using GADT syntax). This fixes #25611. Typechecker changes: In `tcDataFamInstHeader`, we now kind-check the constructors using `kcConDecls`, for H98-style decls and newtype decls ONLY. See Note [Kind inference for data family instances]. Testsuite changes: - The T25611{a,b,c,d} tests test the new kind inference implementation. - a,b: infer result kind from constructors (H98 case) - c: renamed version of test UnliftedNewtypesUnassociatedFamilyFail, which now passes - d: GADT case, checking that we don't infer overly rigid kinds when kind-checking the constructors in data family instances. - DataInstanceKindsDefaults tests defaulting data instance kinds without UnliftedNewtypes or UnliftedDatatypes, as outlined in Note [Defaulting result kind of newtype/data family instance]. Also a few notes are updated to reflect the changes. Co-authored-by: default avatarSimon Peyton Jones <simon.peytonjones at gmail.com> - - - - - f6493dbc by amesgen at 2025-01-15T18:47:23-05:00 wasm: prevent bundlers from resolving import("node:timers") This fixes the following esbuild error: ✘ [ERROR] Could not resolve "node:timers" www/ghc_wasm_jsffi.js:66:25: 66 │ return (await import("node:timers")).setImmediate; ╵ ~~~~~~~~~~~~~ The package "node:timers" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "--platform=node" to do that, which will remove this error. Previously (i.e. after !13503), one had to work around this by passing `--external:node:timers`. - - - - - 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 51e3ec83 by Vladislav Zavialov at 2025-01-22T20:41:32+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 85c60aea by Teo Camarasu at 2025-01-23T18:06:21-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4495e48f by Brandon Chinn at 2025-01-24T11:54:24-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 4f8fc11e by Brandon Chinn at 2025-01-24T11:54:24-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - e7ab778f by Matthew Pickering at 2025-01-24T11:55:01-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - c3593101 by Sylvain Henry at 2025-01-24T23:12:20-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 70f7741a by Jens Petersen at 2025-01-24T23:12:58-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - a1d92378 by Brandon Chinn at 2025-01-25T15:11:54-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 62760367 by ARATA Mizuki at 2025-01-27T16:23:06-05:00 x86 NCG: Make MOVD's output format explicit The old design led to inference of a wrong format, losing upper bits of a vector register. Fixes #25659 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - f19ab490 by Simon Hengel at 2025-01-27T16:23:45-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - e16eae65 by Cheng Shao at 2025-01-27T21:41:39+00:00 hadrian: fix bootstrap with 9.12.1 This patch bumps hadrian index-state to fix bootstrap with 9.12.1. - - - - - 30 changed files: - .gitlab/ci.sh - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Core/Opt/Pipeline.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Cmm.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/DynFlags.hs - compiler/GHC/Driver/Env.hs - compiler/GHC/Driver/Errors.hs - compiler/GHC/Driver/Errors/Ppr.hs - compiler/GHC/Driver/Errors/Types.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a3bc1b0e0810a3b014df22fc31f739ae0ec33bc...e16eae6548743870e77c2c93527bab1d24cff81c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a3bc1b0e0810a3b014df22fc31f739ae0ec33bc...e16eae6548743870e77c2c93527bab1d24cff81c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 02:27:02 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Mon, 27 Jan 2025 21:27:02 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] add workaround for incorrect build ordering Message-ID: <67984076477f0_2aefa3e0070430811@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 254defb9 by Luite Stegeman at 2025-01-28T03:24:41+01:00 add workaround for incorrect build ordering this should fix CI failures mentioning missing files in the ghc-bignum package see #23942 - - - - - 1 changed file: - compiler/GHC/Utils/Containers/Internal/StrictPair.hs Changes: ===================================== compiler/GHC/Utils/Containers/Internal/StrictPair.hs ===================================== @@ -7,6 +7,9 @@ module GHC.Utils.Containers.Internal.StrictPair (StrictPair(..), toPair) where +import Prelude () -- for build ordering; see #23942 and + -- Note [Depend on GHC.Num.Integer] in base:GHC.Base + -- | The same as a regular Haskell pair, but -- -- @ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/254defb9fc0a3aff38d0b10c482fbeb2009d7637 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/254defb9fc0a3aff38d0b10c482fbeb2009d7637 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 09:16:53 2025 From: gitlab at gitlab.haskell.org (Serge S. Gulin (@gulin.serge)) Date: Tue, 28 Jan 2025 04:16:53 -0500 Subject: [Git][ghc/ghc][wip/T24603] 4 commits: Fix for alex-3.5.2.0 (#25623) Message-ID: <6798a085b0572_32a9b316042c0125046@gitlab.mail> Serge S. Gulin pushed to branch wip/T24603 at Glasgow Haskell Compiler / GHC Commits: a1d92378 by Brandon Chinn at 2025-01-25T15:11:54-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 62760367 by ARATA Mizuki at 2025-01-27T16:23:06-05:00 x86 NCG: Make MOVD's output format explicit The old design led to inference of a wrong format, losing upper bits of a vector register. Fixes #25659 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - f19ab490 by Simon Hengel at 2025-01-27T16:23:45-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - a414412d by Serge S. Gulin at 2025-01-28T12:16:22+03:00 Support for ARM64 Windows (LLVM-enabled) (fixes #24603) submodule Co-authored-by: Cheng Shao <terrorjack at type.dance> Co-authored-by: Dmitrii Egorov <egorov.d.i at icloud.com> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> - - - - - 24 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/Parser/Lexer.x - docs/users_guide/diagnostics-as-json-schema-1_0.json - docs/users_guide/diagnostics-as-json-schema-1_1.json - hadrian/cabal.project - libraries/Cabal - libraries/Win32 - libraries/base/src/System/CPUTime/Windows.hsc - libraries/base/tests/perf/encodingAllocations.hs - libraries/directory - libraries/haskeline - libraries/process - libraries/unix - llvm-targets - m4/ghc_tables_next_to_code.m4 - rts/StgCRun.c - rts/win32/veh_excn.c - + testsuite/tests/simd/should_run/T25659.hs - + testsuite/tests/simd/should_run/T25659.stdout - testsuite/tests/simd/should_run/all.T - utils/hsc2hs - utils/llvm-targets/gen-data-layout.sh Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1171,7 +1171,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps bitcast :: Format -> Format -> CmmExpr -> NatM Register bitcast fmt rfmt expr = do (src, e_code) <- getSomeReg expr - let code = \dst -> e_code `snocOL` (MOVD fmt (OpReg src) (OpReg dst)) + let code = \dst -> e_code `snocOL` (MOVD fmt rfmt (OpReg src) (OpReg dst)) return (Any rfmt code) toI8Reg :: Width -> CmmExpr -> NatM Register @@ -1262,7 +1262,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps code dst = exp `snocOL` -- VPBROADCAST from GPR requires AVX-512, -- so we use an additional MOVD. - (MOVD movFormat (OpReg reg) (OpReg dst)) `snocOL` + (MOVD movFormat fmt (OpReg reg) (OpReg dst)) `snocOL` (VPBROADCAST fmt fmt (OpReg dst) dst) return $ Any fmt code @@ -1272,7 +1272,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 16 FmtInt8 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLBW fmt (OpReg dst) dst) `snocOL` (PUNPCKLWD (VecFormat 8 FmtInt16) (OpReg dst) dst) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) @@ -1284,7 +1284,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 8 FmtInt16 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLWD fmt (OpReg dst) dst) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) ) @@ -1295,7 +1295,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 4 FmtInt32 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) ) @@ -1305,7 +1305,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 2 FmtInt64 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II64 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLQDQ fmt (OpReg dst) dst) ) @@ -1793,16 +1793,16 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case i of 0 -> exp `snocOL` - (MOVD FF32 (OpReg r) (OpReg dst)) + (MOVD fmt II32 (OpReg r) (OpReg dst)) 1 -> exp `snocOL` (PSHUFD fmt (ImmInt 0b01_01_01_01) (OpReg r) tmp) `snocOL` -- tmp <- (r[1],r[1],r[1],r[1]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) 2 -> exp `snocOL` (PSHUFD fmt (ImmInt 0b11_10_11_10) (OpReg r) tmp) `snocOL` -- tmp <- (r[2],r[3],r[2],r[3]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) _ -> exp `snocOL` (PSHUFD fmt (ImmInt 0b11_11_11_11) (OpReg r) tmp) `snocOL` -- tmp <- (r[3],r[3],r[3],r[3]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) return (Any II32 code) vector_int32x4_extract_sse2 _ offset = pprPanic "Unsupported offset" (pdoc platform offset) @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD FF64 (OpReg r) (OpReg dst)) + (MOVD fmt II64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD FF64 (OpReg tmp) (OpReg dst)) + (MOVD fmt II64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset @@ -2103,22 +2103,22 @@ getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps = case offset of 0 -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` (MOV floatVectorFormat (OpReg tmp1) (OpReg dst)) -- MOVSS; dst <- (tmp1[0],dst[1],dst[2],dst[3]) 1 -> valExp `appOL` (vecCode tmp1) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0) (PUNPCKLQDQ vectorFormat (OpReg tmp1) dst) `snocOL` -- dst <- (dst[0],dst[1],tmp1[0],tmp1[1]) (SHUF floatVectorFormat (ImmInt 0b11_10_00_10) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[2],dst[0],tmp1[2],tmp1[3]) 2 -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) (MOVU floatVectorFormat (OpReg dst) (OpReg tmp2)) `snocOL` -- MOVUPS; tmp2 <- dst (SHUF floatVectorFormat (ImmInt 0b01_00_01_11) (OpReg tmp1) tmp2) `snocOL` -- SHUFPS; tmp2 <- (tmp2[3],tmp2[1],tmp1[0],tmp1[1]) (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp2) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp2[2],tmp2[0]) _ -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) (SHUF floatVectorFormat (ImmInt 0b11_10_01_00) (OpReg dst) tmp1) `snocOL` -- SHUFPS; tmp1 <- (tmp1[0],tmp1[1],dst[2],dst[3]) (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp1[2],tmp1[0]) return $ Any vectorFormat code @@ -2139,12 +2139,12 @@ getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps CmmInt 0 _ -> valExp `appOL` vecExp `snocOL` (MOVHLPS fmt vecReg tmp) `snocOL` - (MOVD II64 (OpReg valReg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg valReg) (OpReg dst)) `snocOL` (PUNPCKLQDQ fmt (OpReg tmp) dst) CmmInt 1 _ -> valExp `appOL` vecExp `snocOL` - (MOV II64 (OpReg vecReg) (OpReg dst)) `snocOL` - (MOVD II64 (OpReg valReg) (OpReg tmp)) `snocOL` + (MOVDQU fmt (OpReg vecReg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg valReg) (OpReg tmp)) `snocOL` (PUNPCKLQDQ fmt (OpReg tmp) dst) _ -> pprPanic "MO_V_Insert Int64X2: unsupported offset" (ppr offset) in return $ Any fmt code @@ -4083,7 +4083,7 @@ loadArgsWin config (arg:rest) = do -- arguments in both fp and integer registers. let (assign_code', regs') | isFloatFormat arg_fmt = - ( assign_code `snocOL` MOVD FF64 (OpReg freg) (OpReg ireg), + ( assign_code `snocOL` MOVD FF64 II64 (OpReg freg) (OpReg ireg), [ RegWithFormat freg FF64 , RegWithFormat ireg II64 ]) | otherwise = (assign_code, [RegWithFormat ireg II64]) ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -39,7 +39,6 @@ module GHC.CmmToAsm.X86.Instr , patchJumpInstr , isMetaInstr , isJumpishInstr - , movdOutFormat , MinOrMax(..), MinMaxType(..) ) where @@ -127,11 +126,16 @@ data Instr -- with @MOVABS@; we currently do not use this instruction in GHC. -- See https://stackoverflow.com/questions/52434073/whats-the-difference-between-the-x86-64-att-instructions-movq-and-movabsq. - | MOVD Format Operand Operand -- ^ MOVD/MOVQ SSE2 instructions - -- (bitcast between a general purpose - -- register and a float register). - -- Format is input format, output format is - -- calculated in the 'movdOutFormat' function. + -- | MOVD/MOVQ SSE2 instructions + -- (bitcast between a general purpose register and a float register). + | MOVD + Format -- ^ input format + Format -- ^ output format + Operand Operand + -- NB: MOVD stores both the input and output formats. This is because + -- neither format fully determines the other, as either might be + -- a vector format, and we need to know the exact format in order to + -- correctly spill/unspill. See #25659. | CMOV Cond Format Operand Reg | MOVZxL Format Operand Operand -- ^ The format argument is the size of operand 1 (the number of bits we keep) @@ -377,10 +381,10 @@ regUsageOfInstr platform instr -- (largely to avoid partial register stalls) | otherwise -> usageRW fmt src dst - MOVD fmt src dst -> + MOVD fmt1 fmt2 src dst -> -- NB: MOVD and MOVQ always zero any remaining upper part of destination, -- so the destination is "written" not "modified". - usageRW' fmt (movdOutFormat fmt) src dst + usageRW' fmt1 fmt2 src dst CMOV _ fmt src dst -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst] MOVZxL fmt src dst -> usageRW fmt src dst MOVSxL fmt src dst -> usageRW fmt src dst @@ -650,14 +654,6 @@ interesting :: Platform -> Reg -> Bool interesting _ (RegVirtual _) = True interesting platform (RegReal (RealRegSingle i)) = freeReg platform i -movdOutFormat :: Format -> Format -movdOutFormat format = case format of - II32 -> FF32 - II64 -> FF64 - FF32 -> II32 - FF64 -> II64 - _ -> pprPanic "X86: improper format for movd/movq" (ppr format) - -- | Applies the supplied function to all registers in instructions. -- Typically used to change virtual registers to real registers. @@ -665,7 +661,7 @@ patchRegsOfInstr :: HasDebugCallStack => Platform -> Instr -> (Reg -> Reg) -> In patchRegsOfInstr platform instr env = case instr of MOV fmt src dst -> MOV fmt (patchOp src) (patchOp dst) - MOVD fmt src dst -> patch2 (MOVD fmt) src dst + MOVD fmt1 fmt2 src dst -> patch2 (MOVD fmt1 fmt2) src dst CMOV cc fmt src dst -> CMOV cc fmt (patchOp src) (env dst) MOVZxL fmt src dst -> patch2 (MOVZxL fmt) src dst MOVSxL fmt src dst -> patch2 (MOVSxL fmt) src dst ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -657,8 +657,8 @@ pprInstr platform i = case i of CMOV cc format src dst -> pprCondOpReg (text "cmov") format cc src dst - MOVD format src dst - -> pprMovdOpOp (text "mov") format src dst + MOVD format1 format2 src dst + -> pprMovdOpOp (text "mov") format1 format2 src dst MOVZxL II32 src dst -> pprFormatOpOp (text "mov") II32 src dst @@ -1151,21 +1151,21 @@ pprInstr platform i = case i of pprOperand platform format op2 ] - pprMovdOpOp :: Line doc -> Format -> Operand -> Operand -> doc - pprMovdOpOp name format op1 op2 - = let instr = case format of + pprMovdOpOp :: Line doc -> Format -> Format -> Operand -> Operand -> doc + pprMovdOpOp name format1 format2 op1 op2 + = let instr = case (format1, format2) of -- bitcasts to/from a general purpose register to a floating point -- register require II32 or II64. - II32 -> text "d" - II64 -> text "q" - FF32 -> text "d" - FF64 -> text "q" - _ -> panic "X86.Ppr.pprMovdOpOp: improper format for movd/movq." + (II32, _) -> text "d" + (II64, _) -> text "q" + (_, II32) -> text "d" + (_, II64) -> text "q" + _ -> panic "X86.Ppr.pprMovdOpOp: improper format for movd/movq." in line $ hcat [ char '\t' <> name <> instr <> space, - pprOperand platform format op1, + pprOperand platform format1 op1, comma, - pprOperand platform (movdOutFormat format) op2 + pprOperand platform format2 op2 ] pprFormatImmRegOp :: Line doc -> Format -> Imm -> Reg -> Operand -> doc ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -41,6 +41,7 @@ -- Alex "Haskell code fragment top" { +{-# LANGUAGE CPP #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiWayIf #-} @@ -3366,11 +3367,15 @@ topNoLayoutContainsCommas [] = False topNoLayoutContainsCommas (ALRLayout _ _ : ls) = topNoLayoutContainsCommas ls topNoLayoutContainsCommas (ALRNoLayout b _ : _) = b +#ifdef MIN_TOOL_VERSION_alex +#if !MIN_TOOL_VERSION_alex(3,5,2) -- If the generated alexScan/alexScanUser functions are called multiple times -- in this file, alexScanUser gets broken out into a separate function and -- increases memory usage. Make sure GHC inlines this function and optimizes it. -- https://github.com/haskell/alex/pull/262 {-# INLINE alexScanUser #-} +#endif +#endif lexToken :: P (PsLocated Token) lexToken = do ===================================== docs/users_guide/diagnostics-as-json-schema-1_0.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", ===================================== docs/users_guide/diagnostics-as-json-schema-1_1.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", ===================================== hadrian/cabal.project ===================================== @@ -8,7 +8,7 @@ index-state: 2024-10-30T22:56:00Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 -allow-newer: unordered-containers:template-haskell +allow-newer: unordered-containers:template-haskell, splitmix:base, hashable:base, cryptohash-sha256:base -- N.B. Compile with -O0 since this is not a performance-critical executable -- and the Cabal takes nearly twice as long to build with -O1. See #16817. ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 269fd808e5d80223a229b6b19edfe6f5b109007a +Subproject commit 682c54a9e8127c79e714545dbf493bb5de470945 ===================================== libraries/Win32 ===================================== @@ -1 +1 @@ -Subproject commit 027cbcf0de25d681823ea92fb545a2604c3a6a8b +Subproject commit f340d2c3d846fce73117dd2548ad1bf0c56ceb9d ===================================== libraries/base/src/System/CPUTime/Windows.hsc ===================================== @@ -60,7 +60,7 @@ type HANDLE = () #if defined(i386_HOST_ARCH) foreign import stdcall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import stdcall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt -#elif defined(x86_64_HOST_ARCH) +#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) foreign import ccall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import ccall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt #else ===================================== libraries/base/tests/perf/encodingAllocations.hs ===================================== @@ -13,13 +13,13 @@ import Distribution.Simple.Utils main :: IO () -main = withTempFile "." "encodingAllocations.tmp" (const $ loop 1000000) +main = withTempFile "encodingAllocations.tmp" (loop 1000000) -loop :: Int -> Handle -> IO () -loop 0 !_ = pure () -loop !n !h = do +loop :: Int -> FilePath -> Handle -> IO () +loop 0 !_ !_ = pure () +loop !n !fp !h = do hPutChar h $! dummy_char n - loop (n-1) h + loop (n-1) fp h -- unsafe efficient version of `chr` my_chr :: Int -> Char ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 005fa061171a55d35ce8dfe936cf3703525a8616 +Subproject commit eb40bbebcaf86153bbc60772fb2e0466d35c95c4 ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 5f4bf62bf1f4846ad0b8d1fa9d45f902e3934511 +Subproject commit 5f1a790a5db1cb3708d105d4f532c32fcbeb4296 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 9c3bfc214c72bbd0c8a30a1c41465deed0feaf47 +Subproject commit fbbe60718736999db701c12528c85cbc605ab4fb ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 74ae1c0d9dd1518434f7d6cd3e63d7769599e0f9 +Subproject commit 9208d3a5809476e64b9a387a6000821083d1ebfd ===================================== llvm-targets ===================================== @@ -1,4 +1,5 @@ [("x86_64-unknown-windows-gnu", ("e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "")) +,("aarch64-unknown-windows-gnu", ("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32", "generic", "+v8a +fp-armv8 +neon")) ,("arm-unknown-linux-gnueabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm7tdmi", "+strict-align")) ,("arm-unknown-linux-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ,("arm-unknown-linux-musleabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ===================================== m4/ghc_tables_next_to_code.m4 ===================================== @@ -22,8 +22,13 @@ AC_DEFUN([GHC_TABLES_NEXT_TO_CODE], AC_MSG_RESULT([no]) ;; *) - TablesNextToCodeDefault=YES - AC_MSG_RESULT([yes]) + if test "$TargetOS" = "mingw32" && test "$TargetArch" = "aarch64"; then + TablesNextToCodeDefault=NO + AC_MSG_RESULT([no]) + else + TablesNextToCodeDefault=YES + AC_MSG_RESULT([yes]) + fi ;; esac ;; ===================================== rts/StgCRun.c ===================================== @@ -863,8 +863,12 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { */ "br %1\n\t" +#if defined(mingw32_HOST_OS) + ".globl " STG_RETURN "\n" +#else ".globl " STG_RETURN "\n\t" -#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) +#endif +#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) && !defined(mingw32_HOST_OS) ".type " STG_RETURN ", %%function\n" #endif STG_RETURN ":\n\t" ===================================== rts/win32/veh_excn.c ===================================== @@ -287,6 +287,16 @@ void generateStack (EXCEPTION_POINTERS* pExceptionPointers) stackFrame.AddrStack.Offset = context->Rsp; stackFrame.AddrStack.Mode = AddrModeFlat; +#elif defined(aarch64_HOST_ARCH) + machineType = IMAGE_FILE_MACHINE_ARM64; + stackFrame.AddrPC.Offset = context->Pc; + stackFrame.AddrPC.Mode = AddrModeFlat; + + stackFrame.AddrFrame.Offset = context->Fp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + + stackFrame.AddrStack.Offset = context->Sp; + stackFrame.AddrStack.Mode = AddrModeFlat; #endif fprintf (stderr, "\n Attempting to reconstruct a stack trace...\n\n"); if (!SymInitialize (GetCurrentProcess (), NULL, true)) ===================================== testsuite/tests/simd/should_run/T25659.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\_ b -> b) ===================================== testsuite/tests/simd/should_run/T25659.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (22,33) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -26,6 +26,7 @@ test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation +test('T25659', [], compile_and_run, ['']) # Ensure we set the CPU features we have available. # ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit c3b21800a67366c9591dc85a471d1dfdb1efcf29 +Subproject commit 2fab2f4cdffef12afe561ef03f5ebdace7dbae67 ===================================== utils/llvm-targets/gen-data-layout.sh ===================================== @@ -27,6 +27,7 @@ TARGETS=( # Windows "x86_64-unknown-windows-gnu" + "aarch64-unknown-windows-gnu" ######################### # Linux View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/002e26c0ba0415ceac14f9717eb6dc03e7f66d4a...a414412dcbec1835dc12d3bb8a7568243a4f325a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/002e26c0ba0415ceac14f9717eb6dc03e7f66d4a...a414412dcbec1835dc12d3bb8a7568243a4f325a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 09:32:57 2025 From: gitlab at gitlab.haskell.org (Jens Petersen (@juhp)) Date: Tue, 28 Jan 2025 04:32:57 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/juhp-hp2ps-libstdh Message-ID: <6798a44963321_35dffd1fbdc8911d0@gitlab.mail> Jens Petersen pushed new branch wip/juhp-hp2ps-libstdh at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/juhp-hp2ps-libstdh You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 09:42:13 2025 From: gitlab at gitlab.haskell.org (Jens Petersen (@juhp)) Date: Tue, 28 Jan 2025 04:42:13 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/juhp-hp2ps-fixup Message-ID: <6798a6759f4b4_35dffd39c47096646@gitlab.mail> Jens Petersen deleted branch wip/juhp-hp2ps-fixup at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 10:41:02 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Tue, 28 Jan 2025 05:41:02 -0500 Subject: [Git][ghc/ghc][wip/T24359] revert back to previous plan, adding tests etc Message-ID: <6798b43eac432_371ce8402b803575c@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 353cdf66 by sheaf at 2025-01-28T11:40:49+01:00 revert back to previous plan, adding tests etc - - - - - 7 changed files: - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Zonk/Type.hs - + testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -862,23 +862,8 @@ data TcSpecPrag , spe_bndrs :: [Var] -- ^ TyVars, EvVars, and Ids - , spe_expr :: LHsExpr GhcTc + , spe_call :: LHsExpr GhcTc -- ^ The type-checked specialise expression - , spe_rule_binds :: TcEvBinds - -- ^ "RULE RHS evidence bindings" - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig - , spe_call_evvars :: [Var] - -- ^ "specialised call evidence variables" - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig - , spe_call_wrapper :: HsWrapper - -- ^ wrapper for the specialised call - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig } noSpecPrags :: TcSpecPrags @@ -1027,7 +1012,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,9 +791,6 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -SLD TODO: rewrite this whole note, using the same example as -Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. - Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -930,22 +927,7 @@ dsSpec poly_rhs ( , spe_fn_id = poly_id , spe_inl = inl , spe_bndrs = bndrs - , spe_expr = the_call - - -- BLUE bindings (sd1 = d1, sd2 = d3) - , spe_rule_binds = EvBinds rule_evbinds - -- SLD TODO: I am not using the bindings anywhere, only the LHS EvVars - -- - -- On the face of it, this seems obviously incorrect (I am missing the - -- BLUE let bindings), but I don't have a case that triggers a problem, - -- while ADDING the BLUE bindings causes complications due to the fact - -- that the 'sd's are defined by simplifying the 'd's, without cloning, - -- so we naively get (loopy) recursive bindings. - - -- RED binders (d1,..., d4) - , spe_call_evvars = rule_evvars - -- HsWrapper for RED evidence binds (let d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... in) - , spe_call_wrapper = call_wrapper + , spe_call = the_call }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig = do { ds_call <- unsetGOptM Opt_EnableRewriteRules $ -- Note [Desugaring RULE left hand sides] @@ -953,69 +935,80 @@ dsSpec poly_rhs ( zapUnspecables $ dsLExpr the_call + -- Simplify the (desugared) call; see wrinkle (SP1) + -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let - -- See (SP1) in Note [Desugaring SPECIALISE pragmas] - simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - ; case collectSpecArgs poly_id core_call of { + ; let simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + ; case prepareSpecLHS poly_id bndrs core_call of { Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - Just rule_lhs_args -> - do { let - -- BLUE binders, in correspondence with the LHS of the blue bindings - spec_evvars = - map evBindVar (bagToList rule_evbinds) - -- Yes: rule_evbinds and not call_evbinds. - -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] - -- if this is not clear. - - -- The rule binders, including the RED binders d1, ..., d4 - rule_bndrs = scopedSort $ bndrs ++ rule_evvars - -- The specialised $sf binders, including the BLUE binders sd1, sd2 - spec_bndrs = scopedSort $ bndrs ++ spec_evvars - - ; dsHsWrapper call_wrapper $ \ wrap_call -> - do { let mk_spec_body fn_rhs = wrap_call $ mkCoreApps fn_rhs rule_lhs_args - ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id - , text "bndrs:" <+> ppr bndrs - , text "ds_call:" <+> ppr ds_call - , text "core_call:" <+> ppr core_call - , text "rule_evbinds:" <+> ppr rule_evbinds - , text (replicate 40 '-') - , text "rule_evvars:" <+> ppr rule_evvars - , text "spec_evvars:" <+> ppr spec_evvars - , text "rule_bndrs:" <+> ppr rule_bndrs - , text "spec_bndrs:" <+> ppr spec_bndrs - , text "rule_lhs_args:" <+> ppr rule_lhs_args - ]) - ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id rule_lhs_args - spec_bndrs mk_spec_body inl + ; return Nothing } ; + + Just (bndr_set, spec_const_binds, lhs_args) -> + + do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) + all_bndrs = bndr_set `unionVarSet` const_bndrs + -- all_bndrs: all binders in core_call that should be quantified - } } } } -dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" + -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] + rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) + spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs + + mk_spec_body fn_body = mkLets spec_const_binds $ + mkCoreApps fn_body lhs_args + + ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id + , text "bndrs" <+> ppr bndrs + , text "all_bndrs" <+> ppr all_bndrs + , text "const_bndrs" <+> ppr const_bndrs + , text "ds_call" <+> ppr ds_call + , text "core_call" <+> ppr core_call + , text "core_call fvs" <+> ppr (exprFreeVars core_call) + , text "spec_const_binds" <+> ppr spec_const_binds ]) + + ; finishSpecPrag poly_nm poly_rhs + rule_bndrs poly_id lhs_args + spec_bndrs mk_spec_body inl } } } -collectSpecArgs :: Id -> CoreExpr - -> Maybe [CoreExpr] +prepareSpecLHS :: Id -> [EvVar] -> CoreExpr + -> Maybe (VarSet, [CoreBind], [CoreExpr]) -- See (SP2) in Note [Desugaring SPECIALISE pragmas] --- SLD TODO: good example for this is simpl016 -collectSpecArgs poly_id the_call - = go the_call +prepareSpecLHS poly_id evs the_call + = go (mkVarSet evs) [] the_call where - go :: CoreExpr - -> Maybe [CoreExpr] - go (Cast e _) - = go e - go (Let _bind e) - = go e - go e + go :: VarSet -- Quantified variables, or dependencies thereof + -> [CoreBind] -- Reversed list of constant evidence bindings + -> CoreExpr + -> Maybe (IdSet, [CoreBind], [CoreExpr]) + go qevs acc (Cast e _) + = go qevs acc e + go qevs acc (Let bind e) + | not (all isDictId bndrs) -- A normal 'let' is too complicated + = Nothing + + | all (transfer_to_spec_rhs qevs) $ + rhssOfBind bind -- One of the `const_binds` + = go qevs (bind:acc) e + + | otherwise + = go (qevs `extendVarSetList` bndrs) acc e + where + bndrs = bindersOf bind + + go qevs acc e | (Var fun, args) <- collectArgs e = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just args + Just (qevs, reverse acc, args) | otherwise = Nothing + transfer_to_spec_rhs qevs rhs + = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) + where + is_quant_id v = isId v && v `elemVarSet` qevs + -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern -> [Var] -> (CoreExpr -> CoreExpr) -> InlinePragma -- Specialised form ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag, runTcSWithEvBinds ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -722,93 +722,20 @@ demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} -We want to generate: - - RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). - f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True - = let - sd1 = d2 -- We will refer to these as the - sd2 = d4 -- "RULE RHS evidence bindings" - in - $sf @p @q sd1 sd2 x y z - $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) - = let(non-rec) f = in - let - d1 = $fEqList $fEqInt -- - d2 = sd1 -- We will refer to these as the - d3 = sd1 -- "specialised call evidence bindings" - d4 = sd2 -- - in - f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True - -Key observations: - - O1. - - The most important part is to **completely solve** the Eq [Int] constraint, - so that we specialise the call to 'f' to a known dictionary. Without that, - we're not doing any typeclass specialisation! - - O2. - - The `rule_bndrs`, over which the RULE is quantified, are all the variables - free in the call to `f`, /ignoring/ all dictionary simplification. Why? - Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. This is why, in the above example, - the rule binders are: - - rule_bndrs = @p @q - (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) - (x::[Int]) (y::p) (z::q). - - Note that: - - - We have separate binders for `d2` and `d3` even though they are - the same (Eq p) dictionary. Reason: we don't want to force them to be - visibly equal at the call site. - - - We don't assume that the dictionary for 'Eq [q]' was obtained - from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - - generate a RULE of the form - - forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - which is verboten (it matches on the structure of a dictionary), or - - - "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]), which is impossible to do in general. - - "Partially solving" the Eq [q] constraint by using the instance doesn't - buy us anything; we can't do anything useful with the information that an - Eq [q] dictionary is of the form ($fEqList ..). - - To achieve this, we solve the constraints that originated from typechecking - the expression to specialise, but in the special 'TcSSpecPrag' mode, which - ensures that: - - - We don't use instances (whether top-level instances or local instances - from quantified constraints), as those are not "reversible", - - EXCEPT that we **do** use the short-cut solver, so that we can fully - solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). - - O3. - - In the body of $sf, note that we: - - - define 'let(non-rec) f = ' - - refer to this shadowing 'f' in the last line of $sf - - This allows us to deal with functions that recursively call themselves, - as opposed to simply writing - - $sf ... = - let - in - () @p @p @[q] d1 d2 d3 d4 x y y [z] True +Example: + f :: forall a b. (Eq a, Eq b, Eq c) => a -> b -> c -> Bool -> blah + {-# SPECIALISE forall x y. f (x::Int) y y True #-} + -- y::p +We want to generate: + RULE forall @p (d1::Eq Int) (d2::Eq p) (d3::Eq p) (x::Int) (y::p). + f @Int @p @p d1 d2 d3 x y y True + = $sf @p d2 x y + $sf @p (d2::Eq p) (x::Int) (y::p) + = let d1 = $fEqInt + d3 = d2 + in @p @p @Int (d1::Eq p) (d2::Eq p) (d3::Eq p) x y y True Note that @@ -835,26 +762,46 @@ Note that spec_const_binds = let d1 = $fEqInt d3 = d2 -How it works: +This is done in three parts. + + A. Typechecker: `GHC.Tc.Gen.Sig.tcSpecPrag` + + (1) Typecheck the expression, capturing its constraints + + (2) Simplify these constraints, in special TcSSpecPrag mode + SLD TODO add more details. -* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results - into a `SpecPragE` record. Nothing very exciting happens here. + (3) Decide which constraints to quantify over, and quantify. -* `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any - free type variables of the LHS. See Note [Free tyvars on rule LHS] in - GHC.Tc.Zonk.Type. These weren't conveniently available earlier. + (4) Emit the residual (non-quantified) constraints, and wrap the + expression in a let binding for those constraints. -* `GHC.HsToCore.Binds.dsSpec` does the clever stuff: + (5) Store all the information in a 'SpecPragE' record, to be consumed + by the desugarer. - * Simplifies the expression. This is important because a type signature in the - expression will have led to type/dictionary abstractions/applications. Now - it should look like - let in f e1 e1 e3 + B. Zonker: `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` - * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards - the other dictionary bindings, and decomposes the call. + The zonker does a little extra work to collect any free type variables + of the LHS. See Note [Free tyvars on rule LHS] in GHC.Tc.Zonk.Type. + These weren't conveniently available earlier. - * Then it can build the RULE and specialised function. + C. Desugarer: `GHC.HsToCore.Binds.dsSpec`. + + This is where most of the clever stuff happens. See + Note [Desugaring SPECIALISE pragmas] in GHC.HsToCore.Binds for details, + but in brief: + + (1) Simplify the expression. This is important because a type signature in + the expression will have led to type/dictionary abstractions/applications. + Now it should look like + let in f d1 d2 d3 + + (2) `prepareSpecLHS` identifies the `spec_const_binds`, discards the other + dictionary bindings, and decomposes the call. + + (3) Then we build the specialised function $sf, and concoct a RULE + of the form: + forall @a @b d1 d2 d3. f d1 d2 d3 = $sf d1 d2 d3 Note [Handling old-form SPECIALISE pragmas] @@ -1027,84 +974,44 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm - ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) + ; traceTc "tcSpecPrag SpecSigE 1" (ppr nm $$ ppr spec_e) ; skol_info <- mkSkolemInfo skol_info_anon ; (rhs_tclvl, wanted, (rule_bndrs', (tc_spec_e, _rho))) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- (2) Perform unifications: - -- - clone the original constraints, - -- - simplify these cloned constraints - -- - zonk the original constraints - ; wanted_clone <- cloneWC wanted - ; _ <- setTcLevel rhs_tclvl $ - runTcS $ - solveWanteds wanted_clone - ; wanted <- liftZonkM $ zonkWC wanted - - -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted - ; let qevs = map ctEvId (bagToList quant_cts) - - -- (4) Emit the residual constraints. - ; non_quant_binds <- newTcEvBinds + -- (2) Simplify the constraints, in special TcSSpecPrag mode + ; ev_binds_var <- newTcEvBinds + ; wanted <- setTcLevel rhs_tclvl $ + runTcSWithEvBinds ev_binds_var $ + solveWanteds wanted + + -- (3) Quantify over the constraints + ; qevs <- mapM newEvVar $ + ctsPreds $ + approximateWC False wanted + + -- (4) Emit the residual (non-quantified) constraints, + -- and wrap the expression in the evidence let bindings ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds + ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var emptyVarSet tv_bndrs qevs - non_quant_wc - - -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) - -- by solving "quant_cts" in the special TcSSpecPrag mode - ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ - vcat [ text "quant_cts:" <+> ppr quant_cts ] - ; (rule_rhs_wc, spec_call_binds) - <- setTcLevel rhs_tclvl $ - runTcSSpecPrag $ - solveWanteds (emptyWC { wc_simple = quant_cts }) - ; let rule_rhs_implics = wc_impl rule_rhs_wc - ; massertPpr (null rule_rhs_implics) $ - vcat [ text "tcSpecPrag: unexpected non-simple constraints" - , text "quant_cts:" <+> ppr quant_cts - , text "implics:" <+> ppr rule_rhs_implics ] - ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ - vcat [ text "quant_cts:" <+> ppr quant_cts - , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] - - -- (6) Figure out the blue bindings by solving the implication - -- [G] d1, d2, d3, d4 => [W] sd1, sd2 - ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ - vcat [ text "qevs:" <+> ppr qevs - , text "rule_rhs_wc:" <+> ppr rule_rhs_wc - ] - ; (implics, rule_rhs_binds) <- - buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs - qevs -- d1, d2, d3, d4 - rule_rhs_wc -- sd1, sd2 - ; emitImplications implics - - ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ + wanted + ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) tc_spec_e + + ; traceTc "tcSpecPrag:SpecSigE" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl - , text "non_quant:" <+> ppr non_quant_wc - , text (replicate 40 '-') - , text "spec_call_binds:" <+> ppr spec_call_binds - ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_inl = inl - , spe_bndrs = rule_bndrs' - , spe_expr = tc_spec_e - , spe_rule_binds = rule_rhs_binds - , spe_call_evvars = qevs - , spe_call_wrapper = - WpLet (TcEvBinds non_quant_binds) - <.> WpLet (EvBinds spec_call_binds) - }] } + , text "inl:" <+> ppr inl ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order + -- does not matter + , spe_call = lhs_call + , spe_inl = inl }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,29 +854,20 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_expr = spec_e - , spe_rule_binds = rule_evbinds - , spe_call_evvars = call_evvars - , spe_call_wrapper = call_wrapper })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_call = spec_e })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> - runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> - runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> - runZonkBndrT (zonkCoFn call_wrapper) $ \ call_wrapper' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_expr = spec_e' - , spe_rule_binds = rule_evbinds' - , spe_call_evvars = call_evvars' - , spe_call_wrapper = call_wrapper' + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_call = spec_e' })) }} ===================================== testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE QuantifiedConstraints #-} + +module DsSpecPragmas where + +-- Some specialise pragmas that are difficult to generate the correct RULE for. + +-------------------------------------------------------------------------------- + +f1 :: ( Num a, Eq b ) => a -> b -> Int +f1 _ _ = 111 + +-- Make sure we don't generate a rule with an LHS of the form +-- +-- forall @e (d :: Eq e). f @[e] ($fEqList d) = ... +-- +-- but rather +-- +-- forall @e (d :: Eq [e]). f @[e] d = ... +{-# SPECIALISE f1 :: Eq [e] => Word -> [e] -> Int #-} + +-------------------------------------------------------------------------------- + +f2 :: ( Eq a, Eq b ) => a -> b -> Int +f2 a b = if ( a == a ) == ( b == b ) then 1 else 2 + +-- Make sure the rule LHS is of the form +-- +-- f2 @c @c d1 d2 and not f2 @c @c d d +{-# SPECIALISE f2 :: Eq c => c -> c -> Int #-} + +-------------------------------------------------------------------------------- + +f3 :: ( Eq a, forall x. Eq x => Eq ( f x ) ) => f a -> Bool +f3 z = z == z + +-- Discharge the quantified constraint but keep the 'Eq' constraint +{-# SPECIALISE f3 :: Eq c => [ c ] -> Bool #-} + +-- Discharge the 'Eq' constraint but keep the quantified constraint +{-# SPECIALISE f3 :: ( forall y. Eq y => Eq ( g y ) ) => g Int -> Bool #-} + +-------------------------------------------------------------------------------- + +f4 :: Monad m => a -> m a +f4 = return + +-- Check we can deal with locally quantified variables in constraints, +-- in this case 'Monad (ST s)'. +{-# SPECIALISE f4 :: b -> ST s b #-} + +-------------------------------------------------------------------------------- ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -502,6 +502,7 @@ test('T23491d', [extra_files(['T23491.hs']), grep_errmsg(r'Static argument')], m test('T23074', normal, compile, ['-O -ddump-rules']) test('T23272', [only_ways(['ghci']), extra_hc_opts('-fno-unoptimized-core-for-interpreter -O')], ghci_script, ['T23272.script']) test('T23567', [extra_files(['T23567A.hs'])], multimod_compile, ['T23567', '-O -v0']) +test('DsSpecPragmas', normal, compile, ['-O -ddump-rules']) # The -ddump-simpl of T22404 should have no let-bindings test('T22404', [only_ways(['optasm']), check_errmsg(r'let') ], compile, ['-ddump-simpl -dsuppress-uniques']) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -738,6 +738,7 @@ test('ExplicitSpecificityA1', normal, compile, ['']) test('ExplicitSpecificityA2', normal, compile, ['']) test('ExplicitSpecificity4', normal, compile, ['']) test('RuleEqs', normal, compile, ['']) +test('SpecPragmas', normal, compile, ['']) test('T17775-viewpats-a', normal, compile, ['']) test('T17775-viewpats-b', normal, compile_fail, ['']) test('T17775-viewpats-c', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/353cdf66424050f9d19ab4f646b5f369b8408254 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/353cdf66424050f9d19ab4f646b5f369b8408254 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 11:40:52 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Tue, 28 Jan 2025 06:40:52 -0500 Subject: [Git][ghc/ghc][wip/T24359] revert back to previous plan, adding tests etc Message-ID: <6798c244a1d01_38bf6a187900171a8@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: cf844ba6 by sheaf at 2025-01-28T12:40:37+01:00 revert back to previous plan, adding tests etc - - - - - 10 changed files: - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/Zonk/Type.hs - + testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -862,23 +862,8 @@ data TcSpecPrag , spe_bndrs :: [Var] -- ^ TyVars, EvVars, and Ids - , spe_expr :: LHsExpr GhcTc + , spe_call :: LHsExpr GhcTc -- ^ The type-checked specialise expression - , spe_rule_binds :: TcEvBinds - -- ^ "RULE RHS evidence bindings" - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig - , spe_call_evvars :: [Var] - -- ^ "specialised call evidence variables" - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig - , spe_call_wrapper :: HsWrapper - -- ^ wrapper for the specialised call - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig } noSpecPrags :: TcSpecPrags @@ -1027,7 +1012,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,9 +791,6 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -SLD TODO: rewrite this whole note, using the same example as -Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. - Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -930,22 +927,7 @@ dsSpec poly_rhs ( , spe_fn_id = poly_id , spe_inl = inl , spe_bndrs = bndrs - , spe_expr = the_call - - -- BLUE bindings (sd1 = d1, sd2 = d3) - , spe_rule_binds = EvBinds rule_evbinds - -- SLD TODO: I am not using the bindings anywhere, only the LHS EvVars - -- - -- On the face of it, this seems obviously incorrect (I am missing the - -- BLUE let bindings), but I don't have a case that triggers a problem, - -- while ADDING the BLUE bindings causes complications due to the fact - -- that the 'sd's are defined by simplifying the 'd's, without cloning, - -- so we naively get (loopy) recursive bindings. - - -- RED binders (d1,..., d4) - , spe_call_evvars = rule_evvars - -- HsWrapper for RED evidence binds (let d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... in) - , spe_call_wrapper = call_wrapper + , spe_call = the_call }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig = do { ds_call <- unsetGOptM Opt_EnableRewriteRules $ -- Note [Desugaring RULE left hand sides] @@ -953,69 +935,80 @@ dsSpec poly_rhs ( zapUnspecables $ dsLExpr the_call + -- Simplify the (desugared) call; see wrinkle (SP1) + -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let - -- See (SP1) in Note [Desugaring SPECIALISE pragmas] - simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - ; case collectSpecArgs poly_id core_call of { + ; let simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + ; case prepareSpecLHS poly_id bndrs core_call of { Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - Just rule_lhs_args -> - do { let - -- BLUE binders, in correspondence with the LHS of the blue bindings - spec_evvars = - map evBindVar (bagToList rule_evbinds) - -- Yes: rule_evbinds and not call_evbinds. - -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] - -- if this is not clear. - - -- The rule binders, including the RED binders d1, ..., d4 - rule_bndrs = scopedSort $ bndrs ++ rule_evvars - -- The specialised $sf binders, including the BLUE binders sd1, sd2 - spec_bndrs = scopedSort $ bndrs ++ spec_evvars - - ; dsHsWrapper call_wrapper $ \ wrap_call -> - do { let mk_spec_body fn_rhs = wrap_call $ mkCoreApps fn_rhs rule_lhs_args - ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id - , text "bndrs:" <+> ppr bndrs - , text "ds_call:" <+> ppr ds_call - , text "core_call:" <+> ppr core_call - , text "rule_evbinds:" <+> ppr rule_evbinds - , text (replicate 40 '-') - , text "rule_evvars:" <+> ppr rule_evvars - , text "spec_evvars:" <+> ppr spec_evvars - , text "rule_bndrs:" <+> ppr rule_bndrs - , text "spec_bndrs:" <+> ppr spec_bndrs - , text "rule_lhs_args:" <+> ppr rule_lhs_args - ]) - ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id rule_lhs_args - spec_bndrs mk_spec_body inl + ; return Nothing } ; + + Just (bndr_set, spec_const_binds, lhs_args) -> + + do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) + all_bndrs = bndr_set `unionVarSet` const_bndrs + -- all_bndrs: all binders in core_call that should be quantified - } } } } -dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" + -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] + rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) + spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs + + mk_spec_body fn_body = mkLets spec_const_binds $ + mkCoreApps fn_body lhs_args + + ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id + , text "bndrs" <+> ppr bndrs + , text "all_bndrs" <+> ppr all_bndrs + , text "const_bndrs" <+> ppr const_bndrs + , text "ds_call" <+> ppr ds_call + , text "core_call" <+> ppr core_call + , text "core_call fvs" <+> ppr (exprFreeVars core_call) + , text "spec_const_binds" <+> ppr spec_const_binds ]) + + ; finishSpecPrag poly_nm poly_rhs + rule_bndrs poly_id lhs_args + spec_bndrs mk_spec_body inl } } } -collectSpecArgs :: Id -> CoreExpr - -> Maybe [CoreExpr] +prepareSpecLHS :: Id -> [EvVar] -> CoreExpr + -> Maybe (VarSet, [CoreBind], [CoreExpr]) -- See (SP2) in Note [Desugaring SPECIALISE pragmas] --- SLD TODO: good example for this is simpl016 -collectSpecArgs poly_id the_call - = go the_call +prepareSpecLHS poly_id evs the_call + = go (mkVarSet evs) [] the_call where - go :: CoreExpr - -> Maybe [CoreExpr] - go (Cast e _) - = go e - go (Let _bind e) - = go e - go e + go :: VarSet -- Quantified variables, or dependencies thereof + -> [CoreBind] -- Reversed list of constant evidence bindings + -> CoreExpr + -> Maybe (IdSet, [CoreBind], [CoreExpr]) + go qevs acc (Cast e _) + = go qevs acc e + go qevs acc (Let bind e) + | not (all isDictId bndrs) -- A normal 'let' is too complicated + = Nothing + + | all (transfer_to_spec_rhs qevs) $ + rhssOfBind bind -- One of the `const_binds` + = go qevs (bind:acc) e + + | otherwise + = go (qevs `extendVarSetList` bndrs) acc e + where + bndrs = bindersOf bind + + go qevs acc e | (Var fun, args) <- collectArgs e = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just args + Just (qevs, reverse acc, args) | otherwise = Nothing + transfer_to_spec_rhs qevs rhs + = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) + where + is_quant_id v = isId v && v `elemVarSet` qevs + -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern -> [Var] -> (CoreExpr -> CoreExpr) -> InlinePragma -- Specialised form ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) +import GHC.Tc.Solver.Monad( runTcS, runTcSWithEvBinds, runTcSSpecPragWithEvBinds ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -722,93 +722,20 @@ demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} -We want to generate: - - RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). - f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True - = let - sd1 = d2 -- We will refer to these as the - sd2 = d4 -- "RULE RHS evidence bindings" - in - $sf @p @q sd1 sd2 x y z - $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) - = let(non-rec) f = in - let - d1 = $fEqList $fEqInt -- - d2 = sd1 -- We will refer to these as the - d3 = sd1 -- "specialised call evidence bindings" - d4 = sd2 -- - in - f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True - -Key observations: - - O1. - - The most important part is to **completely solve** the Eq [Int] constraint, - so that we specialise the call to 'f' to a known dictionary. Without that, - we're not doing any typeclass specialisation! - - O2. - - The `rule_bndrs`, over which the RULE is quantified, are all the variables - free in the call to `f`, /ignoring/ all dictionary simplification. Why? - Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. This is why, in the above example, - the rule binders are: - - rule_bndrs = @p @q - (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) - (x::[Int]) (y::p) (z::q). - - Note that: - - - We have separate binders for `d2` and `d3` even though they are - the same (Eq p) dictionary. Reason: we don't want to force them to be - visibly equal at the call site. - - - We don't assume that the dictionary for 'Eq [q]' was obtained - from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - - generate a RULE of the form - - forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - which is verboten (it matches on the structure of a dictionary), or - - - "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]), which is impossible to do in general. - - "Partially solving" the Eq [q] constraint by using the instance doesn't - buy us anything; we can't do anything useful with the information that an - Eq [q] dictionary is of the form ($fEqList ..). - - To achieve this, we solve the constraints that originated from typechecking - the expression to specialise, but in the special 'TcSSpecPrag' mode, which - ensures that: - - - We don't use instances (whether top-level instances or local instances - from quantified constraints), as those are not "reversible", - - EXCEPT that we **do** use the short-cut solver, so that we can fully - solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). - - O3. - - In the body of $sf, note that we: - - - define 'let(non-rec) f = ' - - refer to this shadowing 'f' in the last line of $sf - - This allows us to deal with functions that recursively call themselves, - as opposed to simply writing - - $sf ... = - let - in - () @p @p @[q] d1 d2 d3 d4 x y y [z] True +Example: + f :: forall a b. (Eq a, Eq b, Eq c) => a -> b -> c -> Bool -> blah + {-# SPECIALISE forall x y. f (x::Int) y y True #-} + -- y::p +We want to generate: + RULE forall @p (d1::Eq Int) (d2::Eq p) (d3::Eq p) (x::Int) (y::p). + f @Int @p @p d1 d2 d3 x y y True + = $sf @p d2 x y + $sf @p (d2::Eq p) (x::Int) (y::p) + = let d1 = $fEqInt + d3 = d2 + in @p @p @Int (d1::Eq p) (d2::Eq p) (d3::Eq p) x y y True Note that @@ -835,26 +762,46 @@ Note that spec_const_binds = let d1 = $fEqInt d3 = d2 -How it works: +This is done in three parts. + + A. Typechecker: `GHC.Tc.Gen.Sig.tcSpecPrag` + + (1) Typecheck the expression, capturing its constraints + + (2) Simplify these constraints, in special TcSSpecPrag mode + SLD TODO add more details. -* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results - into a `SpecPragE` record. Nothing very exciting happens here. + (3) Decide which constraints to quantify over, and quantify. -* `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any - free type variables of the LHS. See Note [Free tyvars on rule LHS] in - GHC.Tc.Zonk.Type. These weren't conveniently available earlier. + (4) Emit the residual (non-quantified) constraints, and wrap the + expression in a let binding for those constraints. -* `GHC.HsToCore.Binds.dsSpec` does the clever stuff: + (5) Store all the information in a 'SpecPragE' record, to be consumed + by the desugarer. - * Simplifies the expression. This is important because a type signature in the - expression will have led to type/dictionary abstractions/applications. Now - it should look like - let in f e1 e1 e3 + B. Zonker: `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` - * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards - the other dictionary bindings, and decomposes the call. + The zonker does a little extra work to collect any free type variables + of the LHS. See Note [Free tyvars on rule LHS] in GHC.Tc.Zonk.Type. + These weren't conveniently available earlier. - * Then it can build the RULE and specialised function. + C. Desugarer: `GHC.HsToCore.Binds.dsSpec`. + + This is where most of the clever stuff happens. See + Note [Desugaring SPECIALISE pragmas] in GHC.HsToCore.Binds for details, + but in brief: + + (1) Simplify the expression. This is important because a type signature in + the expression will have led to type/dictionary abstractions/applications. + Now it should look like + let in f d1 d2 d3 + + (2) `prepareSpecLHS` identifies the `spec_const_binds`, discards the other + dictionary bindings, and decomposes the call. + + (3) Then we build the specialised function $sf, and concoct a RULE + of the form: + forall @a @b d1 d2 d3. f d1 d2 d3 = $sf d1 d2 d3 Note [Handling old-form SPECIALISE pragmas] @@ -1027,84 +974,44 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm - ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) + ; traceTc "tcSpecPrag SpecSigE 1" (ppr nm $$ ppr spec_e) ; skol_info <- mkSkolemInfo skol_info_anon ; (rhs_tclvl, wanted, (rule_bndrs', (tc_spec_e, _rho))) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- (2) Perform unifications: - -- - clone the original constraints, - -- - simplify these cloned constraints - -- - zonk the original constraints - ; wanted_clone <- cloneWC wanted - ; _ <- setTcLevel rhs_tclvl $ - runTcS $ - solveWanteds wanted_clone - ; wanted <- liftZonkM $ zonkWC wanted - - -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted - ; let qevs = map ctEvId (bagToList quant_cts) - - -- (4) Emit the residual constraints. - ; non_quant_binds <- newTcEvBinds + -- (2) Simplify the constraints, in special TcSSpecPrag mode + ; ev_binds_var <- newTcEvBinds + ; wanted <- setTcLevel rhs_tclvl $ + runTcSSpecPragWithEvBinds ev_binds_var $ + solveWanteds wanted + + -- (3) Quantify over the constraints + ; qevs <- mapM newEvVar $ + ctsPreds $ + approximateWC False wanted + + -- (4) Emit the residual (non-quantified) constraints, + -- and wrap the expression in the evidence let bindings ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds + ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var emptyVarSet tv_bndrs qevs - non_quant_wc - - -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) - -- by solving "quant_cts" in the special TcSSpecPrag mode - ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ - vcat [ text "quant_cts:" <+> ppr quant_cts ] - ; (rule_rhs_wc, spec_call_binds) - <- setTcLevel rhs_tclvl $ - runTcSSpecPrag $ - solveWanteds (emptyWC { wc_simple = quant_cts }) - ; let rule_rhs_implics = wc_impl rule_rhs_wc - ; massertPpr (null rule_rhs_implics) $ - vcat [ text "tcSpecPrag: unexpected non-simple constraints" - , text "quant_cts:" <+> ppr quant_cts - , text "implics:" <+> ppr rule_rhs_implics ] - ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ - vcat [ text "quant_cts:" <+> ppr quant_cts - , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] - - -- (6) Figure out the blue bindings by solving the implication - -- [G] d1, d2, d3, d4 => [W] sd1, sd2 - ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ - vcat [ text "qevs:" <+> ppr qevs - , text "rule_rhs_wc:" <+> ppr rule_rhs_wc - ] - ; (implics, rule_rhs_binds) <- - buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs - qevs -- d1, d2, d3, d4 - rule_rhs_wc -- sd1, sd2 - ; emitImplications implics - - ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ + wanted + ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) tc_spec_e + + ; traceTc "tcSpecPrag:SpecSigE" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl - , text "non_quant:" <+> ppr non_quant_wc - , text (replicate 40 '-') - , text "spec_call_binds:" <+> ppr spec_call_binds - ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_inl = inl - , spe_bndrs = rule_bndrs' - , spe_expr = tc_spec_e - , spe_rule_binds = rule_rhs_binds - , spe_call_evvars = qevs - , spe_call_wrapper = - WpLet (TcEvBinds non_quant_binds) - <.> WpLet (EvBinds spec_call_binds) - }] } + , text "inl:" <+> ppr inl ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order + -- does not matter + , spe_call = lhs_call + , spe_inl = inl }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -3,6 +3,7 @@ -- | Solving Class constraints CDictCan module GHC.Tc.Solver.Dict ( solveDict, solveDictNC, + shortCutSolver, checkInstanceOK, matchLocalInst, chooseInstance, makeSuperClasses, mkStrictSuperClasses, @@ -771,7 +772,6 @@ wantShortCut dflags ev_w ev_i = -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs @@ -788,6 +788,12 @@ shortCutSolver :: DynFlags -> CtEvidence -- Work item -> TcS Bool -- True <=> success shortCutSolver dflags ev_w + | isIPLikePred (ctEvPred ev_w) + -- Not for implicit parameters (#18627) + -- TODO: we should probably also reject QCs, + -- e.g. ( forall a. Eq a => IP "ip" a ) + = return False + | otherwise = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -812,46 +818,51 @@ shortCutSolver dflags ev_w try_solve_from_instance -- See Note [Shortcut try_solve_from_instance] :: (EvBindMap, DictMap DictCt) -> CtEvidence -> MaybeT TcS (EvBindMap, DictMap DictCt) - try_solve_from_instance (ev_binds, solved_dicts) ev - | let pred = ctEvPred ev - , ClassPred cls tys <- classifyPredType pred - = do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w - ; lift $ warn_custom_warn_instance inst_res loc_w - -- See Note [Implementation of deprecated instances] - ; case inst_res of - OneInst { cir_new_theta = preds - , cir_mk_ev = mk_ev - , cir_canonical = canonical - , cir_what = what } - | safeOverlap what - , all isTyFamFree preds -- Note [Shortcut solving: type families] - -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls - , di_tys = tys, di_pend_sc = doNotExpand } - solved_dicts' = addSolvedDict dict_ct solved_dicts - -- solved_dicts': it is important that we add our goal - -- to the cache before we solve! Otherwise we may end - -- up in a loop while solving recursive dictionaries. - - ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) - ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred - ; lift $ checkReductionDepth loc' pred - - - ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds - -- Emit work for subgoals but use our local cache - -- so we can solve recursive dictionaries. - - ; let ev_tm = mk_ev (map getEvExpr evc_vs) - ev_binds' = extendEvBinds ev_binds $ - mkWantedEvBind (ctEvEvId ev) canonical ev_tm - - ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ - freshGoals evc_vs } - - _ -> mzero } + try_solve_from_instance (ev_binds, solved_dicts) ev = + case classifyPredType pred of + ClassPred cls tys -> + do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w + ; lift $ warn_custom_warn_instance inst_res loc_w + -- See Note [Implementation of deprecated instances] + ; case inst_res of + OneInst { cir_new_theta = preds + , cir_mk_ev = mk_ev + , cir_canonical = canonical + , cir_what = what } + | safeOverlap what + , all isTyFamFree preds -- Note [Shortcut solving: type families] + -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls + , di_tys = tys, di_pend_sc = doNotExpand } + solved_dicts' = addSolvedDict dict_ct solved_dicts + -- solved_dicts': it is important that we add our goal + -- to the cache before we solve! Otherwise we may end + -- up in a loop while solving recursive dictionaries. - | otherwise - = mzero + ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) + ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred + ; lift $ checkReductionDepth loc' pred + + + ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds + -- Emit work for subgoals but use our local cache + -- so we can solve recursive dictionaries. + + ; let ev_tm = mk_ev (map getEvExpr evc_vs) + ev_binds' = extendEvBinds ev_binds $ + mkWantedEvBind (ctEvEvId ev) canonical ev_tm + + ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ + freshGoals evc_vs } + + _other_inst_res -> mzero } + + ForAllPred _tvs _theta _body -> + -- TODO: implement short-cut solving for quantified constraints + mzero + + _other_pred -> mzero + where + pred = ctEvPred ev -- Use a local cache of solved dicts while emitting EvVars for new work @@ -874,13 +885,16 @@ shortCutSolver dflags ev_w tryInstances :: DictCt -> SolverStage () tryInstances dict_ct - = Stage $ do { inerts <- getInertSet - ; try_instances inerts dict_ct } + = Stage $ do { dflags <- getDynFlags + ; inerts <- getInertSet + ; mode <- getModeTcS + ; try_instances inerts dflags mode dict_ct } -try_instances :: InertSet -> DictCt -> TcS (StopOrContinue ()) +try_instances :: InertSet -> DynFlags -> TcSMode -> DictCt -> TcS (StopOrContinue ()) -- Try to use type-class instance declarations to simplify the constraint -try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls - , di_tys = xis }) +try_instances inerts dflags mode + work_item@(DictCt { di_ev = ev, di_cls = cls + , di_tys = xis }) | isGiven ev -- Never use instances for Given constraints = continueWith () -- See Note [No Given/Given fundeps] @@ -889,30 +903,26 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls = do { setEvBindIfWanted ev EvCanonical (ctEvTerm solved_ev) ; stopWith ev "Dict/Top (cached)" } + | TcSSpecPrag <- mode + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + = do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag DictCt: short-cut fully solved Wanted from instances" + else continueWith () + } + | otherwise -- Wanted, but not cached - = do { dflags <- getDynFlags - ; mode <- getModeTcS - ; case mode of - -- SLD TODO: pass mode to try_instances and have this as a top-level guard - -- In TcSSpecPrag mode, we only want to "fully solve" constraints - -- from instances. Making partial progress using instances is - -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. - { TcSSpecPrag -> - do { shortcut_worked <- shortCutSolver dflags ev - ; if shortcut_worked - then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" - else continueWith () - } - ; _ -> - do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc - ; case lkup_res of - OneInst { cir_what = what } - -> do { insertSafeOverlapFailureTcS what work_item - ; updSolvedDicts what work_item - ; chooseInstance ev lkup_res } - _ -> -- NoInstance or NotSure - -- We didn't solve it; so try functional dependencies - continueWith () } } } + = do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc + ; case lkup_res of + OneInst { cir_what = what } + -> do { insertSafeOverlapFailureTcS what work_item + ; updSolvedDicts what work_item + ; chooseInstance ev lkup_res } + _ -> -- NoInstance or NotSure + -- We didn't solve it; so try functional dependencies + continueWith () } where dict_loc = ctEvLoc ev ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -16,7 +16,7 @@ module GHC.Tc.Solver.Monad ( -- The TcS monad TcS, TcSMode(..), runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, - runTcSEqualities, runTcSSpecPrag, + runTcSEqualities, runTcSSpecPragWithEvBinds, failTcS, failWithTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, nestTcS, nestImplicTcS, setEvBindsTcS, emitImplicationTcS, emitTvImplicationTcS, @@ -994,6 +994,10 @@ csTraceTcM mk_doc runTcSWithEvBinds :: EvBindsVar -> TcS a -> TcM a runTcSWithEvBinds = runTcSWorker True TcSVanilla +-- | This version of 'runTcSWithEvBinds' uses the 'TcSSpecPrag' mode. +runTcSSpecPragWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSSpecPragWithEvBinds = runTcSWorker True TcSSpecPrag + runTcS :: TcS a -> TcM (a, EvBindMap) runTcS tcs = do { ev_binds_var <- TcM.newTcEvBinds @@ -1015,14 +1019,6 @@ runTcSEqualities thing_inside = do { ev_binds_var <- TcM.newNoTcEvBinds -- No bindings ; runTcSWorker True TcSVanilla ev_binds_var thing_inside } --- | This version of runTcS uses mode TcSSpecPrag -runTcSSpecPrag :: TcS a -> TcM (a, Bag EvBind) -runTcSSpecPrag thing_inside - = do { ev_binds_var <- TcM.newTcEvBinds - ; res <- runTcSWorker True TcSSpecPrag ev_binds_var thing_inside - ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var - ; return (res, evBindMapBinds ev_binds) } - -- | A variant of 'runTcS' that takes and returns an 'InertSet' for -- later resumption of the 'TcS' session. runTcSInerts :: InertSet -> TcS a -> TcM (a, InertSet) ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -1053,7 +1053,7 @@ solveCt (CNonCanonical ev) = solveNC ev solveCt (CIrredCan (IrredCt { ir_ev = ev })) = solveNC ev solveCt (CEqCan (EqCt { eq_ev = ev, eq_eq_rel = eq_rel - , eq_lhs = lhs, eq_rhs = rhs })) + , eq_lhs = lhs, eq_rhs = rhs })) = solveEquality ev eq_rel (canEqLHSType lhs) rhs solveCt (CQuantCan (QCI { qci_ev = ev, qci_pend_sc = pend_sc })) @@ -1211,8 +1211,25 @@ solveForAllNC ev tvs theta pred solveForAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType -> ExpansionFuel -> TcS (StopOrContinue Void) -- Precondition: already rewritten by inert set -solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) - tvs theta pred _fuel +solveForAll ev tvs theta pred fuel + = do { mode <- getModeTcS + ; solve_forAll ev tvs theta pred fuel mode + } + +solve_forAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType + -> ExpansionFuel -> TcSMode + -> TcS (StopOrContinue Void) +solve_forAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) + tvs theta pred fuel mode + | TcSSpecPrag <- mode + = do { dflags <- getDynFlags + ; shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag QC: short-cut fully solved Wanted from instances" + else do { addInertForAll qci + ; stopWith ev "TcSSpecPrag QC: Wanted kept as inert" } + } + | otherwise = -- See Note [Solving a Wanted forall-constraint] TcS.setSrcSpan (getCtLocEnvLoc $ ctLocEnv loc) $ -- This setSrcSpan is important: the emitImplicationTcS uses that @@ -1257,9 +1274,11 @@ solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_lo get_size pred = case classifyPredType pred of ClassPred cls tys -> pSizeClassPred cls tys _ -> pSizeType pred + qci = QCI { qci_ev = ev, qci_tvs = tvs + , qci_pred = pred, qci_pend_sc = fuel } -- See Note [Solving a Given forall-constraint] -solveForAll ev@(CtGiven {}) tvs _theta pred fuel +solve_forAll ev@(CtGiven {}) tvs _theta pred fuel _mode = do { addInertForAll qci ; stopWith ev "Given forall-constraint" } where ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,29 +854,20 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_expr = spec_e - , spe_rule_binds = rule_evbinds - , spe_call_evvars = call_evvars - , spe_call_wrapper = call_wrapper })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_call = spec_e })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> - runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> - runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> - runZonkBndrT (zonkCoFn call_wrapper) $ \ call_wrapper' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_expr = spec_e' - , spe_rule_binds = rule_evbinds' - , spe_call_evvars = call_evvars' - , spe_call_wrapper = call_wrapper' + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_call = spec_e' })) }} ===================================== testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE QuantifiedConstraints #-} + +module DsSpecPragmas where + +-- Some specialise pragmas that are difficult to generate the correct RULE for. + +-------------------------------------------------------------------------------- + +f1 :: ( Num a, Eq b ) => a -> b -> Int +f1 _ _ = 111 + +-- Make sure we don't generate a rule with an LHS of the form +-- +-- forall @e (d :: Eq e). f @[e] ($fEqList d) = ... +-- +-- but rather +-- +-- forall @e (d :: Eq [e]). f @[e] d = ... +{-# SPECIALISE f1 :: Eq [e] => Word -> [e] -> Int #-} + +-------------------------------------------------------------------------------- + +f2 :: ( Eq a, Eq b ) => a -> b -> Int +f2 a b = if ( a == a ) == ( b == b ) then 1 else 2 + +-- Make sure the rule LHS is of the form +-- +-- f2 @c @c d1 d2 and not f2 @c @c d d +{-# SPECIALISE f2 :: Eq c => c -> c -> Int #-} + +-------------------------------------------------------------------------------- + +f3 :: ( Eq a, forall x. Eq x => Eq ( f x ) ) => f a -> Bool +f3 z = z == z + +-- Discharge the quantified constraint but keep the 'Eq' constraint +{-# SPECIALISE f3 :: Eq c => [ c ] -> Bool #-} + +-- Discharge the 'Eq' constraint but keep the quantified constraint +{-# SPECIALISE f3 :: ( forall y. Eq y => Eq ( g y ) ) => g Int -> Bool #-} + +-------------------------------------------------------------------------------- + +f4 :: Monad m => a -> m a +f4 = return + +-- Check we can deal with locally quantified variables in constraints, +-- in this case 'Monad (ST s)'. +{-# SPECIALISE f4 :: b -> ST s b #-} + +-------------------------------------------------------------------------------- ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -502,6 +502,7 @@ test('T23491d', [extra_files(['T23491.hs']), grep_errmsg(r'Static argument')], m test('T23074', normal, compile, ['-O -ddump-rules']) test('T23272', [only_ways(['ghci']), extra_hc_opts('-fno-unoptimized-core-for-interpreter -O')], ghci_script, ['T23272.script']) test('T23567', [extra_files(['T23567A.hs'])], multimod_compile, ['T23567', '-O -v0']) +test('DsSpecPragmas', normal, compile, ['-O -ddump-rules']) # The -ddump-simpl of T22404 should have no let-bindings test('T22404', [only_ways(['optasm']), check_errmsg(r'let') ], compile, ['-ddump-simpl -dsuppress-uniques']) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -738,6 +738,7 @@ test('ExplicitSpecificityA1', normal, compile, ['']) test('ExplicitSpecificityA2', normal, compile, ['']) test('ExplicitSpecificity4', normal, compile, ['']) test('RuleEqs', normal, compile, ['']) +test('SpecPragmas', normal, compile, ['']) test('T17775-viewpats-a', normal, compile, ['']) test('T17775-viewpats-b', normal, compile_fail, ['']) test('T17775-viewpats-c', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf844ba6079c102879a56d7e4ae0f28d542cd3b2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf844ba6079c102879a56d7e4ae0f28d542cd3b2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 12:02:18 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Tue, 28 Jan 2025 07:02:18 -0500 Subject: [Git][ghc/ghc][wip/T24359] revert back to previous plan, adding tests etc Message-ID: <6798c74a9bcaf_38bf6a5c0c74195b2@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: b92e5784 by sheaf at 2025-01-28T13:02:00+01:00 revert back to previous plan, adding tests etc - - - - - 10 changed files: - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/Zonk/Type.hs - + testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -862,23 +862,8 @@ data TcSpecPrag , spe_bndrs :: [Var] -- ^ TyVars, EvVars, and Ids - , spe_expr :: LHsExpr GhcTc + , spe_call :: LHsExpr GhcTc -- ^ The type-checked specialise expression - , spe_rule_binds :: TcEvBinds - -- ^ "RULE RHS evidence bindings" - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig - , spe_call_evvars :: [Var] - -- ^ "specialised call evidence variables" - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig - , spe_call_wrapper :: HsWrapper - -- ^ wrapper for the specialised call - -- - -- See Note [Handling new-form SPECIALISE pragmas] - -- in GHC.Tc.Gen.Sig } noSpecPrags :: TcSpecPrags @@ -1027,7 +1012,7 @@ pprTcSpecPrags (SpecPrags ps) = vcat (map (ppr . unLoc) ps) instance Outputable TcSpecPrag where ppr (SpecPrag var _ inl) = text (extractSpecPragName $ inl_src inl) <+> pprSpec var (text "") inl - ppr (SpecPragE { spe_bndrs = bndrs, spe_expr = spec_e, spe_inl = inl }) + ppr (SpecPragE { spe_bndrs = bndrs, spe_call = spec_e, spe_inl = inl }) = text (extractSpecPragName $ inl_src inl) <+> hang (ppr bndrs) 2 (pprLExpr spec_e) ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -791,9 +791,6 @@ The restrictions are: Note [Desugaring SPECIALISE pragmas] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -SLD TODO: rewrite this whole note, using the same example as -Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig. - Suppose we have f :: forall p q. (Ord p, Eq q) => p -> q -> q, and a pragma {-# SPECIALISE forall x. f @[a] @[Int] x [3,4] #-} @@ -930,22 +927,7 @@ dsSpec poly_rhs ( , spe_fn_id = poly_id , spe_inl = inl , spe_bndrs = bndrs - , spe_expr = the_call - - -- BLUE bindings (sd1 = d1, sd2 = d3) - , spe_rule_binds = EvBinds rule_evbinds - -- SLD TODO: I am not using the bindings anywhere, only the LHS EvVars - -- - -- On the face of it, this seems obviously incorrect (I am missing the - -- BLUE let bindings), but I don't have a case that triggers a problem, - -- while ADDING the BLUE bindings causes complications due to the fact - -- that the 'sd's are defined by simplifying the 'd's, without cloning, - -- so we naively get (loopy) recursive bindings. - - -- RED binders (d1,..., d4) - , spe_call_evvars = rule_evvars - -- HsWrapper for RED evidence binds (let d1 = sd1, d2 = sd1, d3 = sd2, d4 = $fEqList ... in) - , spe_call_wrapper = call_wrapper + , spe_call = the_call }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig = do { ds_call <- unsetGOptM Opt_EnableRewriteRules $ -- Note [Desugaring RULE left hand sides] @@ -953,69 +935,80 @@ dsSpec poly_rhs ( zapUnspecables $ dsLExpr the_call + -- Simplify the (desugared) call; see wrinkle (SP1) + -- in Note [Desugaring SPECIALISE pragmas] ; dflags <- getDynFlags - ; let - -- See (SP1) in Note [Desugaring SPECIALISE pragmas] - simpl_opts = initSimpleOpts dflags - core_call = simpleOptExprNoInline simpl_opts ds_call - ; case collectSpecArgs poly_id core_call of { + ; let simpl_opts = initSimpleOpts dflags + core_call = simpleOptExprNoInline simpl_opts ds_call + + ; case prepareSpecLHS poly_id bndrs core_call of { Nothing -> do { diagnosticDs (DsRuleLhsTooComplicated ds_call core_call) - ; return Nothing } ; - Just rule_lhs_args -> - do { let - -- BLUE binders, in correspondence with the LHS of the blue bindings - spec_evvars = - map evBindVar (bagToList rule_evbinds) - -- Yes: rule_evbinds and not call_evbinds. - -- Re-read the example in Note [Handling new-form SPECIALISE pragmas] - -- if this is not clear. - - -- The rule binders, including the RED binders d1, ..., d4 - rule_bndrs = scopedSort $ bndrs ++ rule_evvars - -- The specialised $sf binders, including the BLUE binders sd1, sd2 - spec_bndrs = scopedSort $ bndrs ++ spec_evvars - - ; dsHsWrapper call_wrapper $ \ wrap_call -> - do { let mk_spec_body fn_rhs = wrap_call $ mkCoreApps fn_rhs rule_lhs_args - ; tracePm "dsSpec" (vcat [ text "poly_id:" <+> ppr poly_id - , text "bndrs:" <+> ppr bndrs - , text "ds_call:" <+> ppr ds_call - , text "core_call:" <+> ppr core_call - , text "rule_evbinds:" <+> ppr rule_evbinds - , text (replicate 40 '-') - , text "rule_evvars:" <+> ppr rule_evvars - , text "spec_evvars:" <+> ppr spec_evvars - , text "rule_bndrs:" <+> ppr rule_bndrs - , text "spec_bndrs:" <+> ppr spec_bndrs - , text "rule_lhs_args:" <+> ppr rule_lhs_args - ]) - ; finishSpecPrag poly_nm poly_rhs - rule_bndrs poly_id rule_lhs_args - spec_bndrs mk_spec_body inl + ; return Nothing } ; + + Just (bndr_set, spec_const_binds, lhs_args) -> + + do { let const_bndrs = mkVarSet (bindersOfBinds spec_const_binds) + all_bndrs = bndr_set `unionVarSet` const_bndrs + -- all_bndrs: all binders in core_call that should be quantified - } } } } -dsSpec _ (SpecPragE{}) = panic "dsSpec: SpecPragE not zonked" + -- rule_bndrs; see (SP3) in Note [Desugaring SPECIALISE pragmas] + rule_bndrs = scopedSort (exprsSomeFreeVarsList (`elemVarSet` all_bndrs) lhs_args) + spec_bndrs = filterOut (`elemVarSet` const_bndrs) rule_bndrs + + mk_spec_body fn_body = mkLets spec_const_binds $ + mkCoreApps fn_body lhs_args + + ; tracePm "dsSpec" (vcat [ text "poly_id" <+> ppr poly_id + , text "bndrs" <+> ppr bndrs + , text "all_bndrs" <+> ppr all_bndrs + , text "const_bndrs" <+> ppr const_bndrs + , text "ds_call" <+> ppr ds_call + , text "core_call" <+> ppr core_call + , text "core_call fvs" <+> ppr (exprFreeVars core_call) + , text "spec_const_binds" <+> ppr spec_const_binds ]) + + ; finishSpecPrag poly_nm poly_rhs + rule_bndrs poly_id lhs_args + spec_bndrs mk_spec_body inl } } } -collectSpecArgs :: Id -> CoreExpr - -> Maybe [CoreExpr] +prepareSpecLHS :: Id -> [EvVar] -> CoreExpr + -> Maybe (VarSet, [CoreBind], [CoreExpr]) -- See (SP2) in Note [Desugaring SPECIALISE pragmas] --- SLD TODO: good example for this is simpl016 -collectSpecArgs poly_id the_call - = go the_call +prepareSpecLHS poly_id evs the_call + = go (mkVarSet evs) [] the_call where - go :: CoreExpr - -> Maybe [CoreExpr] - go (Cast e _) - = go e - go (Let _bind e) - = go e - go e + go :: VarSet -- Quantified variables, or dependencies thereof + -> [CoreBind] -- Reversed list of constant evidence bindings + -> CoreExpr + -> Maybe (IdSet, [CoreBind], [CoreExpr]) + go qevs acc (Cast e _) + = go qevs acc e + go qevs acc (Let bind e) + | not (all isDictId bndrs) -- A normal 'let' is too complicated + = Nothing + + | all (transfer_to_spec_rhs qevs) $ + rhssOfBind bind -- One of the `const_binds` + = go qevs (bind:acc) e + + | otherwise + = go (qevs `extendVarSetList` bndrs) acc e + where + bndrs = bindersOf bind + + go qevs acc e | (Var fun, args) <- collectArgs e = assertPpr (fun == poly_id) (ppr fun $$ ppr poly_id) $ - Just args + Just (qevs, reverse acc, args) | otherwise = Nothing + transfer_to_spec_rhs qevs rhs + = isEmptyVarSet (exprSomeFreeVars is_quant_id rhs) + where + is_quant_id v = isId v && v `elemVarSet` qevs + -- See Note [Desugaring SPECIALISE pragmas] wrinkle (SP4) + finishSpecPrag :: Name -> CoreExpr -- RHS to specialise -> [Var] -> Id -> [CoreExpr] -- RULE LHS pattern -> [Var] -> (CoreExpr -> CoreExpr) -> InlinePragma -- Specialised form ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPrag ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPragWithEvBinds ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -722,93 +722,20 @@ demonstrate the subtle aspects of the implementation: f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} -We want to generate: - - RULE forall @t @p @q (d1::Eq [Proxy t]) (d2::Eq p) (d3::Eq p) (d4 :: Eq [q]) (x::[Proxy t]) (y::p) (z :: q). - f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True - = let - sd1 = d2 -- We will refer to these as the - sd2 = d4 -- "RULE RHS evidence bindings" - in - $sf @p @q sd1 sd2 x y z - $sf @t @p @q (sd1::Eq p) (sd2::Eq [q]) (x::[Proxy t]) (y::p) (z :: q) - = let(non-rec) f = in - let - d1 = $fEqList $fEqInt -- - d2 = sd1 -- We will refer to these as the - d3 = sd1 -- "specialised call evidence bindings" - d4 = sd2 -- - in - f @[Proxy t] @p @p @[q] d1 d2 d3 d4 x y y [z] True - -Key observations: - - O1. - - The most important part is to **completely solve** the Eq [Int] constraint, - so that we specialise the call to 'f' to a known dictionary. Without that, - we're not doing any typeclass specialisation! - - O2. - - The `rule_bndrs`, over which the RULE is quantified, are all the variables - free in the call to `f`, /ignoring/ all dictionary simplification. Why? - Because we want to make the rule maximally applicable; provided the types - match, the dictionaries should match. This is why, in the above example, - the rule binders are: - - rule_bndrs = @p @q - (d1::Eq [Int]) (d2::Eq p) (d3::Eq p) (d4::Eq [q]) - (x::[Int]) (y::p) (z::q). - - Note that: - - - We have separate binders for `d2` and `d3` even though they are - the same (Eq p) dictionary. Reason: we don't want to force them to be - visibly equal at the call site. - - - We don't assume that the dictionary for 'Eq [q]' was obtained - from the top-level instance 'instance Eq x => Eq [x]'. If we did that, - e.g. if we instead had a RULE binder (d4' :: Eq q), we would have to either: - - - generate a RULE of the form - - forall ... @q (d4' :: Eq q). f d1 d2 d3 ($fEqList d4') = ... - - which is verboten (it matches on the structure of a dictionary), or - - - "run the instance in reverse" to extract evidence for - (Eq q) from (Eq [q]), which is impossible to do in general. - - "Partially solving" the Eq [q] constraint by using the instance doesn't - buy us anything; we can't do anything useful with the information that an - Eq [q] dictionary is of the form ($fEqList ..). - - To achieve this, we solve the constraints that originated from typechecking - the expression to specialise, but in the special 'TcSSpecPrag' mode, which - ensures that: - - - We don't use instances (whether top-level instances or local instances - from quantified constraints), as those are not "reversible", - - EXCEPT that we **do** use the short-cut solver, so that we can fully - solve constraints such as the (Eq [Int]) constraint we mentioned in (O1). - - O3. - - In the body of $sf, note that we: - - - define 'let(non-rec) f = ' - - refer to this shadowing 'f' in the last line of $sf - - This allows us to deal with functions that recursively call themselves, - as opposed to simply writing - - $sf ... = - let - in - () @p @p @[q] d1 d2 d3 d4 x y y [z] True +Example: + f :: forall a b. (Eq a, Eq b, Eq c) => a -> b -> c -> Bool -> blah + {-# SPECIALISE forall x y. f (x::Int) y y True #-} + -- y::p +We want to generate: + RULE forall @p (d1::Eq Int) (d2::Eq p) (d3::Eq p) (x::Int) (y::p). + f @Int @p @p d1 d2 d3 x y y True + = $sf @p d2 x y + $sf @p (d2::Eq p) (x::Int) (y::p) + = let d1 = $fEqInt + d3 = d2 + in @p @p @Int (d1::Eq p) (d2::Eq p) (d3::Eq p) x y y True Note that @@ -835,26 +762,46 @@ Note that spec_const_binds = let d1 = $fEqInt d3 = d2 -How it works: +This is done in three parts. + + A. Typechecker: `GHC.Tc.Gen.Sig.tcSpecPrag` + + (1) Typecheck the expression, capturing its constraints + + (2) Simplify these constraints, in special TcSSpecPrag mode + SLD TODO add more details. -* SLD TODO outdated: `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results - into a `SpecPragE` record. Nothing very exciting happens here. + (3) Decide which constraints to quantify over, and quantify. -* `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any - free type variables of the LHS. See Note [Free tyvars on rule LHS] in - GHC.Tc.Zonk.Type. These weren't conveniently available earlier. + (4) Emit the residual (non-quantified) constraints, and wrap the + expression in a let binding for those constraints. -* `GHC.HsToCore.Binds.dsSpec` does the clever stuff: + (5) Store all the information in a 'SpecPragE' record, to be consumed + by the desugarer. - * Simplifies the expression. This is important because a type signature in the - expression will have led to type/dictionary abstractions/applications. Now - it should look like - let in f e1 e1 e3 + B. Zonker: `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` - * SLD TODO outdated: `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards - the other dictionary bindings, and decomposes the call. + The zonker does a little extra work to collect any free type variables + of the LHS. See Note [Free tyvars on rule LHS] in GHC.Tc.Zonk.Type. + These weren't conveniently available earlier. - * Then it can build the RULE and specialised function. + C. Desugarer: `GHC.HsToCore.Binds.dsSpec`. + + This is where most of the clever stuff happens. See + Note [Desugaring SPECIALISE pragmas] in GHC.HsToCore.Binds for details, + but in brief: + + (1) Simplify the expression. This is important because a type signature in + the expression will have led to type/dictionary abstractions/applications. + Now it should look like + let in f d1 d2 d3 + + (2) `prepareSpecLHS` identifies the `spec_const_binds`, discards the other + dictionary bindings, and decomposes the call. + + (3) Then we build the specialised function $sf, and concoct a RULE + of the form: + forall @a @b d1 d2 d3. f d1 d2 d3 = $sf d1 d2 d3 Note [Handling old-form SPECIALISE pragmas] @@ -1027,84 +974,44 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm - ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) + ; traceTc "tcSpecPrag SpecSigE 1" (ppr nm $$ ppr spec_e) ; skol_info <- mkSkolemInfo skol_info_anon ; (rhs_tclvl, wanted, (rule_bndrs', (tc_spec_e, _rho))) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- (2) Perform unifications: - -- - clone the original constraints, - -- - simplify these cloned constraints - -- - zonk the original constraints - ; wanted_clone <- cloneWC wanted - ; _ <- setTcLevel rhs_tclvl $ - runTcS $ - solveWanteds wanted_clone - ; wanted <- liftZonkM $ zonkWC wanted - - -- (3) Get the constraints we will quantify over (e.g. d1, ..., d4) - ; (quant_cts, non_quant_wc) <- getRuleQuantCts wanted - ; let qevs = map ctEvId (bagToList quant_cts) - - -- (4) Emit the residual constraints. - ; non_quant_binds <- newTcEvBinds + -- (2) Simplify the constraints, in special TcSSpecPrag mode + ; ev_binds_var <- newTcEvBinds + ; wanted <- setTcLevel rhs_tclvl $ + runTcSSpecPragWithEvBinds ev_binds_var $ + solveWanteds wanted + + -- (3) Quantify over the constraints + ; qevs <- mapM newEvVar $ + ctsPreds $ + approximateWC False wanted + + -- (4) Emit the residual (non-quantified) constraints, + -- and wrap the expression in the evidence let bindings ; let tv_bndrs = filter isTyVar rule_bndrs' - ; emitResidualConstraints rhs_tclvl skol_info_anon non_quant_binds + ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var emptyVarSet tv_bndrs qevs - non_quant_wc - - -- (5) Figure out sd1, sd2 (rule_rhs_wc) and the red bindings (rule_rhs_binds) - -- by solving "quant_cts" in the special TcSSpecPrag mode - ; traceTc "tcSpecPrag: computing BLUE Cts and RED bindings {" $ - vcat [ text "quant_cts:" <+> ppr quant_cts ] - ; (rule_rhs_wc, spec_call_binds) - <- setTcLevel rhs_tclvl $ - runTcSSpecPrag $ - solveWanteds (emptyWC { wc_simple = quant_cts }) - ; let rule_rhs_implics = wc_impl rule_rhs_wc - ; massertPpr (null rule_rhs_implics) $ - vcat [ text "tcSpecPrag: unexpected non-simple constraints" - , text "quant_cts:" <+> ppr quant_cts - , text "implics:" <+> ppr rule_rhs_implics ] - ; traceTc "tcSpecPrag: computed BLUE Cts and RED bindings }" $ - vcat [ text "quant_cts:" <+> ppr quant_cts - , text "blue Cts:" <+> ppr (wc_simple rule_rhs_wc) ] - - -- (6) Figure out the blue bindings by solving the implication - -- [G] d1, d2, d3, d4 => [W] sd1, sd2 - ; traceTc "tcSpecPrag:SpecSigE: computing BLUE bindings {" $ - vcat [ text "qevs:" <+> ppr qevs - , text "rule_rhs_wc:" <+> ppr rule_rhs_wc - ] - ; (implics, rule_rhs_binds) <- - buildImplicationFor rhs_tclvl skol_info_anon tv_bndrs - qevs -- d1, d2, d3, d4 - rule_rhs_wc -- sd1, sd2 - ; emitImplications implics - - ; traceTc "tcSpecPrag:SpecSigE: computed BLUE bindings }" $ + wanted + ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) tc_spec_e + + ; traceTc "tcSpecPrag:SpecSigE" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl - , text "non_quant:" <+> ppr non_quant_wc - , text (replicate 40 '-') - , text "spec_call_binds:" <+> ppr spec_call_binds - ] - - ; return [SpecPragE { spe_fn_nm = nm - , spe_fn_id = poly_id - , spe_inl = inl - , spe_bndrs = rule_bndrs' - , spe_expr = tc_spec_e - , spe_rule_binds = rule_rhs_binds - , spe_call_evvars = qevs - , spe_call_wrapper = - WpLet (TcEvBinds non_quant_binds) - <.> WpLet (EvBinds spec_call_binds) - }] } + , text "inl:" <+> ppr inl ] + + ; return [SpecPragE { spe_fn_nm = nm + , spe_fn_id = poly_id + , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order + -- does not matter + , spe_call = lhs_call + , spe_inl = inl }] } tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -3,6 +3,7 @@ -- | Solving Class constraints CDictCan module GHC.Tc.Solver.Dict ( solveDict, solveDictNC, + shortCutSolver, checkInstanceOK, matchLocalInst, chooseInstance, makeSuperClasses, mkStrictSuperClasses, @@ -771,7 +772,6 @@ wantShortCut dflags ev_w ev_i = -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs @@ -788,6 +788,12 @@ shortCutSolver :: DynFlags -> CtEvidence -- Work item -> TcS Bool -- True <=> success shortCutSolver dflags ev_w + | isIPLikePred (ctEvPred ev_w) + -- Not for implicit parameters (#18627) + -- TODO: we should probably also reject QCs, + -- e.g. ( forall a. Eq a => IP "ip" a ) + = return False + | otherwise = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -812,46 +818,51 @@ shortCutSolver dflags ev_w try_solve_from_instance -- See Note [Shortcut try_solve_from_instance] :: (EvBindMap, DictMap DictCt) -> CtEvidence -> MaybeT TcS (EvBindMap, DictMap DictCt) - try_solve_from_instance (ev_binds, solved_dicts) ev - | let pred = ctEvPred ev - , ClassPred cls tys <- classifyPredType pred - = do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w - ; lift $ warn_custom_warn_instance inst_res loc_w - -- See Note [Implementation of deprecated instances] - ; case inst_res of - OneInst { cir_new_theta = preds - , cir_mk_ev = mk_ev - , cir_canonical = canonical - , cir_what = what } - | safeOverlap what - , all isTyFamFree preds -- Note [Shortcut solving: type families] - -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls - , di_tys = tys, di_pend_sc = doNotExpand } - solved_dicts' = addSolvedDict dict_ct solved_dicts - -- solved_dicts': it is important that we add our goal - -- to the cache before we solve! Otherwise we may end - -- up in a loop while solving recursive dictionaries. - - ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) - ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred - ; lift $ checkReductionDepth loc' pred - - - ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds - -- Emit work for subgoals but use our local cache - -- so we can solve recursive dictionaries. - - ; let ev_tm = mk_ev (map getEvExpr evc_vs) - ev_binds' = extendEvBinds ev_binds $ - mkWantedEvBind (ctEvEvId ev) canonical ev_tm - - ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ - freshGoals evc_vs } - - _ -> mzero } + try_solve_from_instance (ev_binds, solved_dicts) ev = + case classifyPredType pred of + ClassPred cls tys -> + do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w + ; lift $ warn_custom_warn_instance inst_res loc_w + -- See Note [Implementation of deprecated instances] + ; case inst_res of + OneInst { cir_new_theta = preds + , cir_mk_ev = mk_ev + , cir_canonical = canonical + , cir_what = what } + | safeOverlap what + , all isTyFamFree preds -- Note [Shortcut solving: type families] + -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls + , di_tys = tys, di_pend_sc = doNotExpand } + solved_dicts' = addSolvedDict dict_ct solved_dicts + -- solved_dicts': it is important that we add our goal + -- to the cache before we solve! Otherwise we may end + -- up in a loop while solving recursive dictionaries. - | otherwise - = mzero + ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) + ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred + ; lift $ checkReductionDepth loc' pred + + + ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds + -- Emit work for subgoals but use our local cache + -- so we can solve recursive dictionaries. + + ; let ev_tm = mk_ev (map getEvExpr evc_vs) + ev_binds' = extendEvBinds ev_binds $ + mkWantedEvBind (ctEvEvId ev) canonical ev_tm + + ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ + freshGoals evc_vs } + + _other_inst_res -> mzero } + + ForAllPred _tvs _theta _body -> + -- TODO: implement short-cut solving for quantified constraints + mzero + + _other_pred -> mzero + where + pred = ctEvPred ev -- Use a local cache of solved dicts while emitting EvVars for new work @@ -874,13 +885,16 @@ shortCutSolver dflags ev_w tryInstances :: DictCt -> SolverStage () tryInstances dict_ct - = Stage $ do { inerts <- getInertSet - ; try_instances inerts dict_ct } + = Stage $ do { dflags <- getDynFlags + ; inerts <- getInertSet + ; mode <- getModeTcS + ; try_instances inerts dflags mode dict_ct } -try_instances :: InertSet -> DictCt -> TcS (StopOrContinue ()) +try_instances :: InertSet -> DynFlags -> TcSMode -> DictCt -> TcS (StopOrContinue ()) -- Try to use type-class instance declarations to simplify the constraint -try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls - , di_tys = xis }) +try_instances inerts dflags mode + work_item@(DictCt { di_ev = ev, di_cls = cls + , di_tys = xis }) | isGiven ev -- Never use instances for Given constraints = continueWith () -- See Note [No Given/Given fundeps] @@ -889,30 +903,26 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls = do { setEvBindIfWanted ev EvCanonical (ctEvTerm solved_ev) ; stopWith ev "Dict/Top (cached)" } + | TcSSpecPrag <- mode + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + = do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag DictCt: short-cut fully solved Wanted from instances" + else continueWith () + } + | otherwise -- Wanted, but not cached - = do { dflags <- getDynFlags - ; mode <- getModeTcS - ; case mode of - -- SLD TODO: pass mode to try_instances and have this as a top-level guard - -- In TcSSpecPrag mode, we only want to "fully solve" constraints - -- from instances. Making partial progress using instances is - -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. - { TcSSpecPrag -> - do { shortcut_worked <- shortCutSolver dflags ev - ; if shortcut_worked - then stopWith ev "TcSSpecPrag: short-cut fully solved from instances" - else continueWith () - } - ; _ -> - do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc - ; case lkup_res of - OneInst { cir_what = what } - -> do { insertSafeOverlapFailureTcS what work_item - ; updSolvedDicts what work_item - ; chooseInstance ev lkup_res } - _ -> -- NoInstance or NotSure - -- We didn't solve it; so try functional dependencies - continueWith () } } } + = do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc + ; case lkup_res of + OneInst { cir_what = what } + -> do { insertSafeOverlapFailureTcS what work_item + ; updSolvedDicts what work_item + ; chooseInstance ev lkup_res } + _ -> -- NoInstance or NotSure + -- We didn't solve it; so try functional dependencies + continueWith () } where dict_loc = ctEvLoc ev ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -16,7 +16,7 @@ module GHC.Tc.Solver.Monad ( -- The TcS monad TcS, TcSMode(..), runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, - runTcSEqualities, runTcSSpecPrag, + runTcSEqualities, runTcSSpecPragWithEvBinds, failTcS, failWithTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, nestTcS, nestImplicTcS, setEvBindsTcS, emitImplicationTcS, emitTvImplicationTcS, @@ -994,6 +994,10 @@ csTraceTcM mk_doc runTcSWithEvBinds :: EvBindsVar -> TcS a -> TcM a runTcSWithEvBinds = runTcSWorker True TcSVanilla +-- | This version of 'runTcSWithEvBinds' uses the 'TcSSpecPrag' mode. +runTcSSpecPragWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSSpecPragWithEvBinds = runTcSWorker True TcSSpecPrag + runTcS :: TcS a -> TcM (a, EvBindMap) runTcS tcs = do { ev_binds_var <- TcM.newTcEvBinds @@ -1015,14 +1019,6 @@ runTcSEqualities thing_inside = do { ev_binds_var <- TcM.newNoTcEvBinds -- No bindings ; runTcSWorker True TcSVanilla ev_binds_var thing_inside } --- | This version of runTcS uses mode TcSSpecPrag -runTcSSpecPrag :: TcS a -> TcM (a, Bag EvBind) -runTcSSpecPrag thing_inside - = do { ev_binds_var <- TcM.newTcEvBinds - ; res <- runTcSWorker True TcSSpecPrag ev_binds_var thing_inside - ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var - ; return (res, evBindMapBinds ev_binds) } - -- | A variant of 'runTcS' that takes and returns an 'InertSet' for -- later resumption of the 'TcS' session. runTcSInerts :: InertSet -> TcS a -> TcM (a, InertSet) ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -1053,7 +1053,7 @@ solveCt (CNonCanonical ev) = solveNC ev solveCt (CIrredCan (IrredCt { ir_ev = ev })) = solveNC ev solveCt (CEqCan (EqCt { eq_ev = ev, eq_eq_rel = eq_rel - , eq_lhs = lhs, eq_rhs = rhs })) + , eq_lhs = lhs, eq_rhs = rhs })) = solveEquality ev eq_rel (canEqLHSType lhs) rhs solveCt (CQuantCan (QCI { qci_ev = ev, qci_pend_sc = pend_sc })) @@ -1211,8 +1211,25 @@ solveForAllNC ev tvs theta pred solveForAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType -> ExpansionFuel -> TcS (StopOrContinue Void) -- Precondition: already rewritten by inert set -solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) - tvs theta pred _fuel +solveForAll ev tvs theta pred fuel + = do { mode <- getModeTcS + ; solve_forAll ev tvs theta pred fuel mode + } + +solve_forAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType + -> ExpansionFuel -> TcSMode + -> TcS (StopOrContinue Void) +solve_forAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) + tvs theta pred fuel mode + | TcSSpecPrag <- mode + = do { dflags <- getDynFlags + ; shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag QC: short-cut fully solved Wanted from instances" + else do { addInertForAll qci + ; stopWith ev "TcSSpecPrag QC: Wanted kept as inert" } + } + | otherwise = -- See Note [Solving a Wanted forall-constraint] TcS.setSrcSpan (getCtLocEnvLoc $ ctLocEnv loc) $ -- This setSrcSpan is important: the emitImplicationTcS uses that @@ -1257,9 +1274,11 @@ solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_lo get_size pred = case classifyPredType pred of ClassPred cls tys -> pSizeClassPred cls tys _ -> pSizeType pred + qci = QCI { qci_ev = ev, qci_tvs = tvs + , qci_pred = pred, qci_pend_sc = fuel } -- See Note [Solving a Given forall-constraint] -solveForAll ev@(CtGiven {}) tvs _theta pred fuel +solve_forAll ev@(CtGiven {}) tvs _theta pred fuel _mode = do { addInertForAll qci ; stopWith ev "Given forall-constraint" } where ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -854,29 +854,20 @@ zonkLTcSpecPrags ps = do { co_fn' <- don'tBind $ zonkCoFn co_fn ; id' <- zonkIdOcc id ; return (L loc (SpecPrag id' co_fn' inl)) } - zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_expr = spec_e - , spe_rule_binds = rule_evbinds - , spe_call_evvars = call_evvars - , spe_call_wrapper = call_wrapper })) + zonk_prag (L loc prag@(SpecPragE { spe_fn_id = poly_id + , spe_bndrs = bndrs + , spe_call = spec_e })) = do { poly_id' <- zonkIdOcc poly_id ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> - runZonkBndrT (zonkCoreBndrsX call_evvars) $ \ call_evvars' -> - runZonkBndrT (zonkTcEvBinds rule_evbinds) $ \ rule_evbinds' -> - runZonkBndrT (zonkCoFn call_wrapper) $ \ call_wrapper' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_expr = spec_e' - , spe_rule_binds = rule_evbinds' - , spe_call_evvars = call_evvars' - , spe_call_wrapper = call_wrapper' + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_call = spec_e' })) }} ===================================== testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE QuantifiedConstraints #-} + +module DsSpecPragmas where + +-- Some specialise pragmas that are difficult to generate the correct RULE for. + +-------------------------------------------------------------------------------- + +f1 :: ( Num a, Eq b ) => a -> b -> Int +f1 _ _ = 111 + +-- Make sure we don't generate a rule with an LHS of the form +-- +-- forall @e (d :: Eq e). f @[e] ($fEqList d) = ... +-- +-- but rather +-- +-- forall @e (d :: Eq [e]). f @[e] d = ... +{-# SPECIALISE f1 :: Eq [e] => Word -> [e] -> Int #-} + +-------------------------------------------------------------------------------- + +f2 :: ( Eq a, Eq b ) => a -> b -> Int +f2 a b = if ( a == a ) == ( b == b ) then 1 else 2 + +-- Make sure the rule LHS is of the form +-- +-- f2 @c @c d1 d2 and not f2 @c @c d d +{-# SPECIALISE f2 :: Eq c => c -> c -> Int #-} + +-------------------------------------------------------------------------------- + +f3 :: ( Eq a, forall x. Eq x => Eq ( f x ) ) => f a -> Bool +f3 z = z == z + +-- Discharge the quantified constraint but keep the 'Eq' constraint +{-# SPECIALISE f3 :: Eq c => [ c ] -> Bool #-} + +-- Discharge the 'Eq' constraint but keep the quantified constraint +{-# SPECIALISE f3 :: ( forall y. Eq y => Eq ( g y ) ) => g Int -> Bool #-} + +-------------------------------------------------------------------------------- + +f4 :: Monad m => a -> m a +f4 = return + +-- Check we can deal with locally quantified variables in constraints, +-- in this case 'Monad (ST s)'. +{-# SPECIALISE f4 :: b -> ST s b #-} + +-------------------------------------------------------------------------------- ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -502,6 +502,7 @@ test('T23491d', [extra_files(['T23491.hs']), grep_errmsg(r'Static argument')], m test('T23074', normal, compile, ['-O -ddump-rules']) test('T23272', [only_ways(['ghci']), extra_hc_opts('-fno-unoptimized-core-for-interpreter -O')], ghci_script, ['T23272.script']) test('T23567', [extra_files(['T23567A.hs'])], multimod_compile, ['T23567', '-O -v0']) +test('DsSpecPragmas', normal, compile, ['-O -ddump-rules']) # The -ddump-simpl of T22404 should have no let-bindings test('T22404', [only_ways(['optasm']), check_errmsg(r'let') ], compile, ['-ddump-simpl -dsuppress-uniques']) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -738,6 +738,7 @@ test('ExplicitSpecificityA1', normal, compile, ['']) test('ExplicitSpecificityA2', normal, compile, ['']) test('ExplicitSpecificity4', normal, compile, ['']) test('RuleEqs', normal, compile, ['']) +test('SpecPragmas', normal, compile, ['']) test('T17775-viewpats-a', normal, compile, ['']) test('T17775-viewpats-b', normal, compile_fail, ['']) test('T17775-viewpats-c', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b92e57841019d5339acd35d9c1f77435efcb7cf6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b92e57841019d5339acd35d9c1f77435efcb7cf6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 12:03:07 2025 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Tue, 28 Jan 2025 07:03:07 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/int-index/ghc-9.12-backport-25182-25174 Message-ID: <6798c77b251b9_38bf6a79cc3c20485@gitlab.mail> Vladislav Zavialov pushed new branch wip/int-index/ghc-9.12-backport-25182-25174 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/int-index/ghc-9.12-backport-25182-25174 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 12:18:50 2025 From: gitlab at gitlab.haskell.org (Zubin (@wz1000)) Date: Tue, 28 Jan 2025 07:18:50 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/25687 Message-ID: <6798cb2a4c5f4_38bf6ab6c484232f1@gitlab.mail> Zubin pushed new branch wip/25687 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/25687 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 12:53:52 2025 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Tue, 28 Jan 2025 07:53:52 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/int-index/ghc-9.10-backport-25182-25174 Message-ID: <6798d360c6dd6_38bf6a11b044435290@gitlab.mail> Vladislav Zavialov pushed new branch wip/int-index/ghc-9.10-backport-25182-25174 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/int-index/ghc-9.10-backport-25182-25174 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 13:11:52 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Tue, 28 Jan 2025 08:11:52 -0500 Subject: [Git][ghc/ghc][wip/T24359] WIP: original approach but with TcSSpecPrag Message-ID: <6798d798c95_38bf6a181c8783902f@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 2ffae48c by sheaf at 2025-01-28T14:11:07+01:00 WIP: original approach but with TcSSpecPrag - - - - - 14 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs - + testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -824,7 +824,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +835,36 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_call :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -823,7 +823,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,14 +921,19 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_call = the_call + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig - = do { ds_call <- zapUnspecables $ -- zapUnspecables: see - dsLExpr the_call -- Note [Desugaring RULE left hand sides] + = do { ds_call <- unsetGOptM Opt_EnableRewriteRules $ -- Note [Desugaring RULE left hand sides] + unsetWOptM Opt_WarnIdentities $ + zapUnspecables $ + dsLExpr the_call -- Simplify the (desugared) call; see wrinkle (SP1) -- in Note [Desugaring SPECIALISE pragmas] @@ -1054,7 +1059,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because @@ -1077,7 +1082,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args | all is_nop_arg rule_args, not (isInlinePragma spec_inl) -- The specialisation does nothing. - -- But don't compliain if it is SPECIALISE INLINE (#4444) + -- But don't complain if it is SPECIALISE INLINE (#4444) = Just UselessSpecialiseNoSpecialisation | otherwise ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS, runTcSWithEvBinds ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPragWithEvBinds ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -50,7 +50,7 @@ import GHC.Tc.Utils.Instantiate( topInstantiate, tcInstTypeBndrs ) import GHC.Tc.Utils.Env import GHC.Tc.Types.Origin -import GHC.Tc.Types.Evidence( HsWrapper(..), (<.>), TcEvBinds(..) ) +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Constraint import GHC.Tc.Zonk.TcType @@ -703,17 +703,24 @@ Note [Handling new-form SPECIALISE pragmas] New-form SPECIALISE pragmas are described by GHC Proposal #493. The pragma takes the form of a function application, possibly with intervening -parens and type signatures, with a variable at the head. It may have rule -for-alls at the top. e.g. +parens and type signatures, with a variable at the head: {-# SPECIALISE f1 @Int 3 #-} - {-# SPECIALISE forall x xs. f2 (x:xs) #-} - {-# SPECIALISE f3 :: Int -> Int #-} - {-# SPECIALISE (f4 :: Int -> Int) 5 #-} + {-# SPECIALISE f2 :: Int -> Int #-} + {-# SPECIALISE (f3 :: Int -> Int) 5 #-} + +It may also have rule for-alls at the top, e.g. + + {-# SPECIALISE forall x xs. f4 (x:xs) #-} {-# SPECIALISE forall a. forall x xs. f5 @a @a (x:xs) #-} See `GHC.Rename.Bind.checkSpecESigShape` for the shape-check. +We are going to use the following (perhaps somewhat contrived) example to +demonstrate the subtle aspects of the implementation: + + f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} Example: f :: forall a b. (Eq a, Eq b, Eq c) => a -> b -> c -> Bool -> blah @@ -755,26 +762,46 @@ Note that spec_const_binds = let d1 = $fEqInt d3 = d2 -How it works: +This is done in three parts. + + A. Typechecker: `GHC.Tc.Gen.Sig.tcSpecPrag` + + (1) Typecheck the expression, capturing its constraints + + (2) Simplify these constraints, in special TcSSpecPrag mode + SLD TODO add more details. + + (3) Decide which constraints to quantify over, and quantify. -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results - into a `SpecPragE` record. Nothing very exciting happens here. + (4) Emit the residual (non-quantified) constraints, and wrap the + expression in a let binding for those constraints. -* `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any - free type variables of the LHS. See Note [Free tyvars on rule LHS] in - GHC.Tc.Zonk.Type. These weren't conveniently available earlier. + (5) Store all the information in a 'SpecPragE' record, to be consumed + by the desugarer. -* `GHC.HsToCore.Binds.dsSpec` does the clever stuff: + B. Zonker: `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` - * Simplifies the expression. This is important because a type signature in the - expression will have led to type/dictionary abstractions/applications. Now - it should look like - let in f e1 e1 e3 + The zonker does a little extra work to collect any free type variables + of the LHS. See Note [Free tyvars on rule LHS] in GHC.Tc.Zonk.Type. + These weren't conveniently available earlier. - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards - the other dictionary bindings, and decomposes the call. + C. Desugarer: `GHC.HsToCore.Binds.dsSpec`. - * Then it can build the RULE and specialised function. + This is where most of the clever stuff happens. See + Note [Desugaring SPECIALISE pragmas] in GHC.HsToCore.Binds for details, + but in brief: + + (1) Simplify the expression. This is important because a type signature in + the expression will have led to type/dictionary abstractions/applications. + Now it should look like + let in f d1 d2 d3 + + (2) `prepareSpecLHS` identifies the `spec_const_binds`, discards the other + dictionary bindings, and decomposes the call. + + (3) Then we build the specialised function $sf, and concoct a RULE + of the form: + forall @a @b d1 d2 d3. f d1 d2 d3 = $sf d1 d2 d3 Note [Handling old-form SPECIALISE pragmas] @@ -944,38 +971,41 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) - = do { -- Typecheck the expression, spec_e, capturing its constraints + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] + = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm - ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) + ; traceTc "tcSpecPrag SpecSigE 1" (ppr nm $$ ppr spec_e) ; skol_info <- mkSkolemInfo skol_info_anon - ; (rhs_tclvl, wanted, (rule_bndrs', (spec_e', _rho))) + ; (rhs_tclvl, wanted, (rule_bndrs', (tc_spec_e, _rho))) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- Simplify the constraints + -- (2) Simplify the constraints, in special TcSSpecPrag mode ; ev_binds_var <- newTcEvBinds ; wanted <- setTcLevel rhs_tclvl $ - runTcSWithEvBinds ev_binds_var $ + runTcSSpecPragWithEvBinds ev_binds_var $ solveWanteds wanted - -- Quantify over the the constraints + -- (3) Quantify over the constraints ; qevs <- mapM newEvVar $ ctsPreds $ approximateWC False wanted + -- (4) Emit the residual (non-quantified) constraints, + -- and wrap the expression in the evidence let bindings ; let tv_bndrs = filter isTyVar rule_bndrs' ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var emptyVarSet tv_bndrs qevs wanted + ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) tc_spec_e ; traceTc "tcSpecPrag:SpecSigE" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs - , text "spec_e:" <+> ppr spec_e' + , text "spec_e:" <+> ppr tc_spec_e , text "inl:" <+> ppr inl ] - ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) spec_e' ; return [SpecPragE { spe_fn_nm = nm , spe_fn_id = poly_id , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order @@ -1414,9 +1444,9 @@ in `getRuleQuantCts`. Why not? * Equality constraints are unboxed, and that leads to complications For example equality constraints from the LHS will emit coercion hole Wanteds. These don't have a name, so we can't quantify over them directly. - Instead, in `mk_one` in `getRuleQuantCts` in we'd have to invent a new EvVar - for the coercion, fill the hole with the invented EvVar, and then quantify - over the EvVar. Here is old code from `mk_one` + Instead, in `getRuleQuantCts`, we'd have to invent a new EvVar for the + coercion, fill the hole with the invented EvVar, and then quantify over the + EvVar. Here is old code from `mk_one` do { ev_id <- newEvVar pred ; fillCoercionHole hole (mkCoVarCo ev_id) ; return ev_id } @@ -1483,7 +1513,8 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; lhs_wanted <- liftZonkM $ zonkWC lhs_wanted -- Note [The SimplifyRule Plan] step 3 - ; (quant_evs, residual_lhs_wanted) <-getRuleQuantCts lhs_wanted + ; (quant_cts, residual_lhs_wanted) <- getRuleQuantCts lhs_wanted + ; let quant_evs = map ctEvId (bagToList quant_cts) ; traceTc "simplifyRule" $ vcat [ text "LHS of rule" <+> doubleQuotes (ftext name) @@ -1496,7 +1527,7 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; return (quant_evs, residual_lhs_wanted, dont_default) } -getRuleQuantCts :: WantedConstraints -> TcM ([EvVar], WantedConstraints) +getRuleQuantCts :: WantedConstraints -> TcM (Cts, WantedConstraints) -- Extract all the constraints that we can quantify over, -- also returning the depleted WantedConstraints -- @@ -1504,20 +1535,17 @@ getRuleQuantCts :: WantedConstraints -> TcM ([EvVar], WantedConstraints) -- and attempt to solve them from the quantified constraints. Instead -- we /partition/ the WantedConstraints into ones to quantify and ones -- we can't quantify. We could use approximateWC instead, and leave --- `wanted` unchanged; but then we'd have clone fresh binders and +-- `wanted` unchanged; but then we'd have to clone fresh binders and -- generate silly identity bindings. Seems more direct to do this. --- Probably not a big eal wither way. +-- Probably not a big deal wither way. -- -- NB: we must look inside implications, because with -- -fdefer-type-errors we generate implications rather eagerly; -- see GHC.Tc.Utils.Unify.implicationNeeded. Not doing so caused #14732. getRuleQuantCts wc - = do { quant_evs <- mapM mk_one (bagToList quant_cts) - ; return (quant_evs, residual_wc) } + = return $ float_wc emptyVarSet wc where - (quant_cts, residual_wc) = float_wc emptyVarSet wc - float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_errors = errs }) = ( simple_yes `andCts` implic_yes @@ -1542,17 +1570,6 @@ getRuleQuantCts wc EqPred {} -> False -- Note [RULE quantification over equalities] _ -> tyCoVarsOfCt ct `disjointVarSet` skol_tvs - mk_one :: Ct -> TcM EvVar - mk_one ct - | CtWanted { ctev_dest = dest } <- ctEvidence ct - , EvVarDest ev_id <- dest - -- HoleDest can't happen because we don't quantify - -- over EqPred: See rule_quant_ct above - = return ev_id - - | otherwise - = pprPanic "getRuleQuantCts" (ppr ct) - {- Note [Quantifying over equalities in RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Solver/Default.hs ===================================== @@ -973,7 +973,7 @@ tryDefaultGroup wanteds (Proposal assignments) errInvalidDefaultedTyVar :: WantedConstraints -> Proposal -> NonEmpty TcTyVar -> TcS () errInvalidDefaultedTyVar wanteds (Proposal assignments) problematic_tvs - = failTcS $ TcRnInvalidDefaultedTyVar tidy_wanteds tidy_assignments tidy_problems + = failWithTcS $ TcRnInvalidDefaultedTyVar tidy_wanteds tidy_assignments tidy_problems where proposal_tvs = concatMap (\(tv, ty) -> tv : tyCoVarsOfTypeList ty) assignments tidy_env = tidyFreeTyCoVars emptyTidyEnv $ proposal_tvs ++ NE.toList problematic_tvs ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -3,6 +3,7 @@ -- | Solving Class constraints CDictCan module GHC.Tc.Solver.Dict ( solveDict, solveDictNC, + shortCutSolver, checkInstanceOK, matchLocalInst, chooseInstance, makeSuperClasses, mkStrictSuperClasses, @@ -727,7 +728,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +758,42 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w + | isIPLikePred (ctEvPred ev_w) + -- Not for implicit parameters (#18627) + -- TODO: we should probably also reject QCs, + -- e.g. ( forall a. Eq a => IP "ip" a ) + = return False + | otherwise = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +809,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -806,46 +818,51 @@ shortCutSolver dflags ev_w ev_i try_solve_from_instance -- See Note [Shortcut try_solve_from_instance] :: (EvBindMap, DictMap DictCt) -> CtEvidence -> MaybeT TcS (EvBindMap, DictMap DictCt) - try_solve_from_instance (ev_binds, solved_dicts) ev - | let pred = ctEvPred ev - , ClassPred cls tys <- classifyPredType pred - = do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w - ; lift $ warn_custom_warn_instance inst_res loc_w - -- See Note [Implementation of deprecated instances] - ; case inst_res of - OneInst { cir_new_theta = preds - , cir_mk_ev = mk_ev - , cir_canonical = canonical - , cir_what = what } - | safeOverlap what - , all isTyFamFree preds -- Note [Shortcut solving: type families] - -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls - , di_tys = tys, di_pend_sc = doNotExpand } - solved_dicts' = addSolvedDict dict_ct solved_dicts - -- solved_dicts': it is important that we add our goal - -- to the cache before we solve! Otherwise we may end - -- up in a loop while solving recursive dictionaries. - - ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) - ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred - ; lift $ checkReductionDepth loc' pred - - - ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds - -- Emit work for subgoals but use our local cache - -- so we can solve recursive dictionaries. - - ; let ev_tm = mk_ev (map getEvExpr evc_vs) - ev_binds' = extendEvBinds ev_binds $ - mkWantedEvBind (ctEvEvId ev) canonical ev_tm - - ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ - freshGoals evc_vs } - - _ -> mzero } + try_solve_from_instance (ev_binds, solved_dicts) ev = + case classifyPredType pred of + ClassPred cls tys -> + do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w + ; lift $ warn_custom_warn_instance inst_res loc_w + -- See Note [Implementation of deprecated instances] + ; case inst_res of + OneInst { cir_new_theta = preds + , cir_mk_ev = mk_ev + , cir_canonical = canonical + , cir_what = what } + | safeOverlap what + , all isTyFamFree preds -- Note [Shortcut solving: type families] + -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls + , di_tys = tys, di_pend_sc = doNotExpand } + solved_dicts' = addSolvedDict dict_ct solved_dicts + -- solved_dicts': it is important that we add our goal + -- to the cache before we solve! Otherwise we may end + -- up in a loop while solving recursive dictionaries. - | otherwise - = mzero + ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) + ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred + ; lift $ checkReductionDepth loc' pred + + + ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds + -- Emit work for subgoals but use our local cache + -- so we can solve recursive dictionaries. + + ; let ev_tm = mk_ev (map getEvExpr evc_vs) + ev_binds' = extendEvBinds ev_binds $ + mkWantedEvBind (ctEvEvId ev) canonical ev_tm + + ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ + freshGoals evc_vs } + + _other_inst_res -> mzero } + + ForAllPred _tvs _theta _body -> + -- TODO: implement short-cut solving for quantified constraints + mzero + + _other_pred -> mzero + where + pred = ctEvPred ev -- Use a local cache of solved dicts while emitting EvVars for new work @@ -868,13 +885,16 @@ shortCutSolver dflags ev_w ev_i tryInstances :: DictCt -> SolverStage () tryInstances dict_ct - = Stage $ do { inerts <- getInertSet - ; try_instances inerts dict_ct } + = Stage $ do { dflags <- getDynFlags + ; inerts <- getInertSet + ; mode <- getModeTcS + ; try_instances inerts dflags mode dict_ct } -try_instances :: InertSet -> DictCt -> TcS (StopOrContinue ()) +try_instances :: InertSet -> DynFlags -> TcSMode -> DictCt -> TcS (StopOrContinue ()) -- Try to use type-class instance declarations to simplify the constraint -try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls - , di_tys = xis }) +try_instances inerts dflags mode + work_item@(DictCt { di_ev = ev, di_cls = cls + , di_tys = xis }) | isGiven ev -- Never use instances for Given constraints = continueWith () -- See Note [No Given/Given fundeps] @@ -883,17 +903,26 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls = do { setEvBindIfWanted ev EvCanonical (ctEvTerm solved_ev) ; stopWith ev "Dict/Top (cached)" } + | TcSSpecPrag <- mode + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + = do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag DictCt: short-cut fully solved Wanted from instances" + else continueWith () + } + | otherwise -- Wanted, but not cached - = do { dflags <- getDynFlags - ; lkup_res <- matchClassInst dflags inerts cls xis dict_loc - ; case lkup_res of - OneInst { cir_what = what } - -> do { insertSafeOverlapFailureTcS what work_item - ; updSolvedDicts what work_item - ; chooseInstance ev lkup_res } - _ -> -- NoInstance or NotSure - -- We didn't solve it; so try functional dependencies - continueWith () } + = do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc + ; case lkup_res of + OneInst { cir_what = what } + -> do { insertSafeOverlapFailureTcS what work_item + ; updSolvedDicts what work_item + ; chooseInstance ev lkup_res } + _ -> -- NoInstance or NotSure + -- We didn't solve it; so try functional dependencies + continueWith () } where dict_loc = ctEvLoc ev @@ -940,10 +969,12 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> InertSet +matchClassInst :: DynFlags + -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult matchClassInst dflags inerts clas tys loc + -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance -- whether top level, or local quantified constraints. ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2018,8 +2018,9 @@ finishCanWithIrred :: CtIrredReason -> CtEvidence -> TcS (StopOrContinue (Either IrredCt a)) finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, - -- and the TcS abort-if-insoluble flag is on. - when (isInsolubleReason reason) tryEarlyAbortTcS + -- and the TcSMode is TcsHoleFits + mode <- getModeTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -14,9 +14,10 @@ module GHC.Tc.Solver.Monad ( -- The TcS monad - TcS, runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, - failTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, - runTcSEqualities, + TcS, TcSMode(..), + runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, + runTcSEqualities, runTcSSpecPragWithEvBinds, + failTcS, failWithTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, nestTcS, nestImplicTcS, setEvBindsTcS, emitImplicationTcS, emitTvImplicationTcS, emitFunDepWanteds, @@ -37,7 +38,7 @@ module GHC.Tc.Solver.Monad ( stopWithStage, nopStage, -- Tracing etc - panicTcS, traceTcS, tryEarlyAbortTcS, + panicTcS, traceTcS, getModeTcS, traceFireTcS, bumpStepCountTcS, csTraceTcS, wrapErrTcS, wrapWarnTcS, resetUnificationFlag, setUnificationFlag, @@ -824,6 +825,8 @@ added. This is initialised from the innermost implication constraint. data TcSEnv = TcSEnv { + tcs_mode :: TcSMode, + tcs_ev_binds :: EvBindsVar, tcs_unified :: IORef Int, @@ -841,15 +844,27 @@ data TcSEnv tcs_inerts :: IORef InertSet, -- Current inert set - -- Whether to throw an exception if we come across an insoluble constraint. - -- Used to fail-fast when checking for hole-fits. See Note [Speeding up - -- valid hole-fits]. - tcs_abort_on_insoluble :: Bool, - -- See Note [WorkList priorities] in GHC.Tc.Solver.InertSet tcs_worklist :: IORef WorkList -- Current worklist } +data TcSMode + = TcSVanilla + + | TcSHoleFits -- ^ Throw an exception if we come across an insoluble constraint, + -- to fail-fast when checking for hole-fits. + -- + -- See Note [Speeding up valid hole-fits]. + + | TcSSpecPrag -- ^ Don't use instance declarations or unpack forall constraints; + -- used when simplifying a SPECIALISE pragma. + deriving( Eq ) + +instance Outputable TcSMode where + ppr TcSVanilla = text "TcSVanilla" + ppr TcSHoleFits = text "TcSHoleFits" + ppr TcSSpecPrag = text "TcSSpecPrag" + --------------- newtype TcS a = TcS { unTcS :: TcSEnv -> TcM a } deriving (Functor) @@ -910,17 +925,17 @@ wrapWarnTcS :: TcM a -> TcS a wrapWarnTcS = wrapTcS panicTcS :: SDoc -> TcS a -failTcS :: TcRnMessage -> TcS a +failTcS :: TcS a +failWithTcS :: TcRnMessage -> TcS a warnTcS, addErrTcS :: TcRnMessage -> TcS () -failTcS = wrapTcS . TcM.failWith +failTcS = wrapTcS TcM.failM +failWithTcS = wrapTcS . TcM.failWith warnTcS msg = wrapTcS (TcM.addDiagnostic msg) addErrTcS = wrapTcS . TcM.addErr panicTcS doc = pprPanic "GHC.Tc.Solver.Monad" doc -tryEarlyAbortTcS :: TcS () --- Abort (fail in the monad) if the abort_on_insoluble flag is on -tryEarlyAbortTcS - = mkTcS (\env -> when (tcs_abort_on_insoluble env) TcM.failM) +getModeTcS :: TcS TcSMode +getModeTcS = mkTcS (\env -> return (tcs_mode env)) -- | Emit a warning within the 'TcS' monad at the location given by the 'CtLoc'. ctLocWarnTcS :: CtLoc -> TcRnMessage -> TcS () @@ -976,11 +991,17 @@ csTraceTcM mk_doc msg }) } {-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] -runTcS :: TcS a -- What to run - -> TcM (a, EvBindMap) +runTcSWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSWithEvBinds = runTcSWorker True TcSVanilla + +-- | This version of 'runTcSWithEvBinds' uses the 'TcSSpecPrag' mode. +runTcSSpecPragWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSSpecPragWithEvBinds = runTcSWorker True TcSSpecPrag + +runTcS :: TcS a -> TcM (a, EvBindMap) runTcS tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; res <- runTcSWithEvBinds ev_binds_var tcs + ; res <- runTcSWorker True TcSVanilla ev_binds_var tcs ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var ; return (res, ev_binds) } @@ -990,51 +1011,47 @@ runTcS tcs runTcSEarlyAbort :: TcS a -> TcM a runTcSEarlyAbort tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; runTcSWithEvBinds' True True ev_binds_var tcs } + ; runTcSWorker True TcSHoleFits ev_binds_var tcs } -- | This can deal only with equality constraints. runTcSEqualities :: TcS a -> TcM a runTcSEqualities thing_inside - = do { ev_binds_var <- TcM.newNoTcEvBinds - ; runTcSWithEvBinds ev_binds_var thing_inside } + = do { ev_binds_var <- TcM.newNoTcEvBinds -- No bindings + ; runTcSWorker True TcSVanilla ev_binds_var thing_inside } -- | A variant of 'runTcS' that takes and returns an 'InertSet' for -- later resumption of the 'TcS' session. runTcSInerts :: InertSet -> TcS a -> TcM (a, InertSet) -runTcSInerts inerts tcs = do - ev_binds_var <- TcM.newTcEvBinds - runTcSWithEvBinds' False False ev_binds_var $ do - setInertSet inerts - a <- tcs - new_inerts <- getInertSet - return (a, new_inerts) - -runTcSWithEvBinds :: EvBindsVar - -> TcS a - -> TcM a -runTcSWithEvBinds = runTcSWithEvBinds' True False - -runTcSWithEvBinds' :: Bool -- ^ Restore type variable cycles afterwards? - -- Don't if you want to reuse the InertSet. - -- See also Note [Type equality cycles] - -- in GHC.Tc.Solver.Equality - -> Bool - -> EvBindsVar - -> TcS a - -> TcM a -runTcSWithEvBinds' restore_cycles abort_on_insoluble ev_binds_var tcs +runTcSInerts inerts tcs + = do { ev_binds_var <- TcM.newTcEvBinds + ; runTcSWorker False TcSVanilla ev_binds_var $ + do { setInertSet inerts + ; a <- tcs + ; new_inerts <- getInertSet + ; return (a, new_inerts) } } + +-- runTcSWorker is not exported +runTcSWorker :: Bool -- ^ Restore type variable cycles afterwards? + -- Don't if you want to reuse the InertSet. + -- See also Note [Type equality cycles] + -- in GHC.Tc.Solver.Equality + -> TcSMode + -> EvBindsVar + -> TcS a + -> TcM a +runTcSWorker restore_cycles mode ev_binds_var tcs = do { unified_var <- TcM.newTcRef 0 ; step_count <- TcM.newTcRef 0 ; inert_var <- TcM.newTcRef emptyInert ; wl_var <- TcM.newTcRef emptyWorkList ; unif_lvl_var <- TcM.newTcRef Nothing - ; let env = TcSEnv { tcs_ev_binds = ev_binds_var - , tcs_unified = unified_var - , tcs_unif_lvl = unif_lvl_var - , tcs_count = step_count - , tcs_inerts = inert_var - , tcs_abort_on_insoluble = abort_on_insoluble - , tcs_worklist = wl_var } + ; let env = TcSEnv { tcs_mode = mode + , tcs_ev_binds = ev_binds_var + , tcs_unified = unified_var + , tcs_unif_lvl = unif_lvl_var + , tcs_count = step_count + , tcs_inerts = inert_var + , tcs_worklist = wl_var } -- Run the computation ; res <- unTcS tcs env @@ -1091,12 +1108,7 @@ nestImplicTcS :: EvBindsVar -> TcLevel -> TcS a -> TcS a nestImplicTcS ref inner_tclvl (TcS thing_inside) - = TcS $ \ TcSEnv { tcs_unified = unified_var - , tcs_inerts = old_inert_var - , tcs_count = count - , tcs_unif_lvl = unif_lvl - , tcs_abort_on_insoluble = abort_on_insoluble - } -> + = TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var }) -> do { inerts <- TcM.readTcRef old_inert_var ; let nest_inert = inerts { inert_cycle_breakers = pushCycleBreakerVarStack (inert_cycle_breakers inerts) @@ -1105,13 +1117,9 @@ nestImplicTcS ref inner_tclvl (TcS thing_inside) -- All other InertSet fields are inherited ; new_inert_var <- TcM.newTcRef nest_inert ; new_wl_var <- TcM.newTcRef emptyWorkList - ; let nest_env = TcSEnv { tcs_count = count -- Inherited - , tcs_unif_lvl = unif_lvl -- Inherited - , tcs_ev_binds = ref - , tcs_unified = unified_var - , tcs_inerts = new_inert_var - , tcs_abort_on_insoluble = abort_on_insoluble - , tcs_worklist = new_wl_var } + ; let nest_env = env { tcs_ev_binds = ref + , tcs_inerts = new_inert_var + , tcs_worklist = new_wl_var } ; res <- TcM.setTcLevel inner_tclvl $ thing_inside nest_env ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -923,7 +923,7 @@ solveSimpleWanteds simples -- See Note [The solveSimpleWanteds loop] go n limit wc | n `intGtLimit` limit - = failTcS $ TcRnSimplifierTooManyIterations simples limit wc + = failWithTcS $ TcRnSimplifierTooManyIterations simples limit wc | isEmptyBag (wc_simple wc) = return (n,wc) @@ -1053,7 +1053,7 @@ solveCt (CNonCanonical ev) = solveNC ev solveCt (CIrredCan (IrredCt { ir_ev = ev })) = solveNC ev solveCt (CEqCan (EqCt { eq_ev = ev, eq_eq_rel = eq_rel - , eq_lhs = lhs, eq_rhs = rhs })) + , eq_lhs = lhs, eq_rhs = rhs })) = solveEquality ev eq_rel (canEqLHSType lhs) rhs solveCt (CQuantCan (QCI { qci_ev = ev, qci_pend_sc = pend_sc })) @@ -1211,8 +1211,25 @@ solveForAllNC ev tvs theta pred solveForAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType -> ExpansionFuel -> TcS (StopOrContinue Void) -- Precondition: already rewritten by inert set -solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) - tvs theta pred _fuel +solveForAll ev tvs theta pred fuel + = do { mode <- getModeTcS + ; solve_forAll ev tvs theta pred fuel mode + } + +solve_forAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType + -> ExpansionFuel -> TcSMode + -> TcS (StopOrContinue Void) +solve_forAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) + tvs theta pred fuel mode + | TcSSpecPrag <- mode + = do { dflags <- getDynFlags + ; shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag QC: short-cut fully solved Wanted from instances" + else do { addInertForAll qci + ; stopWith ev "TcSSpecPrag QC: Wanted kept as inert" } + } + | otherwise = -- See Note [Solving a Wanted forall-constraint] TcS.setSrcSpan (getCtLocEnvLoc $ ctLocEnv loc) $ -- This setSrcSpan is important: the emitImplicationTcS uses that @@ -1257,9 +1274,11 @@ solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_lo get_size pred = case classifyPredType pred of ClassPred cls tys -> pSizeClassPred cls tys _ -> pSizeType pred + qci = QCI { qci_ev = ev, qci_tvs = tvs + , qci_pred = pred, qci_pend_sc = fuel } -- See Note [Solving a Given forall-constraint] -solveForAll ev@(CtGiven {}) tvs _theta pred fuel +solve_forAll ev@(CtGiven {}) tvs _theta pred fuel _mode = do { addInertForAll qci ; stopWith ev "Given forall-constraint" } where ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -862,12 +862,14 @@ zonkLTcSpecPrags ps ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_call = spec_e' + })) + }} {- ************************************************************************ ===================================== testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE QuantifiedConstraints #-} + +module DsSpecPragmas where + +-- Some specialise pragmas that are difficult to generate the correct RULE for. + +-------------------------------------------------------------------------------- + +f1 :: ( Num a, Eq b ) => a -> b -> Int +f1 _ _ = 111 + +-- Make sure we don't generate a rule with an LHS of the form +-- +-- forall @e (d :: Eq e). f @[e] ($fEqList d) = ... +-- +-- but rather +-- +-- forall @e (d :: Eq [e]). f @[e] d = ... +{-# SPECIALISE f1 :: Eq [e] => Word -> [e] -> Int #-} + +-------------------------------------------------------------------------------- + +f2 :: ( Eq a, Eq b ) => a -> b -> Int +f2 a b = if ( a == a ) == ( b == b ) then 1 else 2 + +-- Make sure the rule LHS is of the form +-- +-- f2 @c @c d1 d2 and not f2 @c @c d d +{-# SPECIALISE f2 :: Eq c => c -> c -> Int #-} + +-------------------------------------------------------------------------------- + +f3 :: ( Eq a, forall x. Eq x => Eq ( f x ) ) => f a -> Bool +f3 z = z == z + +-- Discharge the quantified constraint but keep the 'Eq' constraint +{-# SPECIALISE f3 :: Eq c => [ c ] -> Bool #-} + +-- Discharge the 'Eq' constraint but keep the quantified constraint +{-# SPECIALISE f3 :: ( forall y. Eq y => Eq ( g y ) ) => g Int -> Bool #-} + +-------------------------------------------------------------------------------- + +f4 :: Monad m => a -> m a +f4 = return + +-- Check we can deal with locally quantified variables in constraints, +-- in this case 'Monad (ST s)'. +{-# SPECIALISE f4 :: b -> ST s b #-} + +-------------------------------------------------------------------------------- ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -502,6 +502,7 @@ test('T23491d', [extra_files(['T23491.hs']), grep_errmsg(r'Static argument')], m test('T23074', normal, compile, ['-O -ddump-rules']) test('T23272', [only_ways(['ghci']), extra_hc_opts('-fno-unoptimized-core-for-interpreter -O')], ghci_script, ['T23272.script']) test('T23567', [extra_files(['T23567A.hs'])], multimod_compile, ['T23567', '-O -v0']) +test('DsSpecPragmas', normal, compile, ['-O -ddump-rules']) # The -ddump-simpl of T22404 should have no let-bindings test('T22404', [only_ways(['optasm']), check_errmsg(r'let') ], compile, ['-ddump-simpl -dsuppress-uniques']) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -738,6 +738,7 @@ test('ExplicitSpecificityA1', normal, compile, ['']) test('ExplicitSpecificityA2', normal, compile, ['']) test('ExplicitSpecificity4', normal, compile, ['']) test('RuleEqs', normal, compile, ['']) +test('SpecPragmas', normal, compile, ['']) test('T17775-viewpats-a', normal, compile, ['']) test('T17775-viewpats-b', normal, compile_fail, ['']) test('T17775-viewpats-c', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ffae48ccd1f48284f676e2c1f4b7f2ad9893ab4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2ffae48ccd1f48284f676e2c1f4b7f2ad9893ab4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 13:26:46 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Tue, 28 Jan 2025 08:26:46 -0500 Subject: [Git][ghc/ghc][wip/T24359] WIP: original approach but with TcSSpecPrag Message-ID: <6798db161bf5d_3bc1b5c05d0623cb@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 7ca0f8c9 by sheaf at 2025-01-28T14:26:20+01:00 WIP: original approach but with TcSSpecPrag - - - - - 14 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs - + testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -824,7 +824,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +835,36 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_call :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -823,7 +823,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,14 +921,19 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_call = the_call + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig - = do { ds_call <- zapUnspecables $ -- zapUnspecables: see - dsLExpr the_call -- Note [Desugaring RULE left hand sides] + = do { ds_call <- unsetGOptM Opt_EnableRewriteRules $ -- Note [Desugaring RULE left hand sides] + unsetWOptM Opt_WarnIdentities $ + zapUnspecables $ + dsLExpr the_call -- Simplify the (desugared) call; see wrinkle (SP1) -- in Note [Desugaring SPECIALISE pragmas] @@ -1054,7 +1059,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because @@ -1077,7 +1082,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args | all is_nop_arg rule_args, not (isInlinePragma spec_inl) -- The specialisation does nothing. - -- But don't compliain if it is SPECIALISE INLINE (#4444) + -- But don't complain if it is SPECIALISE INLINE (#4444) = Just UselessSpecialiseNoSpecialisation | otherwise ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS, runTcSWithEvBinds ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPragWithEvBinds ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -50,7 +50,7 @@ import GHC.Tc.Utils.Instantiate( topInstantiate, tcInstTypeBndrs ) import GHC.Tc.Utils.Env import GHC.Tc.Types.Origin -import GHC.Tc.Types.Evidence( HsWrapper(..), (<.>), TcEvBinds(..) ) +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Constraint import GHC.Tc.Zonk.TcType @@ -703,17 +703,24 @@ Note [Handling new-form SPECIALISE pragmas] New-form SPECIALISE pragmas are described by GHC Proposal #493. The pragma takes the form of a function application, possibly with intervening -parens and type signatures, with a variable at the head. It may have rule -for-alls at the top. e.g. +parens and type signatures, with a variable at the head: {-# SPECIALISE f1 @Int 3 #-} - {-# SPECIALISE forall x xs. f2 (x:xs) #-} - {-# SPECIALISE f3 :: Int -> Int #-} - {-# SPECIALISE (f4 :: Int -> Int) 5 #-} + {-# SPECIALISE f2 :: Int -> Int #-} + {-# SPECIALISE (f3 :: Int -> Int) 5 #-} + +It may also have rule for-alls at the top, e.g. + + {-# SPECIALISE forall x xs. f4 (x:xs) #-} {-# SPECIALISE forall a. forall x xs. f5 @a @a (x:xs) #-} See `GHC.Rename.Bind.checkSpecESigShape` for the shape-check. +We are going to use the following (perhaps somewhat contrived) example to +demonstrate the subtle aspects of the implementation: + + f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} Example: f :: forall a b. (Eq a, Eq b, Eq c) => a -> b -> c -> Bool -> blah @@ -755,26 +762,46 @@ Note that spec_const_binds = let d1 = $fEqInt d3 = d2 -How it works: +This is done in three parts. + + A. Typechecker: `GHC.Tc.Gen.Sig.tcSpecPrag` + + (1) Typecheck the expression, capturing its constraints + + (2) Simplify these constraints, in special TcSSpecPrag mode + SLD TODO add more details. + + (3) Decide which constraints to quantify over, and quantify. -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results - into a `SpecPragE` record. Nothing very exciting happens here. + (4) Emit the residual (non-quantified) constraints, and wrap the + expression in a let binding for those constraints. -* `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any - free type variables of the LHS. See Note [Free tyvars on rule LHS] in - GHC.Tc.Zonk.Type. These weren't conveniently available earlier. + (5) Store all the information in a 'SpecPragE' record, to be consumed + by the desugarer. -* `GHC.HsToCore.Binds.dsSpec` does the clever stuff: + B. Zonker: `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` - * Simplifies the expression. This is important because a type signature in the - expression will have led to type/dictionary abstractions/applications. Now - it should look like - let in f e1 e1 e3 + The zonker does a little extra work to collect any free type variables + of the LHS. See Note [Free tyvars on rule LHS] in GHC.Tc.Zonk.Type. + These weren't conveniently available earlier. - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards - the other dictionary bindings, and decomposes the call. + C. Desugarer: `GHC.HsToCore.Binds.dsSpec`. - * Then it can build the RULE and specialised function. + This is where most of the clever stuff happens. See + Note [Desugaring SPECIALISE pragmas] in GHC.HsToCore.Binds for details, + but in brief: + + (1) Simplify the expression. This is important because a type signature in + the expression will have led to type/dictionary abstractions/applications. + Now it should look like + let in f d1 d2 d3 + + (2) `prepareSpecLHS` identifies the `spec_const_binds`, discards the other + dictionary bindings, and decomposes the call. + + (3) Then we build the specialised function $sf, and concoct a RULE + of the form: + forall @a @b d1 d2 d3. f d1 d2 d3 = $sf d1 d2 d3 Note [Handling old-form SPECIALISE pragmas] @@ -944,38 +971,41 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) - = do { -- Typecheck the expression, spec_e, capturing its constraints + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] + = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm - ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) + ; traceTc "tcSpecPrag SpecSigE 1" (ppr nm $$ ppr spec_e) ; skol_info <- mkSkolemInfo skol_info_anon - ; (rhs_tclvl, wanted, (rule_bndrs', (spec_e', _rho))) + ; (rhs_tclvl, wanted, (rule_bndrs', (tc_spec_e, _rho))) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- Simplify the constraints + -- (2) Simplify the constraints, in special TcSSpecPrag mode ; ev_binds_var <- newTcEvBinds ; wanted <- setTcLevel rhs_tclvl $ - runTcSWithEvBinds ev_binds_var $ + runTcSSpecPragWithEvBinds ev_binds_var $ solveWanteds wanted - -- Quantify over the the constraints + -- (3) Quantify over the constraints ; qevs <- mapM newEvVar $ ctsPreds $ approximateWC False wanted + -- (4) Emit the residual (non-quantified) constraints, + -- and wrap the expression in the evidence let bindings ; let tv_bndrs = filter isTyVar rule_bndrs' ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var emptyVarSet tv_bndrs qevs wanted + ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) tc_spec_e ; traceTc "tcSpecPrag:SpecSigE" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs - , text "spec_e:" <+> ppr spec_e' + , text "spec_e:" <+> ppr tc_spec_e , text "inl:" <+> ppr inl ] - ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) spec_e' ; return [SpecPragE { spe_fn_nm = nm , spe_fn_id = poly_id , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order @@ -1414,9 +1444,9 @@ in `getRuleQuantCts`. Why not? * Equality constraints are unboxed, and that leads to complications For example equality constraints from the LHS will emit coercion hole Wanteds. These don't have a name, so we can't quantify over them directly. - Instead, in `mk_one` in `getRuleQuantCts` in we'd have to invent a new EvVar - for the coercion, fill the hole with the invented EvVar, and then quantify - over the EvVar. Here is old code from `mk_one` + Instead, in `getRuleQuantCts`, we'd have to invent a new EvVar for the + coercion, fill the hole with the invented EvVar, and then quantify over the + EvVar. Here is old code from `mk_one` do { ev_id <- newEvVar pred ; fillCoercionHole hole (mkCoVarCo ev_id) ; return ev_id } @@ -1483,7 +1513,8 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; lhs_wanted <- liftZonkM $ zonkWC lhs_wanted -- Note [The SimplifyRule Plan] step 3 - ; (quant_evs, residual_lhs_wanted) <-getRuleQuantCts lhs_wanted + ; (quant_cts, residual_lhs_wanted) <- getRuleQuantCts lhs_wanted + ; let quant_evs = map ctEvId (bagToList quant_cts) ; traceTc "simplifyRule" $ vcat [ text "LHS of rule" <+> doubleQuotes (ftext name) @@ -1496,7 +1527,7 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; return (quant_evs, residual_lhs_wanted, dont_default) } -getRuleQuantCts :: WantedConstraints -> TcM ([EvVar], WantedConstraints) +getRuleQuantCts :: WantedConstraints -> TcM (Cts, WantedConstraints) -- Extract all the constraints that we can quantify over, -- also returning the depleted WantedConstraints -- @@ -1504,20 +1535,17 @@ getRuleQuantCts :: WantedConstraints -> TcM ([EvVar], WantedConstraints) -- and attempt to solve them from the quantified constraints. Instead -- we /partition/ the WantedConstraints into ones to quantify and ones -- we can't quantify. We could use approximateWC instead, and leave --- `wanted` unchanged; but then we'd have clone fresh binders and +-- `wanted` unchanged; but then we'd have to clone fresh binders and -- generate silly identity bindings. Seems more direct to do this. --- Probably not a big eal wither way. +-- Probably not a big deal wither way. -- -- NB: we must look inside implications, because with -- -fdefer-type-errors we generate implications rather eagerly; -- see GHC.Tc.Utils.Unify.implicationNeeded. Not doing so caused #14732. getRuleQuantCts wc - = do { quant_evs <- mapM mk_one (bagToList quant_cts) - ; return (quant_evs, residual_wc) } + = return $ float_wc emptyVarSet wc where - (quant_cts, residual_wc) = float_wc emptyVarSet wc - float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_errors = errs }) = ( simple_yes `andCts` implic_yes @@ -1542,17 +1570,6 @@ getRuleQuantCts wc EqPred {} -> False -- Note [RULE quantification over equalities] _ -> tyCoVarsOfCt ct `disjointVarSet` skol_tvs - mk_one :: Ct -> TcM EvVar - mk_one ct - | CtWanted { ctev_dest = dest } <- ctEvidence ct - , EvVarDest ev_id <- dest - -- HoleDest can't happen because we don't quantify - -- over EqPred: See rule_quant_ct above - = return ev_id - - | otherwise - = pprPanic "getRuleQuantCts" (ppr ct) - {- Note [Quantifying over equalities in RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Solver/Default.hs ===================================== @@ -973,7 +973,7 @@ tryDefaultGroup wanteds (Proposal assignments) errInvalidDefaultedTyVar :: WantedConstraints -> Proposal -> NonEmpty TcTyVar -> TcS () errInvalidDefaultedTyVar wanteds (Proposal assignments) problematic_tvs - = failTcS $ TcRnInvalidDefaultedTyVar tidy_wanteds tidy_assignments tidy_problems + = failWithTcS $ TcRnInvalidDefaultedTyVar tidy_wanteds tidy_assignments tidy_problems where proposal_tvs = concatMap (\(tv, ty) -> tv : tyCoVarsOfTypeList ty) assignments tidy_env = tidyFreeTyCoVars emptyTidyEnv $ proposal_tvs ++ NE.toList problematic_tvs ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -3,6 +3,7 @@ -- | Solving Class constraints CDictCan module GHC.Tc.Solver.Dict ( solveDict, solveDictNC, + shortCutSolver, checkInstanceOK, matchLocalInst, chooseInstance, makeSuperClasses, mkStrictSuperClasses, @@ -727,7 +728,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +758,42 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w + | isIPLikePred (ctEvPred ev_w) + -- Not for implicit parameters (#18627) + -- TODO: we should probably also reject QCs, + -- e.g. ( forall a. Eq a => IP "ip" a ) + = return False + | otherwise = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +809,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -806,46 +818,51 @@ shortCutSolver dflags ev_w ev_i try_solve_from_instance -- See Note [Shortcut try_solve_from_instance] :: (EvBindMap, DictMap DictCt) -> CtEvidence -> MaybeT TcS (EvBindMap, DictMap DictCt) - try_solve_from_instance (ev_binds, solved_dicts) ev - | let pred = ctEvPred ev - , ClassPred cls tys <- classifyPredType pred - = do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w - ; lift $ warn_custom_warn_instance inst_res loc_w - -- See Note [Implementation of deprecated instances] - ; case inst_res of - OneInst { cir_new_theta = preds - , cir_mk_ev = mk_ev - , cir_canonical = canonical - , cir_what = what } - | safeOverlap what - , all isTyFamFree preds -- Note [Shortcut solving: type families] - -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls - , di_tys = tys, di_pend_sc = doNotExpand } - solved_dicts' = addSolvedDict dict_ct solved_dicts - -- solved_dicts': it is important that we add our goal - -- to the cache before we solve! Otherwise we may end - -- up in a loop while solving recursive dictionaries. - - ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) - ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred - ; lift $ checkReductionDepth loc' pred - - - ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds - -- Emit work for subgoals but use our local cache - -- so we can solve recursive dictionaries. - - ; let ev_tm = mk_ev (map getEvExpr evc_vs) - ev_binds' = extendEvBinds ev_binds $ - mkWantedEvBind (ctEvEvId ev) canonical ev_tm - - ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ - freshGoals evc_vs } - - _ -> mzero } + try_solve_from_instance (ev_binds, solved_dicts) ev = + case classifyPredType pred of + ClassPred cls tys -> + do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w + ; lift $ warn_custom_warn_instance inst_res loc_w + -- See Note [Implementation of deprecated instances] + ; case inst_res of + OneInst { cir_new_theta = preds + , cir_mk_ev = mk_ev + , cir_canonical = canonical + , cir_what = what } + | safeOverlap what + , all isTyFamFree preds -- Note [Shortcut solving: type families] + -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls + , di_tys = tys, di_pend_sc = doNotExpand } + solved_dicts' = addSolvedDict dict_ct solved_dicts + -- solved_dicts': it is important that we add our goal + -- to the cache before we solve! Otherwise we may end + -- up in a loop while solving recursive dictionaries. - | otherwise - = mzero + ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) + ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred + ; lift $ checkReductionDepth loc' pred + + + ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds + -- Emit work for subgoals but use our local cache + -- so we can solve recursive dictionaries. + + ; let ev_tm = mk_ev (map getEvExpr evc_vs) + ev_binds' = extendEvBinds ev_binds $ + mkWantedEvBind (ctEvEvId ev) canonical ev_tm + + ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ + freshGoals evc_vs } + + _other_inst_res -> mzero } + + ForAllPred _tvs _theta _body -> + -- TODO: implement short-cut solving for quantified constraints + mzero + + _other_pred -> mzero + where + pred = ctEvPred ev -- Use a local cache of solved dicts while emitting EvVars for new work @@ -868,13 +885,16 @@ shortCutSolver dflags ev_w ev_i tryInstances :: DictCt -> SolverStage () tryInstances dict_ct - = Stage $ do { inerts <- getInertSet - ; try_instances inerts dict_ct } + = Stage $ do { dflags <- getDynFlags + ; inerts <- getInertSet + ; mode <- getModeTcS + ; try_instances inerts dflags mode dict_ct } -try_instances :: InertSet -> DictCt -> TcS (StopOrContinue ()) +try_instances :: InertSet -> DynFlags -> TcSMode -> DictCt -> TcS (StopOrContinue ()) -- Try to use type-class instance declarations to simplify the constraint -try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls - , di_tys = xis }) +try_instances inerts dflags mode + work_item@(DictCt { di_ev = ev, di_cls = cls + , di_tys = xis }) | isGiven ev -- Never use instances for Given constraints = continueWith () -- See Note [No Given/Given fundeps] @@ -883,17 +903,26 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls = do { setEvBindIfWanted ev EvCanonical (ctEvTerm solved_ev) ; stopWith ev "Dict/Top (cached)" } + | TcSSpecPrag <- mode + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + = do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag DictCt: short-cut fully solved Wanted from instances" + else continueWith () + } + | otherwise -- Wanted, but not cached - = do { dflags <- getDynFlags - ; lkup_res <- matchClassInst dflags inerts cls xis dict_loc - ; case lkup_res of - OneInst { cir_what = what } - -> do { insertSafeOverlapFailureTcS what work_item - ; updSolvedDicts what work_item - ; chooseInstance ev lkup_res } - _ -> -- NoInstance or NotSure - -- We didn't solve it; so try functional dependencies - continueWith () } + = do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc + ; case lkup_res of + OneInst { cir_what = what } + -> do { insertSafeOverlapFailureTcS what work_item + ; updSolvedDicts what work_item + ; chooseInstance ev lkup_res } + _ -> -- NoInstance or NotSure + -- We didn't solve it; so try functional dependencies + continueWith () } where dict_loc = ctEvLoc ev @@ -940,10 +969,12 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> InertSet +matchClassInst :: DynFlags + -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult matchClassInst dflags inerts clas tys loc + -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance -- whether top level, or local quantified constraints. ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2018,8 +2018,9 @@ finishCanWithIrred :: CtIrredReason -> CtEvidence -> TcS (StopOrContinue (Either IrredCt a)) finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, - -- and the TcS abort-if-insoluble flag is on. - when (isInsolubleReason reason) tryEarlyAbortTcS + -- and the TcSMode is TcsHoleFits + mode <- getModeTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -14,9 +14,10 @@ module GHC.Tc.Solver.Monad ( -- The TcS monad - TcS, runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, - failTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, - runTcSEqualities, + TcS, TcSMode(..), + runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, + runTcSEqualities, runTcSSpecPragWithEvBinds, + failTcS, failWithTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, nestTcS, nestImplicTcS, setEvBindsTcS, emitImplicationTcS, emitTvImplicationTcS, emitFunDepWanteds, @@ -37,7 +38,7 @@ module GHC.Tc.Solver.Monad ( stopWithStage, nopStage, -- Tracing etc - panicTcS, traceTcS, tryEarlyAbortTcS, + panicTcS, traceTcS, getModeTcS, traceFireTcS, bumpStepCountTcS, csTraceTcS, wrapErrTcS, wrapWarnTcS, resetUnificationFlag, setUnificationFlag, @@ -824,6 +825,8 @@ added. This is initialised from the innermost implication constraint. data TcSEnv = TcSEnv { + tcs_mode :: TcSMode, + tcs_ev_binds :: EvBindsVar, tcs_unified :: IORef Int, @@ -841,15 +844,27 @@ data TcSEnv tcs_inerts :: IORef InertSet, -- Current inert set - -- Whether to throw an exception if we come across an insoluble constraint. - -- Used to fail-fast when checking for hole-fits. See Note [Speeding up - -- valid hole-fits]. - tcs_abort_on_insoluble :: Bool, - -- See Note [WorkList priorities] in GHC.Tc.Solver.InertSet tcs_worklist :: IORef WorkList -- Current worklist } +data TcSMode + = TcSVanilla + + | TcSHoleFits -- ^ Throw an exception if we come across an insoluble constraint, + -- to fail-fast when checking for hole-fits. + -- + -- See Note [Speeding up valid hole-fits]. + + | TcSSpecPrag -- ^ Don't use instance declarations or unpack forall constraints; + -- used when simplifying a SPECIALISE pragma. + deriving( Eq ) + +instance Outputable TcSMode where + ppr TcSVanilla = text "TcSVanilla" + ppr TcSHoleFits = text "TcSHoleFits" + ppr TcSSpecPrag = text "TcSSpecPrag" + --------------- newtype TcS a = TcS { unTcS :: TcSEnv -> TcM a } deriving (Functor) @@ -910,17 +925,17 @@ wrapWarnTcS :: TcM a -> TcS a wrapWarnTcS = wrapTcS panicTcS :: SDoc -> TcS a -failTcS :: TcRnMessage -> TcS a +failTcS :: TcS a +failWithTcS :: TcRnMessage -> TcS a warnTcS, addErrTcS :: TcRnMessage -> TcS () -failTcS = wrapTcS . TcM.failWith +failTcS = wrapTcS TcM.failM +failWithTcS = wrapTcS . TcM.failWith warnTcS msg = wrapTcS (TcM.addDiagnostic msg) addErrTcS = wrapTcS . TcM.addErr panicTcS doc = pprPanic "GHC.Tc.Solver.Monad" doc -tryEarlyAbortTcS :: TcS () --- Abort (fail in the monad) if the abort_on_insoluble flag is on -tryEarlyAbortTcS - = mkTcS (\env -> when (tcs_abort_on_insoluble env) TcM.failM) +getModeTcS :: TcS TcSMode +getModeTcS = mkTcS (\env -> return (tcs_mode env)) -- | Emit a warning within the 'TcS' monad at the location given by the 'CtLoc'. ctLocWarnTcS :: CtLoc -> TcRnMessage -> TcS () @@ -976,11 +991,17 @@ csTraceTcM mk_doc msg }) } {-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] -runTcS :: TcS a -- What to run - -> TcM (a, EvBindMap) +runTcSWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSWithEvBinds = runTcSWorker True TcSVanilla + +-- | This version of 'runTcSWithEvBinds' uses the 'TcSSpecPrag' mode. +runTcSSpecPragWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSSpecPragWithEvBinds = runTcSWorker True TcSSpecPrag + +runTcS :: TcS a -> TcM (a, EvBindMap) runTcS tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; res <- runTcSWithEvBinds ev_binds_var tcs + ; res <- runTcSWorker True TcSVanilla ev_binds_var tcs ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var ; return (res, ev_binds) } @@ -990,51 +1011,47 @@ runTcS tcs runTcSEarlyAbort :: TcS a -> TcM a runTcSEarlyAbort tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; runTcSWithEvBinds' True True ev_binds_var tcs } + ; runTcSWorker True TcSHoleFits ev_binds_var tcs } -- | This can deal only with equality constraints. runTcSEqualities :: TcS a -> TcM a runTcSEqualities thing_inside - = do { ev_binds_var <- TcM.newNoTcEvBinds - ; runTcSWithEvBinds ev_binds_var thing_inside } + = do { ev_binds_var <- TcM.newNoTcEvBinds -- No bindings + ; runTcSWorker True TcSVanilla ev_binds_var thing_inside } -- | A variant of 'runTcS' that takes and returns an 'InertSet' for -- later resumption of the 'TcS' session. runTcSInerts :: InertSet -> TcS a -> TcM (a, InertSet) -runTcSInerts inerts tcs = do - ev_binds_var <- TcM.newTcEvBinds - runTcSWithEvBinds' False False ev_binds_var $ do - setInertSet inerts - a <- tcs - new_inerts <- getInertSet - return (a, new_inerts) - -runTcSWithEvBinds :: EvBindsVar - -> TcS a - -> TcM a -runTcSWithEvBinds = runTcSWithEvBinds' True False - -runTcSWithEvBinds' :: Bool -- ^ Restore type variable cycles afterwards? - -- Don't if you want to reuse the InertSet. - -- See also Note [Type equality cycles] - -- in GHC.Tc.Solver.Equality - -> Bool - -> EvBindsVar - -> TcS a - -> TcM a -runTcSWithEvBinds' restore_cycles abort_on_insoluble ev_binds_var tcs +runTcSInerts inerts tcs + = do { ev_binds_var <- TcM.newTcEvBinds + ; runTcSWorker False TcSVanilla ev_binds_var $ + do { setInertSet inerts + ; a <- tcs + ; new_inerts <- getInertSet + ; return (a, new_inerts) } } + +-- runTcSWorker is not exported +runTcSWorker :: Bool -- ^ Restore type variable cycles afterwards? + -- Don't if you want to reuse the InertSet. + -- See also Note [Type equality cycles] + -- in GHC.Tc.Solver.Equality + -> TcSMode + -> EvBindsVar + -> TcS a + -> TcM a +runTcSWorker restore_cycles mode ev_binds_var tcs = do { unified_var <- TcM.newTcRef 0 ; step_count <- TcM.newTcRef 0 ; inert_var <- TcM.newTcRef emptyInert ; wl_var <- TcM.newTcRef emptyWorkList ; unif_lvl_var <- TcM.newTcRef Nothing - ; let env = TcSEnv { tcs_ev_binds = ev_binds_var - , tcs_unified = unified_var - , tcs_unif_lvl = unif_lvl_var - , tcs_count = step_count - , tcs_inerts = inert_var - , tcs_abort_on_insoluble = abort_on_insoluble - , tcs_worklist = wl_var } + ; let env = TcSEnv { tcs_mode = mode + , tcs_ev_binds = ev_binds_var + , tcs_unified = unified_var + , tcs_unif_lvl = unif_lvl_var + , tcs_count = step_count + , tcs_inerts = inert_var + , tcs_worklist = wl_var } -- Run the computation ; res <- unTcS tcs env @@ -1091,12 +1108,7 @@ nestImplicTcS :: EvBindsVar -> TcLevel -> TcS a -> TcS a nestImplicTcS ref inner_tclvl (TcS thing_inside) - = TcS $ \ TcSEnv { tcs_unified = unified_var - , tcs_inerts = old_inert_var - , tcs_count = count - , tcs_unif_lvl = unif_lvl - , tcs_abort_on_insoluble = abort_on_insoluble - } -> + = TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var }) -> do { inerts <- TcM.readTcRef old_inert_var ; let nest_inert = inerts { inert_cycle_breakers = pushCycleBreakerVarStack (inert_cycle_breakers inerts) @@ -1105,13 +1117,9 @@ nestImplicTcS ref inner_tclvl (TcS thing_inside) -- All other InertSet fields are inherited ; new_inert_var <- TcM.newTcRef nest_inert ; new_wl_var <- TcM.newTcRef emptyWorkList - ; let nest_env = TcSEnv { tcs_count = count -- Inherited - , tcs_unif_lvl = unif_lvl -- Inherited - , tcs_ev_binds = ref - , tcs_unified = unified_var - , tcs_inerts = new_inert_var - , tcs_abort_on_insoluble = abort_on_insoluble - , tcs_worklist = new_wl_var } + ; let nest_env = env { tcs_ev_binds = ref + , tcs_inerts = new_inert_var + , tcs_worklist = new_wl_var } ; res <- TcM.setTcLevel inner_tclvl $ thing_inside nest_env ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -923,7 +923,7 @@ solveSimpleWanteds simples -- See Note [The solveSimpleWanteds loop] go n limit wc | n `intGtLimit` limit - = failTcS $ TcRnSimplifierTooManyIterations simples limit wc + = failWithTcS $ TcRnSimplifierTooManyIterations simples limit wc | isEmptyBag (wc_simple wc) = return (n,wc) @@ -1053,7 +1053,7 @@ solveCt (CNonCanonical ev) = solveNC ev solveCt (CIrredCan (IrredCt { ir_ev = ev })) = solveNC ev solveCt (CEqCan (EqCt { eq_ev = ev, eq_eq_rel = eq_rel - , eq_lhs = lhs, eq_rhs = rhs })) + , eq_lhs = lhs, eq_rhs = rhs })) = solveEquality ev eq_rel (canEqLHSType lhs) rhs solveCt (CQuantCan (QCI { qci_ev = ev, qci_pend_sc = pend_sc })) @@ -1211,8 +1211,29 @@ solveForAllNC ev tvs theta pred solveForAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType -> ExpansionFuel -> TcS (StopOrContinue Void) -- Precondition: already rewritten by inert set -solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) - tvs theta pred _fuel +solveForAll ev tvs theta pred fuel + = do { mode <- getModeTcS + ; solve_forAll ev tvs theta pred fuel mode + } + +solve_forAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType + -> ExpansionFuel -> TcSMode + -> TcS (StopOrContinue Void) +solve_forAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) + tvs theta pred _fuel _mode +{- SLD TODO + | TcSSpecPrag <- mode + = do { dflags <- getDynFlags + ; shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag QC: short-cut fully solved Wanted from instances" + else do { let qci = QCI { qci_ev = ev, qci_tvs = tvs + , qci_pred = pred, qci_pend_sc = fuel } + ; addInertForAll qci + ; stopWith ev "TcSSpecPrag QC: Wanted kept as inert" } + } + | otherwise +-} = -- See Note [Solving a Wanted forall-constraint] TcS.setSrcSpan (getCtLocEnvLoc $ ctLocEnv loc) $ -- This setSrcSpan is important: the emitImplicationTcS uses that @@ -1259,7 +1280,7 @@ solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_lo _ -> pSizeType pred -- See Note [Solving a Given forall-constraint] -solveForAll ev@(CtGiven {}) tvs _theta pred fuel +solve_forAll ev@(CtGiven {}) tvs _theta pred fuel _mode = do { addInertForAll qci ; stopWith ev "Given forall-constraint" } where ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -862,12 +862,14 @@ zonkLTcSpecPrags ps ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_call = spec_e' + })) + }} {- ************************************************************************ ===================================== testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE QuantifiedConstraints #-} + +module DsSpecPragmas where + +-- Some specialise pragmas that are difficult to generate the correct RULE for. + +-------------------------------------------------------------------------------- + +f1 :: ( Num a, Eq b ) => a -> b -> Int +f1 _ _ = 111 + +-- Make sure we don't generate a rule with an LHS of the form +-- +-- forall @e (d :: Eq e). f @[e] ($fEqList d) = ... +-- +-- but rather +-- +-- forall @e (d :: Eq [e]). f @[e] d = ... +{-# SPECIALISE f1 :: Eq [e] => Word -> [e] -> Int #-} + +-------------------------------------------------------------------------------- + +f2 :: ( Eq a, Eq b ) => a -> b -> Int +f2 a b = if ( a == a ) == ( b == b ) then 1 else 2 + +-- Make sure the rule LHS is of the form +-- +-- f2 @c @c d1 d2 and not f2 @c @c d d +{-# SPECIALISE f2 :: Eq c => c -> c -> Int #-} + +-------------------------------------------------------------------------------- + +f3 :: ( Eq a, forall x. Eq x => Eq ( f x ) ) => f a -> Bool +f3 z = z == z + +-- Discharge the quantified constraint but keep the 'Eq' constraint +{-# SPECIALISE f3 :: Eq c => [ c ] -> Bool #-} + +-- Discharge the 'Eq' constraint but keep the quantified constraint +{-# SPECIALISE f3 :: ( forall y. Eq y => Eq ( g y ) ) => g Int -> Bool #-} + +-------------------------------------------------------------------------------- + +f4 :: Monad m => a -> m a +f4 = return + +-- Check we can deal with locally quantified variables in constraints, +-- in this case 'Monad (ST s)'. +{-# SPECIALISE f4 :: b -> ST s b #-} + +-------------------------------------------------------------------------------- ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -502,6 +502,7 @@ test('T23491d', [extra_files(['T23491.hs']), grep_errmsg(r'Static argument')], m test('T23074', normal, compile, ['-O -ddump-rules']) test('T23272', [only_ways(['ghci']), extra_hc_opts('-fno-unoptimized-core-for-interpreter -O')], ghci_script, ['T23272.script']) test('T23567', [extra_files(['T23567A.hs'])], multimod_compile, ['T23567', '-O -v0']) +test('DsSpecPragmas', normal, compile, ['-O -ddump-rules']) # The -ddump-simpl of T22404 should have no let-bindings test('T22404', [only_ways(['optasm']), check_errmsg(r'let') ], compile, ['-ddump-simpl -dsuppress-uniques']) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -738,6 +738,7 @@ test('ExplicitSpecificityA1', normal, compile, ['']) test('ExplicitSpecificityA2', normal, compile, ['']) test('ExplicitSpecificity4', normal, compile, ['']) test('RuleEqs', normal, compile, ['']) +test('SpecPragmas', normal, compile, ['']) test('T17775-viewpats-a', normal, compile, ['']) test('T17775-viewpats-b', normal, compile_fail, ['']) test('T17775-viewpats-c', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ca0f8c9df86f74a1965c21705fa9e38627160a1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ca0f8c9df86f74a1965c21705fa9e38627160a1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 14:39:10 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Tue, 28 Jan 2025 09:39:10 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] 23 commits: AArch64: Simplify BL instruction Message-ID: <6798ec0e21e9c_3de785c059431319@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 786303f5 by Sven Tennie at 2025-01-28T15:07:02+01:00 AArch64: Simplify BL instruction The BL constructor carried unused data in its third argument. (cherry picked from commit eb612fbc8e94d50c9895c02f3d6ee076f61b7773) - - - - - b8cb2249 by Sven Tennie at 2025-01-28T15:07:02+01:00 AArch64: Implement switch/jump tables (#19912) This improves the performance of Cmm switch statements (compared to a chain of if statements.) (cherry picked from commit 1d22611665117131d1c7c3c0287696e8efcc88f2) - - - - - 4621dab0 by Andrzej Rybczak at 2025-01-28T15:07:02+01:00 Fix typo in the @since annotation of annotateIO (cherry picked from commit 55609880c3eeda2c13859c10c157d7df05496288) - - - - - 397b2a2a by Cristiano Moraes at 2025-01-28T15:07:02+01:00 configure: Find C++ probing when GCC version is the latest but G++ is old #23118 (cherry picked from commit 78ad81ecef846f73fee0f6c1a86cd6f19aa29b21) - - - - - cf2b4a95 by sheaf at 2025-01-28T15:07:02+01:00 LLVM: use sse4.2 instead of sse42 LLVM expects the former instead of the latter since version 3.4. Fixes #25019 (cherry picked from commit 694489edf35c35b29fbdf09a8e3fdc404469858f) - - - - - 501b0335 by sheaf at 2025-01-28T15:07:02+01:00 LLVM: make SSE4.2 imply +popcnt For consistency with the NCG as well as with Clang and GCC, we make the SSE4.2 feature flag imply +popcnt when using the LLVM backend. Fixes #25353 (cherry picked from commit 06ae85071b95376bd1eb354f7cc7901aed45b625) - - - - - b4a4848f by Ben Gamari at 2025-01-28T15:07:02+01:00 testsuite: Normalise trailing digits from hole fits output The type variables in the holes fit output from `abstract_refinement_hole_fits` is quite sensitive to compiler configuration. Specifically, a slight change in the inlining behavior of `throw` changes type variable naming in `(>>=)` and a few others. Ideally we would make hole fits output more deterministic but in the meantime we simply normalise this difference away as it not relevant to the test's goal. (cherry picked from commit d029f1700effa626ff622700b198ed49ee8b6c19) - - - - - 3af5c6c1 by Ben Gamari at 2025-01-28T15:07:02+01:00 base: Add test for #25066 (cherry picked from commit da5d7d0d8bde06a1c29612fd17b6a579fc523036) - - - - - 7569f321 by Ben Gamari at 2025-01-28T15:07:02+01:00 base: Fix #25066 As noted in #25066, the exception backtrace proposal introduced a rather subtle performance regression due to simplification producing Core which the demand analyser concludes may diverge with a precise exception. The nature of the problem is more completely described in the new Note [Hiding precise exception signature in throw]. The (rather hacky) solution we use here hides the problematic optimisation through judicious use of `noinline`. Ultimately however we will want a more principled solution (e.g. #23847). Fixes #255066 CLC proposal: https://github.com/haskell/core-libraries-committee/issues/290 Metric Decrease: T9872d (cherry picked from commit eb7ddae1a2b3fb1be1cd635849516a6398327b29) - - - - - 0dc9b9d9 by Ben Gamari at 2025-01-28T15:07:02+01:00 base: Improve documentation of Control.Exception.Backtrace (cherry picked from commit 0060ece762d7a936daf28195676b6162c30dc845) - - - - - 58447b1b by Andreas Klebinger at 2025-01-28T15:07:02+01:00 9.10.2 - more changelogs - - - - - 6dd945b9 by Cheng Shao at 2025-01-28T15:07:02+01:00 Revert "compiler: start deprecating cmmToRawCmmHook" This reverts commit 1c064ef1f3e1aa2afc996e962ad53effa99ec5f4. Turns out the GHC-WPC project does use it to observe Cmm in the pipeline, see #25363. (cherry picked from commit 525d451e175c7d6acfa968ce99d8d3fc7a8af0c7) - - - - - ba420fdd by Cheng Shao at 2025-01-28T15:07:02+01:00 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. (cherry picked from commit 5bcfefd5bb73c18a9bad63d1813968832b696f9a) - - - - - 47977ab7 by Zubin Duggal at 2025-01-28T15:07:02+01:00 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit d83f5bd730a8aef37d8a38b3560590d9798f8e45) (cherry picked from commit 280b627869da55a22b4b9a3458e6115b06b5fff4) - - - - - 9acb4a30 by Zubin Duggal at 2025-01-28T15:07:02+01:00 release: copy zip files into the correct directory Fixes #25446 (cherry picked from commit 346e4cd1903b2cbcc9bb7c39652666c513eb2a59) - - - - - 3a076771 by Zubin Duggal at 2025-01-28T15:07:02+01:00 release: Sign .gz bindists too Fixes #25447 (cherry picked from commit bbdbe2254df1bfc9157cfb409afc93f8157712cd) - - - - - 9a49df8d by Sebastian Graf at 2025-01-28T15:07:02+01:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. (cherry picked from commit 00d58ae18a7ce8db6b2d57261a08ba8c1c2549b5) - - - - - 3724a021 by Andreas Klebinger at 2025-01-28T15:07:02+01:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 (cherry picked from commit 7f90f319531c312a074d21688b05f664f0d173fc) - - - - - 660ad907 by Ben Gamari at 2025-01-28T15:07:02+01:00 rts: Allow ExecPage to allocate anywhere in address space Currently the ExecPage facility has two users: * GHCi, for constructing info tables, and * the adjustor allocation path Despite neither of these have any spatial locality constraints ExecPage was using the linker's `mmapAnonForLinker`, which tries hard to ensure that mappings end up nearby the executable image. This makes adjustor allocation needlessly subject to fragmentation concerns. We now instead return less constrained mappings, improving the robustness of the mechanism. Addresses #25503. (cherry picked from commit a104508d2ea5bbc61c4a756dca42fc043b329709) - - - - - 8cb92d62 by Ben Gamari at 2025-01-28T15:07:02+01:00 base: Fix incorrect mentions of GHC.Internal.Numeric These were incorrectly changed by the automated refactoring of the `ghc-internal` migration. Fixes #25521. (cherry picked from commit c3fc9b861fd00a85a4fcbd9960b8242d9fabe04b) - - - - - 2e3ce607 by Arnaud Spiwack at 2025-01-28T15:07:02+01:00 Add test for #25428 (cherry picked from commit e6c957e49260230c4cb297aeec16be3293381fb7) - - - - - 290fe2f2 by Rodrigo Mesquita at 2025-01-28T15:10:44+01:00 ghc-internal: Derive version from ghc's version Fixes #25005 This also introduces ghc-experimental.cabal.in (cherry picked from commit 05116c83ec0d74bc66fa50181df8f577a09f24a6) - - - - - cc7a06ae by Andreas Klebinger at 2025-01-28T15:11:42+01:00 Change versionig of ghc-experimental to follow ghc versions. Just like ghc-internal it will now use the @ProjectVersionForLib@ macro for versioning. This means for ghc=9.10.1, ghc-experimental's version will be 9.1001.0 and so on. This fixes #25289 (cherry picked from commit 2293c0b7d709df7be04f596e72c97fd2435c4134) - - - - - 30 changed files: - .gitignore - .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py - .gitlab/rel_eng/recompress-all - .gitlab/rel_eng/upload.sh - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline/Execute.hs - docs/users_guide/9.10.2-notes.rst - hadrian/cfg/system.config.in - hadrian/src/Oracles/Setting.hs - hadrian/src/Rules/Generate.hs - libraries/base/base.cabal → libraries/base/base.cabal.in - libraries/base/changelog.md - libraries/base/src/Control/Exception/Backtrace.hs - libraries/base/src/Data/Char.hs - libraries/base/src/Data/Semigroup.hs - libraries/base/src/Prelude.hs - + libraries/base/tests/T25066.hs - + libraries/base/tests/T25066.stderr - libraries/base/tests/all.T - libraries/ghc-experimental/ghc-experimental.cabal → libraries/ghc-experimental/ghc-experimental.cabal.in - libraries/ghc-heap/ghc-heap.cabal.in - libraries/ghc-internal/ghc-internal.cabal → libraries/ghc-internal/ghc-internal.cabal.in - libraries/ghc-internal/src/GHC/Internal/Base.hs - libraries/ghc-internal/src/GHC/Internal/Exception.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d7d9aa07406a69daffeeedca3bb20969ba0b383e...cc7a06ae7b433a58b4d395fde442e3a5304f71c4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d7d9aa07406a69daffeeedca3bb20969ba0b383e...cc7a06ae7b433a58b4d395fde442e3a5304f71c4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 14:43:53 2025 From: gitlab at gitlab.haskell.org (Serge S. Gulin (@gulin.serge)) Date: Tue, 28 Jan 2025 09:43:53 -0500 Subject: [Git][ghc/ghc][wip/T24603] Support for ARM64 Windows (LLVM-enabled) (fixes #24603) Message-ID: <6798ed291184d_3de785c05e44076b@gitlab.mail> Serge S. Gulin pushed to branch wip/T24603 at Glasgow Haskell Compiler / GHC Commits: 1e528596 by Serge S. Gulin at 2025-01-28T17:42:51+03:00 Support for ARM64 Windows (LLVM-enabled) (fixes #24603) submodule Co-authored-by: Cheng Shao <terrorjack at type.dance> Co-authored-by: Dmitrii Egorov <egorov.d.i at icloud.com> Co-authored-by: Andrei Borzenkov <root at sandwitch.dev> - - - - - 17 changed files: - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs - hadrian/cabal.project - libraries/Cabal - libraries/Win32 - libraries/base/src/System/CPUTime/Windows.hsc - libraries/base/tests/perf/encodingAllocations.hs - libraries/directory - libraries/haskeline - libraries/process - libraries/unix - llvm-targets - m4/ghc_tables_next_to_code.m4 - rts/StgCRun.c - rts/win32/veh_excn.c - utils/hsc2hs - utils/llvm-targets/gen-data-layout.sh Changes: ===================================== compiler/GHC/CmmToAsm/AArch64/Instr.hs ===================================== @@ -1,4 +1,5 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} +{-# LANGUAGE CPP #-} module GHC.CmmToAsm.AArch64.Instr @@ -217,7 +218,11 @@ regUsageOfInstr platform instr = case instr of -- TODO: The zero register is currently mapped to -1 but should get it's own separate number. callerSavedRegisters :: [Reg] callerSavedRegisters +#if defined(mingw32_HOST_OS) + = map regSingle [0..17] +#else = map regSingle [0..18] +#endif ++ map regSingle [32..39] ++ map regSingle [48..63] ===================================== compiler/GHC/CmmToAsm/Reg/Linear/AArch64.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE CPP #-} + module GHC.CmmToAsm.Reg.Linear.AArch64 where import GHC.Prelude @@ -118,7 +120,11 @@ getFreeRegs :: RegClass -> FreeRegs -> [RealReg] getFreeRegs cls (FreeRegs g f) = case cls of RcFloatOrVector -> go 32 f 31 +#if defined(mingw32_HOST_OS) + RcInteger -> go 0 g 17 +#else RcInteger -> go 0 g 18 +#endif where go _ _ i | i < 0 = [] go off x i | testBit x i = RealRegSingle (off + i) : (go off x $! i - 1) ===================================== hadrian/cabal.project ===================================== @@ -8,7 +8,7 @@ index-state: 2024-10-30T22:56:00Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 -allow-newer: unordered-containers:template-haskell +allow-newer: unordered-containers:template-haskell, splitmix:base, hashable:base, cryptohash-sha256:base -- N.B. Compile with -O0 since this is not a performance-critical executable -- and the Cabal takes nearly twice as long to build with -O1. See #16817. ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 269fd808e5d80223a229b6b19edfe6f5b109007a +Subproject commit 682c54a9e8127c79e714545dbf493bb5de470945 ===================================== libraries/Win32 ===================================== @@ -1 +1 @@ -Subproject commit 027cbcf0de25d681823ea92fb545a2604c3a6a8b +Subproject commit f340d2c3d846fce73117dd2548ad1bf0c56ceb9d ===================================== libraries/base/src/System/CPUTime/Windows.hsc ===================================== @@ -60,7 +60,7 @@ type HANDLE = () #if defined(i386_HOST_ARCH) foreign import stdcall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import stdcall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt -#elif defined(x86_64_HOST_ARCH) +#elif defined(x86_64_HOST_ARCH) || defined(aarch64_HOST_ARCH) foreign import ccall unsafe "GetCurrentProcess" getCurrentProcess :: IO (Ptr HANDLE) foreign import ccall unsafe "GetProcessTimes" getProcessTimes :: Ptr HANDLE -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> Ptr FILETIME -> IO CInt #else ===================================== libraries/base/tests/perf/encodingAllocations.hs ===================================== @@ -13,13 +13,13 @@ import Distribution.Simple.Utils main :: IO () -main = withTempFile "." "encodingAllocations.tmp" (const $ loop 1000000) +main = withTempFile "encodingAllocations.tmp" (loop 1000000) -loop :: Int -> Handle -> IO () -loop 0 !_ = pure () -loop !n !h = do +loop :: Int -> FilePath -> Handle -> IO () +loop 0 !_ !_ = pure () +loop !n !fp !h = do hPutChar h $! dummy_char n - loop (n-1) h + loop (n-1) fp h -- unsafe efficient version of `chr` my_chr :: Int -> Char ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 005fa061171a55d35ce8dfe936cf3703525a8616 +Subproject commit eb40bbebcaf86153bbc60772fb2e0466d35c95c4 ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 5f4bf62bf1f4846ad0b8d1fa9d45f902e3934511 +Subproject commit 5f1a790a5db1cb3708d105d4f532c32fcbeb4296 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 9c3bfc214c72bbd0c8a30a1c41465deed0feaf47 +Subproject commit fbbe60718736999db701c12528c85cbc605ab4fb ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 74ae1c0d9dd1518434f7d6cd3e63d7769599e0f9 +Subproject commit 9208d3a5809476e64b9a387a6000821083d1ebfd ===================================== llvm-targets ===================================== @@ -1,4 +1,5 @@ [("x86_64-unknown-windows-gnu", ("e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "")) +,("aarch64-unknown-windows-gnu", ("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32", "generic", "+v8a +fp-armv8 +neon")) ,("arm-unknown-linux-gnueabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm7tdmi", "+strict-align")) ,("arm-unknown-linux-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ,("arm-unknown-linux-musleabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ===================================== m4/ghc_tables_next_to_code.m4 ===================================== @@ -22,8 +22,13 @@ AC_DEFUN([GHC_TABLES_NEXT_TO_CODE], AC_MSG_RESULT([no]) ;; *) - TablesNextToCodeDefault=YES - AC_MSG_RESULT([yes]) + if test "$TargetOS" = "mingw32" && test "$TargetArch" = "aarch64"; then + TablesNextToCodeDefault=NO + AC_MSG_RESULT([no]) + else + TablesNextToCodeDefault=YES + AC_MSG_RESULT([yes]) + fi ;; esac ;; ===================================== rts/StgCRun.c ===================================== @@ -863,8 +863,12 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { */ "br %1\n\t" +#if defined(mingw32_HOST_OS) + ".globl " STG_RETURN "\n" +#else ".globl " STG_RETURN "\n\t" -#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) +#endif +#if !defined(ios_HOST_OS) && !defined(darwin_HOST_OS) && !defined(mingw32_HOST_OS) ".type " STG_RETURN ", %%function\n" #endif STG_RETURN ":\n\t" ===================================== rts/win32/veh_excn.c ===================================== @@ -287,6 +287,16 @@ void generateStack (EXCEPTION_POINTERS* pExceptionPointers) stackFrame.AddrStack.Offset = context->Rsp; stackFrame.AddrStack.Mode = AddrModeFlat; +#elif defined(aarch64_HOST_ARCH) + machineType = IMAGE_FILE_MACHINE_ARM64; + stackFrame.AddrPC.Offset = context->Pc; + stackFrame.AddrPC.Mode = AddrModeFlat; + + stackFrame.AddrFrame.Offset = context->Fp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + + stackFrame.AddrStack.Offset = context->Sp; + stackFrame.AddrStack.Mode = AddrModeFlat; #endif fprintf (stderr, "\n Attempting to reconstruct a stack trace...\n\n"); if (!SymInitialize (GetCurrentProcess (), NULL, true)) ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit c3b21800a67366c9591dc85a471d1dfdb1efcf29 +Subproject commit 2fab2f4cdffef12afe561ef03f5ebdace7dbae67 ===================================== utils/llvm-targets/gen-data-layout.sh ===================================== @@ -27,6 +27,7 @@ TARGETS=( # Windows "x86_64-unknown-windows-gnu" + "aarch64-unknown-windows-gnu" ######################### # Linux View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e5285963863bac9191ddf7e5f247b2d60699601 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e5285963863bac9191ddf7e5f247b2d60699601 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 15:04:31 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 28 Jan 2025 10:04:31 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/slide_x_0 Message-ID: <6798f1ff92432_3de7855f422c55833@gitlab.mail> Matthew Pickering pushed new branch wip/slide_x_0 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/slide_x_0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 15:04:58 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Tue, 28 Jan 2025 10:04:58 -0500 Subject: [Git][ghc/ghc][wip/slide_x_0] 8 commits: Rework built-in and punned names (#25174, #25179, #25180, #25182) Message-ID: <6798f21a8543b_3de785894e005601b@gitlab.mail> Matthew Pickering pushed to branch wip/slide_x_0 at Glasgow Haskell Compiler / GHC Commits: 51e3ec83 by Vladislav Zavialov at 2025-01-22T20:41:32+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 85c60aea by Teo Camarasu at 2025-01-23T18:06:21-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4495e48f by Brandon Chinn at 2025-01-24T11:54:24-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 4f8fc11e by Brandon Chinn at 2025-01-24T11:54:24-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - e7ab778f by Matthew Pickering at 2025-01-24T11:55:01-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - c3593101 by Sylvain Henry at 2025-01-24T23:12:20-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 70f7741a by Jens Petersen at 2025-01-24T23:12:58-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - d811e356 by Matthew Pickering at 2025-01-28T15:04:48+00:00 bytecode: Do not generate `SLIDE x 0` instructions SLIDE x 0 is a no-op as it means to shift x elements of the stack by no spaces. In the interpreter, this results in a loop which copies an array element into the same place. I have instrumented GHCi to count how many of these instructions are interpreted. The workload was `ghc` compiling two simple modules. Total no-op slides: 7793476 Total slides: 11413289 Percentage useless (slides): 68% Percentage uselss of total instructions: 9% - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Config/Core/Rules.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/HsToCore/Foreign/JavaScript.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser/Errors/Ppr.hs - compiler/GHC/Parser/HaddockLex.x - compiler/GHC/Parser/Header.hs - compiler/GHC/Parser/Lexer.x - + compiler/GHC/Parser/Lexer/Interface.hs - + compiler/GHC/Parser/Lexer/String.x - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Env.hs - compiler/GHC/Runtime/Interpreter/JS.hs - compiler/GHC/StgToByteCode.hs - compiler/GHC/StgToJS/Linker/Linker.hs - compiler/GHC/StgToJS/Linker/Utils.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Ppr.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Splice.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d736522d5795cdabfa83b56d92f7b6588293587d...d811e35670a1e5df0e7a629da8889dc0eaf0c7ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d736522d5795cdabfa83b56d92f7b6588293587d...d811e35670a1e5df0e7a629da8889dc0eaf0c7ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 15:35:36 2025 From: gitlab at gitlab.haskell.org (Vladislav Zavialov (@int-index)) Date: Tue, 28 Jan 2025 10:35:36 -0500 Subject: [Git][ghc/ghc][wip/int-index/ghc-9.10-backport-25182-25174] Fixes for built-in names (#25182, #25174) Message-ID: <6798f9484b762_3de785e47fc8788e1@gitlab.mail> Vladislav Zavialov pushed to branch wip/int-index/ghc-9.10-backport-25182-25174 at Glasgow Haskell Compiler / GHC Commits: cc4470be by Vladislav Zavialov at 2025-01-28T18:32:38+03:00 Fixes for built-in names (#25182, #25174) * In isBuiltInOcc_maybe, do not match on "FUN" (#25174) * Classify MkSolo as UserSyntax (#25182) Extracted from 51e3ec839c378f0da7052278a56482f0349e9bc7 - - - - - 15 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Types/Name/Ppr.hs - docs/users_guide/9.10.2-notes.rst - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - + testsuite/tests/rename/should_compile/ReExportTuples.hs - + testsuite/tests/rename/should_compile/T25182.hs - testsuite/tests/rename/should_compile/all.T - + testsuite/tests/th/FunNameTH.hs - testsuite/tests/th/T13776.hs - testsuite/tests/th/T13776.stderr - + testsuite/tests/th/T25174.hs - testsuite/tests/th/all.T - testsuite/tests/typecheck/should_compile/holes.stderr - testsuite/tests/typecheck/should_compile/holes3.stderr - testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -78,6 +78,7 @@ module GHC.Builtin.Types ( promotedTupleDataCon, unitTyCon, unitDataCon, unitDataConId, unitTy, unitTyConKey, soloTyCon, + soloDataConName, pairTyCon, mkPromotedPairTy, isPromotedPairType, unboxedUnitTy, unboxedUnitTyCon, unboxedUnitDataCon, @@ -896,7 +897,6 @@ isBuiltInOcc_maybe occ = ":" -> Just consDataConName -- function tycon - "FUN" -> Just fUNTyConName "->" -> Just unrestrictedFunTyConName -- tuple data/tycon @@ -1055,40 +1055,36 @@ isPunOcc_maybe mod occ isCTupleOcc_maybe mod occ <|> isSumTyOcc_maybe mod occ -mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName --- No need to cache these, the caching is done in mk_tuple -mkTupleOcc ns Boxed ar = mkOccName ns (mkBoxedTupleStr ns ar) -mkTupleOcc ns Unboxed ar = mkOccName ns (mkUnboxedTupleStr ns ar) +mkTupleOcc :: NameSpace -> Boxity -> Arity -> (OccName, BuiltInSyntax) +mkTupleOcc ns b ar = (mkOccName ns str, built_in) + where (str, built_in) = mkTupleStr' ns b ar mkCTupleOcc :: NameSpace -> Arity -> OccName mkCTupleOcc ns ar = mkOccName ns (mkConstraintTupleStr ar) mkTupleStr :: Boxity -> NameSpace -> Arity -> String -mkTupleStr Boxed = mkBoxedTupleStr -mkTupleStr Unboxed = mkUnboxedTupleStr - -mkBoxedTupleStr :: NameSpace -> Arity -> String -mkBoxedTupleStr ns 0 - | isDataConNameSpace ns = "()" - | otherwise = "Unit" -mkBoxedTupleStr ns 1 - | isDataConNameSpace ns = "MkSolo" -- See Note [One-tuples] - | otherwise = "Solo" -mkBoxedTupleStr ns ar - | isDataConNameSpace ns = '(' : commas ar ++ ")" - | otherwise = "Tuple" ++ showInt ar "" - - -mkUnboxedTupleStr :: NameSpace -> Arity -> String -mkUnboxedTupleStr ns 0 - | isDataConNameSpace ns = "(##)" - | otherwise = "Unit#" -mkUnboxedTupleStr ns 1 - | isDataConNameSpace ns = "(# #)" -- See Note [One-tuples] - | otherwise = "Solo#" -mkUnboxedTupleStr ns ar - | isDataConNameSpace ns = "(#" ++ commas ar ++ "#)" - | otherwise = "Tuple" ++ show ar ++ "#" +mkTupleStr b ns ar = str + where (str, _) = mkTupleStr' ns b ar + +mkTupleStr' :: NameSpace -> Boxity -> Arity -> (String, BuiltInSyntax) +mkTupleStr' ns Boxed 0 + | isDataConNameSpace ns = ("()", BuiltInSyntax) + | otherwise = ("Unit", UserSyntax) +mkTupleStr' ns Boxed 1 + | isDataConNameSpace ns = ("MkSolo", UserSyntax) -- See Note [One-tuples] + | otherwise = ("Solo", UserSyntax) +mkTupleStr' ns Boxed ar + | isDataConNameSpace ns = ('(' : commas ar ++ ")", BuiltInSyntax) + | otherwise = ("Tuple" ++ showInt ar "", UserSyntax) +mkTupleStr' ns Unboxed 0 + | isDataConNameSpace ns = ("(##)", BuiltInSyntax) + | otherwise = ("Unit#", UserSyntax) +mkTupleStr' ns Unboxed 1 + | isDataConNameSpace ns = ("(# #)", BuiltInSyntax) -- See Note [One-tuples] + | otherwise = ("Solo#", UserSyntax) +mkTupleStr' ns Unboxed ar + | isDataConNameSpace ns = ("(#" ++ commas ar ++ "#)", BuiltInSyntax) + | otherwise = ("Tuple" ++ show ar ++ "#", UserSyntax) mkConstraintTupleStr :: Arity -> String mkConstraintTupleStr 0 = "CUnit" @@ -1244,10 +1240,10 @@ mk_tuple Boxed arity = (tycon, tuple_con) boxity = Boxed modu = gHC_INTERNAL_TUPLE - tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq - (ATyCon tycon) UserSyntax - dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq - (AConLike (RealDataCon tuple_con)) BuiltInSyntax + tc_name = mkWiredInName modu occ tc_uniq (ATyCon tycon) built_in + where (occ, built_in) = mkTupleOcc tcName boxity arity + dc_name = mkWiredInName modu occ dc_uniq (AConLike (RealDataCon tuple_con)) built_in + where (occ, built_in) = mkTupleOcc dataName boxity arity tc_uniq = mkTupleTyConUnique boxity arity dc_uniq = mkTupleDataConUnique boxity arity @@ -1278,10 +1274,10 @@ mk_tuple Unboxed arity = (tycon, tuple_con) boxity = Unboxed modu = gHC_TYPES - tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq - (ATyCon tycon) UserSyntax - dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq - (AConLike (RealDataCon tuple_con)) BuiltInSyntax + tc_name = mkWiredInName modu occ tc_uniq (ATyCon tycon) built_in + where (occ, built_in) = mkTupleOcc tcName boxity arity + dc_name = mkWiredInName modu occ dc_uniq (AConLike (RealDataCon tuple_con)) built_in + where (occ, built_in) = mkTupleOcc dataName boxity arity tc_uniq = mkTupleTyConUnique boxity arity dc_uniq = mkTupleDataConUnique boxity arity @@ -1345,6 +1341,9 @@ soloTyCon = tupleTyCon Boxed 1 soloTyConName :: Name soloTyConName = tyConName soloTyCon +soloDataConName :: Name +soloDataConName = tupleDataConName Boxed 1 + pairTyCon :: TyCon pairTyCon = tupleTyCon Boxed 2 ===================================== compiler/GHC/Types/Name/Ppr.hs ===================================== @@ -123,7 +123,8 @@ mkQualName env = qual_name where , fUNTyConName, unrestrictedFunTyConName , oneDataConName , listTyConName - , manyDataConName ] + , manyDataConName + , soloDataConName ] || isJust (isTupleTyOcc_maybe mod occ) || isJust (isSumTyOcc_maybe mod occ) ===================================== docs/users_guide/9.10.2-notes.rst ===================================== @@ -68,6 +68,10 @@ Compiler specialization rules was added. It was actually added ghc-9.10.1 already but mistakenly not mentioned in the 9.10.1 changelog. +- Fixed re-exports of ``MkSolo`` (:ghc-ticket:`25182`) + +- Fixed the behavior of ``Language.Haskell.TH.mkName "FUN"`` (:ghc-ticket:`25174`) + JavaScript backend ~~~~~~~~~~~~~~~~~~ ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout ===================================== @@ -5481,7 +5481,7 @@ module Prelude.Experimental where data List a = ... pattern Solo :: forall a. a -> Solo a type Solo :: * -> * - data Solo a = ... + data Solo a = MkSolo a type Solo# :: forall (k :: GHC.Types.RuntimeRep). TYPE k -> TYPE (GHC.Types.TupleRep '[k]) data Solo# a = ... type Sum10# :: forall (k0 :: GHC.Types.RuntimeRep) (k1 :: GHC.Types.RuntimeRep) (k2 :: GHC.Types.RuntimeRep) (k3 :: GHC.Types.RuntimeRep) (k4 :: GHC.Types.RuntimeRep) (k5 :: GHC.Types.RuntimeRep) (k6 :: GHC.Types.RuntimeRep) (k7 :: GHC.Types.RuntimeRep) (k8 :: GHC.Types.RuntimeRep) (k9 :: GHC.Types.RuntimeRep). TYPE k0 -> TYPE k1 -> TYPE k2 -> TYPE k3 -> TYPE k4 -> TYPE k5 -> TYPE k6 -> TYPE k7 -> TYPE k8 -> TYPE k9 -> TYPE (GHC.Types.SumRep [k0, k1, k2, k3, k4, k5, k6, k7, k8, k9]) ===================================== testsuite/tests/rename/should_compile/ReExportTuples.hs ===================================== @@ -0,0 +1,4 @@ +module ReExportTuples (module Data.Tuple) where +-- Re-export the entire Data.Tuple module at once + +import Data.Tuple ===================================== testsuite/tests/rename/should_compile/T25182.hs ===================================== @@ -0,0 +1,6 @@ +module T25182 where + +import ReExportTuples + +s :: Solo String +s = MkSolo "hello" \ No newline at end of file ===================================== testsuite/tests/rename/should_compile/all.T ===================================== @@ -223,3 +223,4 @@ test('T22478a', req_th, compile, ['']) test('RecordWildCardDeprecation', normal, multimod_compile, ['RecordWildCardDeprecation', '-Wno-duplicate-exports']) test('T14032b', normal, compile_and_run, ['']) test('T14032d', normal, compile, ['']) +test('T25182', [extra_files(['ReExportTuples.hs'])], multimod_compile, ['T25182', '-v0']) ===================================== testsuite/tests/th/FunNameTH.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE TemplateHaskell #-} + +module FunNameTH where + +import Language.Haskell.TH + +f1 :: forall a. $(conT (mkName "->")) [a] Bool +f1 = null + +f2 :: forall a. $(conT ''(->)) [a] Bool +f2 = null \ No newline at end of file ===================================== testsuite/tests/th/T13776.hs ===================================== @@ -10,6 +10,9 @@ spliceTy1 = (1,2) spliceTy2 :: $(conT ''[] `appT` conT ''Int) spliceTy2 = [] +spliceTy3 :: $(conT ''(->)) [Int] Int +spliceTy3 = sum + spliceExp1 :: (Int, Int) spliceExp1 = $(conE '(,) `appE` litE (integerL 1) `appE` litE (integerL 1)) ===================================== testsuite/tests/th/T13776.stderr ===================================== @@ -1,12 +1,13 @@ +T13776.hs:13:15-27: Splicing type conT ''(->) ======> (->) T13776.hs:10:15-43: Splicing type conT ''[] `appT` conT ''Int ======> [] Int T13776.hs:7:15-62: Splicing type conT ''(,) `appT` conT ''Int `appT` conT ''Int ======> (,) Int Int -T13776.hs:14:15-75: Splicing expression +T13776.hs:17:15-75: Splicing expression conE '(,) `appE` litE (integerL 1) `appE` litE (integerL 1) ======> (,) 1 1 -T13776.hs:17:15-24: Splicing expression conE '[] ======> [] -T13776.hs:20:13-62: Splicing pattern +T13776.hs:20:15-24: Splicing expression conE '[] ======> [] +T13776.hs:23:13-62: Splicing pattern conP '(,) [litP (integerL 1), litP (integerL 1)] ======> (,) 1 1 -T13776.hs:23:13-25: Splicing pattern conP '[] [] ======> [] +T13776.hs:26:13-25: Splicing pattern conP '[] [] ======> [] ===================================== testsuite/tests/th/T25174.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE TemplateHaskell #-} + +module T25174 where + +import Language.Haskell.TH + +data FUN a b = MkFUN (a -> b) + +evenFUN :: $(conT (mkName "FUN")) Int Bool +evenFUN = MkFUN even + ===================================== testsuite/tests/th/all.T ===================================== @@ -614,3 +614,5 @@ test('T24557e', normal, compile, ['']) test('T24702a', normal, compile, ['']) test('T24702b', normal, compile, ['']) test('T24837', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('T25174', normal, compile, ['']) +test('FunNameTH', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_compile/holes.stderr ===================================== @@ -88,7 +88,6 @@ holes.hs:11:15: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] Nothing :: forall a. Maybe a Just :: forall a. a -> Maybe a [] :: forall a. [a] - MkSolo :: forall a. a -> Solo a asTypeOf :: forall a. a -> a -> a id :: forall a. a -> a until :: forall a. (a -> Bool) -> (a -> a) -> a -> a ===================================== testsuite/tests/typecheck/should_compile/holes3.stderr ===================================== @@ -91,7 +91,6 @@ holes3.hs:11:15: error: [GHC-88464] Nothing :: forall a. Maybe a Just :: forall a. a -> Maybe a [] :: forall a. [a] - MkSolo :: forall a. a -> Solo a asTypeOf :: forall a. a -> a -> a id :: forall a. a -> a until :: forall a. (a -> Bool) -> (a -> a) -> a -> a ===================================== testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr ===================================== @@ -1,6 +1,5 @@ [1 of 2] Compiling ValidHoleFits ( ValidHoleFits.hs, ValidHoleFits.o ) [2 of 2] Compiling Foo ( valid_hole_fits.hs, valid_hole_fits.o ) - valid_hole_fits.hs:9:6: warning: [GHC-88464] [-Wdeferred-out-of-scope-variables (in -Wdefault)] Variable not in scope: putStrLn :: String -> IO () Suggested fixes: @@ -148,9 +147,6 @@ valid_hole_fits.hs:34:11: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] with Just @Bool (imported from ‘Data.Maybe’ at valid_hole_fits.hs:5:1-17 (and originally defined in ‘GHC.Internal.Maybe’)) - MkSolo :: forall a. a -> Solo a - with MkSolo @Bool - (bound at ) id :: forall a. a -> a with id @Bool (imported from ‘Prelude’ at valid_hole_fits.hs:3:1-40 @@ -259,3 +255,4 @@ valid_hole_fits.hs:41:8: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] with mempty @(String -> IO ()) (imported from ‘Prelude’ at valid_hole_fits.hs:3:1-40 (and originally defined in ‘GHC.Internal.Base’)) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc4470be68fa11ce296cef0684a11c4641f85ffe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc4470be68fa11ce296cef0684a11c4641f85ffe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 16:44:56 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 28 Jan 2025 11:44:56 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/romes/25170-simpl Message-ID: <67990988c3827_76984a509c86881@gitlab.mail> Rodrigo Mesquita pushed new branch wip/romes/25170-simpl at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/25170-simpl You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 17:04:11 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 28 Jan 2025 12:04:11 -0500 Subject: [Git][ghc/ghc][wip/romes/25170-simpl] rules twice idea 3 Message-ID: <67990e0ba23f3_7698c1db80917a0@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/25170-simpl at Glasgow Haskell Compiler / GHC Commits: 7ce549d0 by Rodrigo Mesquita at 2025-01-28T17:03:59+00:00 rules twice idea 3 - - - - - 1 changed file: - compiler/GHC/Core/Opt/Simplify/Iteration.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -2307,17 +2307,28 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args ---------- Try rewrite RULES, if ai_rewrite = TryRules -------------- -- See Note [Rewrite rules and inlining] -- See also Note [Trying rewrite rules] + rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rewrite = TryRules nr_wanted rules }) cont - | nr_wanted == 0 || no_more_args + , ai_rewrite = TryRules _nr_wanted rules }) cont + | [] <- rev_args + = -- Try rewrite rules on unsimplified arguments, then once more when all + -- arguments have been simplified (below). See Note [TODO] + let (unsimp_info, res_cont') = take_unsimpl cont + in applyRules (ai_args unsimp_info) res_cont' + + | no_more_args = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] - do { mb_match <- tryRules env rules fun (reverse rev_args) cont - ; case mb_match of - Just (env', rhs, cont') -> simplExprF env' rhs cont' - Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont } + applyRules rev_args cont + where + applyRules rev_args' cont' = do + mb_match <- tryRules env rules fun (reverse rev_args') cont' + case mb_match of + Just (env', rhs, cont'') -> simplExprF env' rhs cont'' + Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont' + -- If we have run out of arguments, just try the rules; there might -- be some with lower arity. Casts get in the way -- they aren't -- allowed on rule LHSs @@ -2326,6 +2337,18 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args ApplyToVal {} -> False _ -> True + take_unsimpl ApplyToVal { sc_arg = arg, sc_hole_ty = fun_ty, sc_cont = k } + | (i, k') <- take_unsimpl k + = (addValArgTo i arg fun_ty, k') + take_unsimpl ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = k } + | (i, k') <- take_unsimpl k + = (addTyArgTo i arg_ty hole_ty, k') + take_unsimpl CastIt { sc_co = co, sc_cont = k } + | (i, k') <- take_unsimpl k + = (addCastTo i co, k') + take_unsimpl k + = (info, k) + ---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt { sc_co = co, sc_opt = opt, sc_cont = cont }) = rebuildCall env (addCastTo info co') cont View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ce549d0ebc2e8d267d18da7f29a396bb28f4602 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ce549d0ebc2e8d267d18da7f29a396bb28f4602 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 17:16:23 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Tue, 28 Jan 2025 12:16:23 -0500 Subject: [Git][ghc/ghc][wip/romes/25170-simpl] rules twice idea 3 Message-ID: <679910e751b7f_7698dd84fc992b8@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/25170-simpl at Glasgow Haskell Compiler / GHC Commits: 00ee0bc0 by Rodrigo Mesquita at 2025-01-28T17:16:11+00:00 rules twice idea 3 - - - - - 1 changed file: - compiler/GHC/Core/Opt/Simplify/Iteration.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -2307,17 +2307,28 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args ---------- Try rewrite RULES, if ai_rewrite = TryRules -------------- -- See Note [Rewrite rules and inlining] -- See also Note [Trying rewrite rules] + rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rewrite = TryRules nr_wanted rules }) cont - | nr_wanted == 0 || no_more_args + , ai_rewrite = TryRules _nr_wanted rules }) cont + | [] <- rev_args + = -- Try rewrite rules on unsimplified arguments, then once more when all + -- arguments have been simplified (below). See Note [TODO] + let (unsimp_info, res_cont') = take_unsimpl cont + in applyRules (ai_args unsimp_info) res_cont' + + | no_more_args = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] - do { mb_match <- tryRules env rules fun (reverse rev_args) cont - ; case mb_match of - Just (env', rhs, cont') -> simplExprF env' rhs cont' - Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont } + applyRules rev_args cont + where + applyRules rev_args' cont' = do + mb_match <- tryRules env rules fun (reverse rev_args') cont' + case mb_match of + Just (env', rhs, cont'') -> simplExprF env' rhs cont'' + Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont' + -- If we have run out of arguments, just try the rules; there might -- be some with lower arity. Casts get in the way -- they aren't -- allowed on rule LHSs @@ -2326,6 +2337,20 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args ApplyToVal {} -> False _ -> True + take_unsimpl ApplyToVal { sc_arg = arg, sc_hole_ty = fun_ty, sc_cont = k } + | (i, k') <- take_unsimpl k + = (addValArgTo i arg fun_ty, k') + take_unsimpl ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = k } + | (i, k') <- take_unsimpl k + = (addTyArgTo i arg_ty hole_ty, k') + take_unsimpl CastIt { sc_co = co, sc_opt = opt, sc_cont = k } + | (i, k') <- take_unsimpl k + = (addCastTo i co', k') + where -- must still simpl coercions + co' = optOutCoercion env co opt + take_unsimpl k + = (info, k) + ---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt { sc_co = co, sc_opt = opt, sc_cont = cont }) = rebuildCall env (addCastTo info co') cont View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00ee0bc075441642724255007586d2720673aa61 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00ee0bc075441642724255007586d2720673aa61 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 18:45:23 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 13:45:23 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/bump-xhtml Message-ID: <679925c3403a5_49bfc1f9ab451897@gitlab.mail> Ben Gamari pushed new branch wip/bump-xhtml at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bump-xhtml You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 18:52:51 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 13:52:51 -0500 Subject: [Git][ghc/ghc][wip/bump-xhtml] Bump hpc to 0.7.0.2 Message-ID: <67992783e608c_49bfc57b37c555c1@gitlab.mail> Ben Gamari pushed to branch wip/bump-xhtml at Glasgow Haskell Compiler / GHC Commits: 145abd31 by Ben Gamari at 2025-01-28T13:49:28-05:00 Bump hpc to 0.7.0.2 - - - - - 1 changed file: - libraries/hpc Changes: ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 9e29abb785ab4f82c37c7a4e73ec999083955b09 +Subproject commit 37c56cf932e429950a199d0b1f39796677b052c5 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/145abd31269bc38d846d530d27715ecb9e5fe7d7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/145abd31269bc38d846d530d27715ecb9e5fe7d7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 20:04:54 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 28 Jan 2025 15:04:54 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: x86 NCG: Make MOVD's output format explicit Message-ID: <67993866d9ef3_49bfc13d63047315c@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 62760367 by ARATA Mizuki at 2025-01-27T16:23:06-05:00 x86 NCG: Make MOVD's output format explicit The old design led to inference of a wrong format, losing upper bits of a vector register. Fixes #25659 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - f19ab490 by Simon Hengel at 2025-01-27T16:23:45-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - e16eae65 by Cheng Shao at 2025-01-27T21:41:39+00:00 hadrian: fix bootstrap with 9.12.1 This patch bumps hadrian index-state to fix bootstrap with 9.12.1. - - - - - 9955f737 by Jeffrey Young at 2025-01-28T15:04:38-05:00 base: add SrcLoc changes to changelog, 4.21.0.0 I accidentally dropped this in !13381 - closes #25614 See: - ea4587794b9e3a098f9c02bd6cea2294af2539ce (the 13381 commit) - Issue #25614 - - - - - 11 changed files: - .gitlab/ci.sh - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - docs/users_guide/diagnostics-as-json-schema-1_0.json - docs/users_guide/diagnostics-as-json-schema-1_1.json - hadrian/cabal.project - libraries/base/changelog.md - + testsuite/tests/simd/should_run/T25659.hs - + testsuite/tests/simd/should_run/T25659.stdout - testsuite/tests/simd/should_run/all.T Changes: ===================================== .gitlab/ci.sh ===================================== @@ -8,7 +8,7 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-27T17:45:32Z" MIN_HAPPY_VERSION="1.20" MIN_ALEX_VERSION="3.2.6" ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -1171,7 +1171,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps bitcast :: Format -> Format -> CmmExpr -> NatM Register bitcast fmt rfmt expr = do (src, e_code) <- getSomeReg expr - let code = \dst -> e_code `snocOL` (MOVD fmt (OpReg src) (OpReg dst)) + let code = \dst -> e_code `snocOL` (MOVD fmt rfmt (OpReg src) (OpReg dst)) return (Any rfmt code) toI8Reg :: Width -> CmmExpr -> NatM Register @@ -1262,7 +1262,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps code dst = exp `snocOL` -- VPBROADCAST from GPR requires AVX-512, -- so we use an additional MOVD. - (MOVD movFormat (OpReg reg) (OpReg dst)) `snocOL` + (MOVD movFormat fmt (OpReg reg) (OpReg dst)) `snocOL` (VPBROADCAST fmt fmt (OpReg dst) dst) return $ Any fmt code @@ -1272,7 +1272,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 16 FmtInt8 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLBW fmt (OpReg dst) dst) `snocOL` (PUNPCKLWD (VecFormat 8 FmtInt16) (OpReg dst) dst) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) @@ -1284,7 +1284,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 8 FmtInt16 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLWD fmt (OpReg dst) dst) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) ) @@ -1295,7 +1295,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 4 FmtInt32 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II32 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II32 fmt (OpReg reg) (OpReg dst)) `snocOL` (PSHUFD fmt (ImmInt 0x00) (OpReg dst) dst) ) @@ -1305,7 +1305,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps (reg, exp) <- getNonClobberedReg expr let fmt = VecFormat 2 FmtInt64 return $ Any fmt (\dst -> exp `snocOL` - (MOVD II64 (OpReg reg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg reg) (OpReg dst)) `snocOL` (PUNPCKLQDQ fmt (OpReg dst) dst) ) @@ -1793,16 +1793,16 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case i of 0 -> exp `snocOL` - (MOVD FF32 (OpReg r) (OpReg dst)) + (MOVD fmt II32 (OpReg r) (OpReg dst)) 1 -> exp `snocOL` (PSHUFD fmt (ImmInt 0b01_01_01_01) (OpReg r) tmp) `snocOL` -- tmp <- (r[1],r[1],r[1],r[1]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) 2 -> exp `snocOL` (PSHUFD fmt (ImmInt 0b11_10_11_10) (OpReg r) tmp) `snocOL` -- tmp <- (r[2],r[3],r[2],r[3]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) _ -> exp `snocOL` (PSHUFD fmt (ImmInt 0b11_11_11_11) (OpReg r) tmp) `snocOL` -- tmp <- (r[3],r[3],r[3],r[3]) - (MOVD FF32 (OpReg tmp) (OpReg dst)) + (MOVD fmt II32 (OpReg tmp) (OpReg dst)) return (Any II32 code) vector_int32x4_extract_sse2 _ offset = pprPanic "Unsupported offset" (pdoc platform offset) @@ -1818,10 +1818,10 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps let code dst = case lit of CmmInt 0 _ -> exp `snocOL` - (MOVD FF64 (OpReg r) (OpReg dst)) + (MOVD fmt II64 (OpReg r) (OpReg dst)) CmmInt 1 _ -> exp `snocOL` (MOVHLPS fmt r tmp) `snocOL` - (MOVD FF64 (OpReg tmp) (OpReg dst)) + (MOVD fmt II64 (OpReg tmp) (OpReg dst)) _ -> panic "Error in offset while unpacking" return (Any II64 code) vector_int64x2_extract_sse2 _ offset @@ -2103,22 +2103,22 @@ getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps = case offset of 0 -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` (MOV floatVectorFormat (OpReg tmp1) (OpReg dst)) -- MOVSS; dst <- (tmp1[0],dst[1],dst[2],dst[3]) 1 -> valExp `appOL` (vecCode tmp1) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg dst)) `snocOL` -- dst <- (val,0,0,0) (PUNPCKLQDQ vectorFormat (OpReg tmp1) dst) `snocOL` -- dst <- (dst[0],dst[1],tmp1[0],tmp1[1]) (SHUF floatVectorFormat (ImmInt 0b11_10_00_10) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[2],dst[0],tmp1[2],tmp1[3]) 2 -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) (MOVU floatVectorFormat (OpReg dst) (OpReg tmp2)) `snocOL` -- MOVUPS; tmp2 <- dst (SHUF floatVectorFormat (ImmInt 0b01_00_01_11) (OpReg tmp1) tmp2) `snocOL` -- SHUFPS; tmp2 <- (tmp2[3],tmp2[1],tmp1[0],tmp1[1]) (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp2) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp2[2],tmp2[0]) _ -> valExp `appOL` (vecCode dst) `snocOL` - (MOVD II32 (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) + (MOVD II32 vectorFormat (OpReg valReg) (OpReg tmp1)) `snocOL` -- tmp1 <- (val,0,0,0) (SHUF floatVectorFormat (ImmInt 0b11_10_01_00) (OpReg dst) tmp1) `snocOL` -- SHUFPS; tmp1 <- (tmp1[0],tmp1[1],dst[2],dst[3]) (SHUF floatVectorFormat (ImmInt 0b00_10_01_00) (OpReg tmp1) dst) -- SHUFPS; dst <- (dst[0],dst[1],tmp1[2],tmp1[0]) return $ Any vectorFormat code @@ -2139,12 +2139,12 @@ getRegister' platform _is32Bit (CmmMachOp mop [x, y, z]) = do -- ternary MachOps CmmInt 0 _ -> valExp `appOL` vecExp `snocOL` (MOVHLPS fmt vecReg tmp) `snocOL` - (MOVD II64 (OpReg valReg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg valReg) (OpReg dst)) `snocOL` (PUNPCKLQDQ fmt (OpReg tmp) dst) CmmInt 1 _ -> valExp `appOL` vecExp `snocOL` - (MOV II64 (OpReg vecReg) (OpReg dst)) `snocOL` - (MOVD II64 (OpReg valReg) (OpReg tmp)) `snocOL` + (MOVDQU fmt (OpReg vecReg) (OpReg dst)) `snocOL` + (MOVD II64 fmt (OpReg valReg) (OpReg tmp)) `snocOL` (PUNPCKLQDQ fmt (OpReg tmp) dst) _ -> pprPanic "MO_V_Insert Int64X2: unsupported offset" (ppr offset) in return $ Any fmt code @@ -4083,7 +4083,7 @@ loadArgsWin config (arg:rest) = do -- arguments in both fp and integer registers. let (assign_code', regs') | isFloatFormat arg_fmt = - ( assign_code `snocOL` MOVD FF64 (OpReg freg) (OpReg ireg), + ( assign_code `snocOL` MOVD FF64 II64 (OpReg freg) (OpReg ireg), [ RegWithFormat freg FF64 , RegWithFormat ireg II64 ]) | otherwise = (assign_code, [RegWithFormat ireg II64]) ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -39,7 +39,6 @@ module GHC.CmmToAsm.X86.Instr , patchJumpInstr , isMetaInstr , isJumpishInstr - , movdOutFormat , MinOrMax(..), MinMaxType(..) ) where @@ -127,11 +126,16 @@ data Instr -- with @MOVABS@; we currently do not use this instruction in GHC. -- See https://stackoverflow.com/questions/52434073/whats-the-difference-between-the-x86-64-att-instructions-movq-and-movabsq. - | MOVD Format Operand Operand -- ^ MOVD/MOVQ SSE2 instructions - -- (bitcast between a general purpose - -- register and a float register). - -- Format is input format, output format is - -- calculated in the 'movdOutFormat' function. + -- | MOVD/MOVQ SSE2 instructions + -- (bitcast between a general purpose register and a float register). + | MOVD + Format -- ^ input format + Format -- ^ output format + Operand Operand + -- NB: MOVD stores both the input and output formats. This is because + -- neither format fully determines the other, as either might be + -- a vector format, and we need to know the exact format in order to + -- correctly spill/unspill. See #25659. | CMOV Cond Format Operand Reg | MOVZxL Format Operand Operand -- ^ The format argument is the size of operand 1 (the number of bits we keep) @@ -377,10 +381,10 @@ regUsageOfInstr platform instr -- (largely to avoid partial register stalls) | otherwise -> usageRW fmt src dst - MOVD fmt src dst -> + MOVD fmt1 fmt2 src dst -> -- NB: MOVD and MOVQ always zero any remaining upper part of destination, -- so the destination is "written" not "modified". - usageRW' fmt (movdOutFormat fmt) src dst + usageRW' fmt1 fmt2 src dst CMOV _ fmt src dst -> mkRU (use_R fmt src [mk fmt dst]) [mk fmt dst] MOVZxL fmt src dst -> usageRW fmt src dst MOVSxL fmt src dst -> usageRW fmt src dst @@ -650,14 +654,6 @@ interesting :: Platform -> Reg -> Bool interesting _ (RegVirtual _) = True interesting platform (RegReal (RealRegSingle i)) = freeReg platform i -movdOutFormat :: Format -> Format -movdOutFormat format = case format of - II32 -> FF32 - II64 -> FF64 - FF32 -> II32 - FF64 -> II64 - _ -> pprPanic "X86: improper format for movd/movq" (ppr format) - -- | Applies the supplied function to all registers in instructions. -- Typically used to change virtual registers to real registers. @@ -665,7 +661,7 @@ patchRegsOfInstr :: HasDebugCallStack => Platform -> Instr -> (Reg -> Reg) -> In patchRegsOfInstr platform instr env = case instr of MOV fmt src dst -> MOV fmt (patchOp src) (patchOp dst) - MOVD fmt src dst -> patch2 (MOVD fmt) src dst + MOVD fmt1 fmt2 src dst -> patch2 (MOVD fmt1 fmt2) src dst CMOV cc fmt src dst -> CMOV cc fmt (patchOp src) (env dst) MOVZxL fmt src dst -> patch2 (MOVZxL fmt) src dst MOVSxL fmt src dst -> patch2 (MOVSxL fmt) src dst ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -657,8 +657,8 @@ pprInstr platform i = case i of CMOV cc format src dst -> pprCondOpReg (text "cmov") format cc src dst - MOVD format src dst - -> pprMovdOpOp (text "mov") format src dst + MOVD format1 format2 src dst + -> pprMovdOpOp (text "mov") format1 format2 src dst MOVZxL II32 src dst -> pprFormatOpOp (text "mov") II32 src dst @@ -1151,21 +1151,21 @@ pprInstr platform i = case i of pprOperand platform format op2 ] - pprMovdOpOp :: Line doc -> Format -> Operand -> Operand -> doc - pprMovdOpOp name format op1 op2 - = let instr = case format of + pprMovdOpOp :: Line doc -> Format -> Format -> Operand -> Operand -> doc + pprMovdOpOp name format1 format2 op1 op2 + = let instr = case (format1, format2) of -- bitcasts to/from a general purpose register to a floating point -- register require II32 or II64. - II32 -> text "d" - II64 -> text "q" - FF32 -> text "d" - FF64 -> text "q" - _ -> panic "X86.Ppr.pprMovdOpOp: improper format for movd/movq." + (II32, _) -> text "d" + (II64, _) -> text "q" + (_, II32) -> text "d" + (_, II64) -> text "q" + _ -> panic "X86.Ppr.pprMovdOpOp: improper format for movd/movq." in line $ hcat [ char '\t' <> name <> instr <> space, - pprOperand platform format op1, + pprOperand platform format1 op1, comma, - pprOperand platform (movdOutFormat format) op2 + pprOperand platform format2 op2 ] pprFormatImmRegOp :: Line doc -> Format -> Imm -> Reg -> Operand -> doc ===================================== docs/users_guide/diagnostics-as-json-schema-1_0.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", ===================================== docs/users_guide/diagnostics-as-json-schema-1_1.json ===================================== @@ -13,7 +13,10 @@ "type": "string" }, "span": { - "$ref": "#/$defs/span" + "oneOf": [ + { "$ref": "#/$defs/span" }, + { "type": "null" } + ] }, "severity": { "description": "The diagnostic severity", ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-27T17:45:32Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 ===================================== libraries/base/changelog.md ===================================== @@ -11,6 +11,7 @@ * `instance Functor NonEmpty` is now specified using `map` (rather than duplicating code). ([CLC proposal #300](https://github.com/haskell/core-libraries-committee/issues/300)) ## 4.21.0.0 *TBA* + * Change `SrcLoc` to be a strict and unboxed (finishing [CLC proposal #55](https://github.com/haskell/core-libraries-committee/issues/55)) * Introduce `Data.Bounded` module exporting the `Bounded` typeclass (finishing [CLC proposal #208](https://github.com/haskell/core-libraries-committee/issues/208)) * Deprecate export of `Bounded` class from `Data.Enum` ([CLC proposal #208](https://github.com/haskell/core-libraries-committee/issues/208)) * `GHC.Desugar` has been deprecated and should be removed in GHC 9.14. ([CLC proposal #216](https://github.com/haskell/core-libraries-committee/issues/216)) ===================================== testsuite/tests/simd/should_run/T25659.hs ===================================== @@ -0,0 +1,19 @@ +{-# LANGUAGE MagicHash, UnboxedTuples, ExtendedLiterals #-} +import GHC.Int +import GHC.Prim + +test :: (Int64X2# -> Int64X2# -> Int64X2#) -> IO () +test f = do + let a = packInt64X2# (# 0#Int64, 11#Int64 #) + b = packInt64X2# (# 22#Int64, 33#Int64 #) + c = f a b + (# x0, x1 #) = unpackInt64X2# a + (# y0, y1 #) = unpackInt64X2# b + (# z0, z1 #) = unpackInt64X2# c + putStrLn $ "a = " ++ show (I64# x0, I64# x1) + putStrLn $ "b = " ++ show (I64# y0, I64# y1) + putStrLn $ "c = " ++ show (I64# z0, I64# z1) +{-# NOINLINE test #-} + +main :: IO () +main = test (\_ b -> b) ===================================== testsuite/tests/simd/should_run/T25659.stdout ===================================== @@ -0,0 +1,3 @@ +a = (0,11) +b = (22,33) +c = (22,33) ===================================== testsuite/tests/simd/should_run/all.T ===================================== @@ -26,6 +26,7 @@ test('word32x4_basic_baseline', [], compile_and_run, ['']) test('word64x2_basic_baseline', [], compile_and_run, ['']) test('T25658', [], compile_and_run, ['']) # #25658 is a bug with SSE2 code generation +test('T25659', [], compile_and_run, ['']) # Ensure we set the CPU features we have available. # View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8ec0a4dd5c4a39cc55d4013892123c93075f9590...9955f7371eb210c53f53d0e42216fefb09b4fdad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8ec0a4dd5c4a39cc55d4013892123c93075f9590...9955f7371eb210c53f53d0e42216fefb09b4fdad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 20:49:51 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 15:49:51 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/backports-9.12 Message-ID: <679942ef5f7e0_7a694c062014045@gitlab.mail> Ben Gamari pushed new branch wip/backports-9.12 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/backports-9.12 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 20:52:11 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 15:52:11 -0500 Subject: [Git][ghc/ghc][wip/backports-9.12] Bump hpc to 0.7.0.2 Message-ID: <6799437ba6519_7a694c06701565c@gitlab.mail> Ben Gamari pushed to branch wip/backports-9.12 at Glasgow Haskell Compiler / GHC Commits: d3633636 by Ben Gamari at 2025-01-28T15:52:00-05:00 Bump hpc to 0.7.0.2 - - - - - 1 changed file: - libraries/hpc Changes: ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 9e29abb785ab4f82c37c7a4e73ec999083955b09 +Subproject commit f321056015dc36b454f323ca4285d684f4f782d3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3633636f652bdafc71538c28d27e580ca2ef89f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3633636f652bdafc71538c28d27e580ca2ef89f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 21:25:19 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 16:25:19 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25691 Message-ID: <67994b3f9941d_7a694c39588332a5@gitlab.mail> Ben Gamari pushed new branch wip/T25691 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25691 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 21:28:16 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 16:28:16 -0500 Subject: [Git][ghc/ghc][wip/T25691] ghc-toolchain: Parse i686 triples Message-ID: <67994bf0a2119_7a694d5d97835195@gitlab.mail> Ben Gamari pushed to branch wip/T25691 at Glasgow Haskell Compiler / GHC Commits: f207268d by Ben Gamari at 2025-01-28T16:28:00-05:00 ghc-toolchain: Parse i686 triples This is a moniker used for later 32-bit x86 implementations (Pentium Pro and later). Fixes #25691. - - - - - 1 changed file: - utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs Changes: ===================================== utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs ===================================== @@ -36,6 +36,7 @@ parseArch :: Cc -> String -> M Arch parseArch cc arch = case arch of "i386" -> pure ArchX86 + "i686" -> pure ArchX86 "x86_64" -> pure ArchX86_64 "amd64" -> pure ArchX86_64 "powerpc" -> pure ArchPPC View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f207268de2c61b7ec00d5a663288610b9ad98d6e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f207268de2c61b7ec00d5a663288610b9ad98d6e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 21:38:17 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 16:38:17 -0500 Subject: [Git][ghc/ghc][wip/coreprep-sat-name] CorePrep: Name `sat` binders more descriptively Message-ID: <67994e49607d1_8ffd0f0438777fa@gitlab.mail> Ben Gamari pushed to branch wip/coreprep-sat-name at Glasgow Haskell Compiler / GHC Commits: 2a9b869a by Ben Gamari at 2025-01-28T16:37:57-05:00 CorePrep: Name `sat` binders more descriptively - - - - - 8 changed files: - compiler/GHC/CoreToStg/Prep.hs - testsuite/tests/core-to-stg/T14895.stderr - testsuite/tests/core-to-stg/T24124.stderr - testsuite/tests/ghci/should_run/T21052.stdout - testsuite/tests/simplCore/should_compile/T20040.stderr - testsuite/tests/simplCore/should_compile/T23083.stderr - testsuite/tests/simplStg/should_compile/T15226b.stderr - testsuite/tests/simplStg/should_compile/T19717.stderr Changes: ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -61,7 +61,8 @@ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Id.Make ( realWorldPrimId ) import GHC.Types.Basic -import GHC.Types.Name ( NamedThing(..), nameSrcSpan, isInternalName ) +import GHC.Types.Name ( NamedThing(..), nameSrcSpan, isInternalName, OccName ) +import GHC.Types.Name.Occurrence (occNameString) import GHC.Types.SrcLoc ( SrcSpan(..), realSrcLocSpan, mkRealSrcLoc ) import GHC.Types.Literal import GHC.Types.Tickish @@ -72,6 +73,7 @@ import qualified Data.ByteString.Builder as BB import Data.ByteString.Builder.Prim import Control.Monad +import Data.List (intercalate) {- Note [CorePrep Overview] @@ -249,11 +251,11 @@ corePrepPgm logger cp_cfg pgm_cfg withTiming logger (text "CorePrep"<+>brackets (ppr this_mod)) (\a -> a `seqList` ()) $ do - us <- mkSplitUniqSupply 's' let initialCorePrepEnv = mkInitialCorePrepEnv cp_cfg - let - implicit_binds = mkDataConWorkers + us <- mkSplitUniqSupply 's' + + let implicit_binds = mkDataConWorkers (cpPgm_generateDebugInfo pgm_cfg) mod_loc data_tycons -- NB: we must feed mkImplicitBinds through corePrep too @@ -713,13 +715,13 @@ cpePair :: TopLevelFlag -> RecFlag -> Demand -> Levity -> UniqSM (Floats, CpeRhs) -- Used for all bindings -- The binder is already cloned, hence an OutId -cpePair top_lvl is_rec dmd lev env bndr rhs +cpePair top_lvl is_rec dmd lev env0 bndr rhs = assert (not (isJoinId bndr)) $ -- those should use cpeJoinPair do { (floats1, rhs1) <- cpeRhsE env rhs -- See if we are allowed to float this stuff out of the RHS ; let dec = want_float_from_rhs floats1 rhs1 - ; (floats2, rhs2) <- executeFloatDecision dec floats1 rhs1 + ; (floats2, rhs2) <- executeFloatDecision env dec floats1 rhs1 -- Make the arity match up ; (floats3, rhs3) @@ -727,7 +729,7 @@ cpePair top_lvl is_rec dmd lev env bndr rhs then return (floats2, cpeEtaExpand arity rhs2) else warnPprTrace True "CorePrep: silly extra arguments:" (ppr bndr) $ -- Note [Silly extra arguments] - (do { v <- newVar (idType bndr) + (do { v <- newVar env (idType bndr) ; let (float, v') = mkNonRecFloat env Lifted v rhs2 ; return ( snocFloat floats2 float , cpeEtaExpand arity (Var v')) }) @@ -737,6 +739,8 @@ cpePair top_lvl is_rec dmd lev env bndr rhs ; return (floats4, rhs4) } where + env = pushBinderContext bndr env0 + arity = idArity bndr -- We must match this arity want_float_from_rhs floats rhs @@ -967,36 +971,36 @@ cpeBodyNF env expr cpeBody :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeBody) cpeBody env expr = do { (floats1, rhs) <- cpeRhsE env expr - ; (floats2, body) <- rhsToBody rhs + ; (floats2, body) <- rhsToBody env rhs ; return (floats1 `appFloats` floats2, body) } -------- -rhsToBody :: CpeRhs -> UniqSM (Floats, CpeBody) +rhsToBody :: CorePrepEnv -> CpeRhs -> UniqSM (Floats, CpeBody) -- Remove top level lambdas by let-binding -rhsToBody (Tick t expr) +rhsToBody env (Tick t expr) | tickishScoped t == NoScope -- only float out of non-scoped annotations - = do { (floats, expr') <- rhsToBody expr + = do { (floats, expr') <- rhsToBody env expr ; return (floats, mkTick t expr') } -rhsToBody (Cast e co) +rhsToBody env (Cast e co) -- You can get things like -- case e of { p -> coerce t (\s -> ...) } - = do { (floats, e') <- rhsToBody e + = do { (floats, e') <- rhsToBody env e ; return (floats, Cast e' co) } -rhsToBody expr@(Lam {}) -- See Note [No eta reduction needed in rhsToBody] +rhsToBody env expr@(Lam {}) -- See Note [No eta reduction needed in rhsToBody] | all isTyVar bndrs -- Type lambdas are ok = return (emptyFloats, expr) | otherwise -- Some value lambdas = do { let rhs = cpeEtaExpand (exprArity expr) expr - ; fn <- newVar (exprType rhs) + ; fn <- newVar env (exprType rhs) ; let float = Float (NonRec fn rhs) LetBound TopLvlFloatable ; return (unitFloat float, Var fn) } where (bndrs,_) = collectBinders expr -rhsToBody expr = return (emptyFloats, expr) +rhsToBody _env expr = return (emptyFloats, expr) {- Note [No eta reduction needed in rhsToBody] @@ -1168,7 +1172,7 @@ cpeApp top_env expr -- allocating CaseBound Floats for token and thing as needed = do { (floats1, token) <- cpeArg env topDmd token ; (floats2, thing) <- cpeBody env thing - ; case_bndr <- (`setIdUnfolding` evaldUnfolding) <$> newVar ty + ; case_bndr <- (`setIdUnfolding` evaldUnfolding) <$> newVar env ty ; let tup = mkCoreUnboxedTuple [token, Var case_bndr] ; let float = mkCaseFloat case_bndr thing ; return (floats1 `appFloats` floats2 `snocFloat` float, tup) } @@ -1577,7 +1581,7 @@ cpeArg env dmd arg ; let arg_ty = exprType arg1 lev = typeLevity arg_ty dec = wantFloatLocal NonRecursive dmd lev floats1 arg1 - ; (floats2, arg2) <- executeFloatDecision dec floats1 arg1 + ; (floats2, arg2) <- executeFloatDecision env dec floats1 arg1 -- Else case: arg1 might have lambdas, and we can't -- put them inside a wrapBinds @@ -1586,7 +1590,7 @@ cpeArg env dmd arg -- see Note [ANF-ising literal string arguments] ; if exprIsTrivial arg2 then return (floats2, arg2) - else do { v <- (`setIdDemandInfo` dmd) <$> newVar arg_ty + else do { v <- (`setIdDemandInfo` dmd) <$> newVar env arg_ty -- See Note [Pin demand info on floats] ; let arity = cpeArgArity env dec floats1 arg2 arg3 = cpeEtaExpand arity arg2 @@ -2424,13 +2428,13 @@ instance Outputable FloatDecision where ppr FloatNone = text "none" ppr FloatAll = text "all" -executeFloatDecision :: FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) -executeFloatDecision dec floats rhs +executeFloatDecision :: CorePrepEnv -> FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs) +executeFloatDecision env dec floats rhs = case dec of FloatAll -> return (floats, rhs) FloatNone | isEmptyFloats floats -> return (emptyFloats, rhs) - | otherwise -> do { (floats', body) <- rhsToBody rhs + | otherwise -> do { (floats', body) <- rhsToBody env rhs ; return (emptyFloats, wrapBinds floats $ wrapBinds floats' body) } -- FloatNone case: `rhs` might have lambdas, and we can't @@ -2569,6 +2573,8 @@ data CorePrepEnv , cpe_subst :: Subst -- ^ See Note [CorePrepEnv: cpe_subst] , cpe_rec_ids :: UnVarSet -- Faster OutIdSet; See Note [Speculative evaluation] + + , cpe_context :: [OccName] -- ^ See Note [Binder context] } mkInitialCorePrepEnv :: CorePrepConfig -> CorePrepEnv @@ -2576,6 +2582,7 @@ mkInitialCorePrepEnv cfg = CPE { cpe_config = cfg , cpe_subst = emptySubst , cpe_rec_ids = emptyUnVarSet + , cpe_context = [] } extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv @@ -2616,6 +2623,14 @@ cpSubstCo :: CorePrepEnv -> Coercion -> Coercion cpSubstCo (CPE { cpe_subst = subst }) co = substCo subst co -- substCo has a short-cut if the TCvSubst is empty +-- | See Note [Binder context] +pushBinderContext :: Id -> CorePrepEnv -> CorePrepEnv +pushBinderContext ident env + | lengthAtLeast (cpe_context env) 2 + = env + | otherwise + = env { cpe_context = getOccName ident : cpe_context env} + ------------------------------------------------------------------------------ -- Cloning binders -- --------------------------------------------------------------------------- @@ -2704,10 +2719,20 @@ fiddleCCall id -- Generating new binders -- --------------------------------------------------------------------------- -newVar :: Type -> UniqSM Id -newVar ty - = seqType ty `seq` mkSysLocalOrCoVarM (fsLit "sat") ManyTy ty - +newVar :: CorePrepEnv -> Type -> UniqSM Id +newVar env ty + -- See Note [Binder context] + = seqType ty `seq` mkSysLocalOrCoVarM (fsLit occ) ManyTy ty + where occ = intercalate "_" (map occNameString $ cpe_context env) ++ "_sat" + +{- Note [Binder context] + ~~~~~~~~~~~~~~~~~~~~~ + To ensure that the compiled program (specifically symbol names) + remains understandable to the user we maintain a context + of binders that we are currently under. This allows us to give + identifiers conjured during CorePrep more contextually-meaningful + names. This is done in `newVar`. + -} ------------------------------------------------------------------------------ -- Floating ticks ===================================== testsuite/tests/core-to-stg/T14895.stderr ===================================== @@ -11,10 +11,10 @@ T14895.go GHC.Internal.Data.Either.Left e [Occ=Once1] -> wild; GHC.Internal.Data.Either.Right a1 [Occ=Once1] -> let { - sat [Occ=Once1] :: b + go_sat [Occ=Once1] :: b [LclId] = {a1, f} \u [] f a1; - } in GHC.Internal.Data.Either.Right [sat]; + } in GHC.Internal.Data.Either.Right [go_sat]; }; ===================================== testsuite/tests/core-to-stg/T24124.stderr ===================================== @@ -8,16 +8,16 @@ T24124.testFun1 -> (# GHC.Prim.State# GHC.Prim.RealWorld, T24124.StrictPair a b #) [GblId, Arity=3, Str=, Cpr=1, Unf=OtherCon []] = {} \r [x y void] - case x of sat { + case x of testFun1_sat { __DEFAULT -> case case y of y [OS=OneShot] { - __DEFAULT -> T24124.MkStrictPair [sat y]; + __DEFAULT -> T24124.MkStrictPair [testFun1_sat y]; } of - sat + testFun1_sat { - __DEFAULT -> MkSolo# [sat]; + __DEFAULT -> MkSolo# [testFun1_sat]; }; }; ===================================== testsuite/tests/ghci/should_run/T21052.stdout ===================================== @@ -4,9 +4,9 @@ BCO_toplevel :: GHC.Types.IO [GHC.Types.Any] [LclIdX] = {} \u [] let { - sat :: [GHC.Types.Any] + _sat :: [GHC.Types.Any] [LclId, Unf=OtherCon []] = :! [GHC.Tuple.() GHC.Types.[]]; - } in GHC.Internal.Base.returnIO sat; + } in GHC.Internal.Base.returnIO _sat; ===================================== testsuite/tests/simplCore/should_compile/T20040.stderr ===================================== @@ -16,7 +16,9 @@ ifoldl' = Cons ipv2 ipv3 -> case z of z1 { __DEFAULT -> - case f z1 ipv2 of sat { __DEFAULT -> ifoldl' f sat ipv3; }; + case f z1 ipv2 of ifoldl'_sat { + __DEFAULT -> ifoldl' f ifoldl'_sat ipv3; + }; }; }; end Rec } ===================================== testsuite/tests/simplCore/should_compile/T23083.stderr ===================================== @@ -13,10 +13,10 @@ T23083.g :: ((GHC.Internal.Bignum.Integer.Integer -> GHC.Internal.Bignum.Integer T23083.g = \ (f [Occ=Once1!] :: (GHC.Internal.Bignum.Integer.Integer -> GHC.Internal.Bignum.Integer.Integer) -> GHC.Internal.Bignum.Integer.Integer) (h [Occ=OnceL1] :: GHC.Internal.Bignum.Integer.Integer -> GHC.Internal.Bignum.Integer.Integer) -> let { - sat [Occ=Once1] :: GHC.Internal.Bignum.Integer.Integer -> GHC.Internal.Bignum.Integer.Integer + g_sat [Occ=Once1] :: GHC.Internal.Bignum.Integer.Integer -> GHC.Internal.Bignum.Integer.Integer [LclId, Unf=OtherCon []] - sat = \ (eta [Occ=Once1] :: GHC.Internal.Bignum.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Internal.Bignum.Integer.Integer @GHC.Internal.Bignum.Integer.Integer h1 eta } } in - f sat + g_sat = \ (eta [Occ=Once1] :: GHC.Internal.Bignum.Integer.Integer) -> case h of h1 [Occ=Once1] { __DEFAULT -> T23083.$$ @GHC.Internal.Bignum.Integer.Integer @GHC.Internal.Bignum.Integer.Integer h1 eta } } in + f g_sat -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T23083.$trModule4 :: GHC.Prim.Addr# ===================================== testsuite/tests/simplStg/should_compile/T15226b.stderr ===================================== @@ -8,13 +8,13 @@ T15226b.bar1 T15226b.Str (GHC.Internal.Maybe.Maybe a) #) [GblId, Arity=2, Str=, Cpr=1(, 1), Unf=OtherCon []] = {} \r [x void] - case x of sat { + case x of bar1_sat { __DEFAULT -> let { - sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) + bar1_sat [Occ=Once1] :: T15226b.Str (GHC.Internal.Maybe.Maybe a) [LclId, Unf=OtherCon []] = - T15226b.Str! [sat]; - } in MkSolo# [sat]; + T15226b.Str! [bar1_sat]; + } in MkSolo# [bar1_sat]; }; T15226b.bar ===================================== testsuite/tests/simplStg/should_compile/T19717.stderr ===================================== @@ -6,14 +6,14 @@ Foo.f :: forall {a}. a -> [GHC.Internal.Maybe.Maybe a] case x of x1 { __DEFAULT -> let { - sat [Occ=Once1] :: GHC.Internal.Maybe.Maybe a + f_sat [Occ=Once1] :: GHC.Internal.Maybe.Maybe a [LclId, Unf=OtherCon []] = GHC.Internal.Maybe.Just! [x1]; } in let { - sat [Occ=Once1] :: [GHC.Internal.Maybe.Maybe a] + f_sat [Occ=Once1] :: [GHC.Internal.Maybe.Maybe a] [LclId, Unf=OtherCon []] = - :! [sat GHC.Types.[]]; - } in : [sat sat]; + :! [f_sat GHC.Types.[]]; + } in : [f_sat f_sat]; }; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a9b869a65d988cacfc00c6fe9755ff307e891b6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a9b869a65d988cacfc00c6fe9755ff307e891b6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 21:41:55 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Tue, 28 Jan 2025 16:41:55 -0500 Subject: [Git][ghc/ghc][ghc-9.10] Fixes for built-in names (#25182, #25174) Message-ID: <67994f23430a9_8ffd02108b8951ec@gitlab.mail> Andreas Klebinger pushed to branch ghc-9.10 at Glasgow Haskell Compiler / GHC Commits: cc4470be by Vladislav Zavialov at 2025-01-28T18:32:38+03:00 Fixes for built-in names (#25182, #25174) * In isBuiltInOcc_maybe, do not match on "FUN" (#25174) * Classify MkSolo as UserSyntax (#25182) Extracted from 51e3ec839c378f0da7052278a56482f0349e9bc7 - - - - - 15 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Types/Name/Ppr.hs - docs/users_guide/9.10.2-notes.rst - testsuite/tests/interface-stability/ghc-experimental-exports.stdout - + testsuite/tests/rename/should_compile/ReExportTuples.hs - + testsuite/tests/rename/should_compile/T25182.hs - testsuite/tests/rename/should_compile/all.T - + testsuite/tests/th/FunNameTH.hs - testsuite/tests/th/T13776.hs - testsuite/tests/th/T13776.stderr - + testsuite/tests/th/T25174.hs - testsuite/tests/th/all.T - testsuite/tests/typecheck/should_compile/holes.stderr - testsuite/tests/typecheck/should_compile/holes3.stderr - testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -78,6 +78,7 @@ module GHC.Builtin.Types ( promotedTupleDataCon, unitTyCon, unitDataCon, unitDataConId, unitTy, unitTyConKey, soloTyCon, + soloDataConName, pairTyCon, mkPromotedPairTy, isPromotedPairType, unboxedUnitTy, unboxedUnitTyCon, unboxedUnitDataCon, @@ -896,7 +897,6 @@ isBuiltInOcc_maybe occ = ":" -> Just consDataConName -- function tycon - "FUN" -> Just fUNTyConName "->" -> Just unrestrictedFunTyConName -- tuple data/tycon @@ -1055,40 +1055,36 @@ isPunOcc_maybe mod occ isCTupleOcc_maybe mod occ <|> isSumTyOcc_maybe mod occ -mkTupleOcc :: NameSpace -> Boxity -> Arity -> OccName --- No need to cache these, the caching is done in mk_tuple -mkTupleOcc ns Boxed ar = mkOccName ns (mkBoxedTupleStr ns ar) -mkTupleOcc ns Unboxed ar = mkOccName ns (mkUnboxedTupleStr ns ar) +mkTupleOcc :: NameSpace -> Boxity -> Arity -> (OccName, BuiltInSyntax) +mkTupleOcc ns b ar = (mkOccName ns str, built_in) + where (str, built_in) = mkTupleStr' ns b ar mkCTupleOcc :: NameSpace -> Arity -> OccName mkCTupleOcc ns ar = mkOccName ns (mkConstraintTupleStr ar) mkTupleStr :: Boxity -> NameSpace -> Arity -> String -mkTupleStr Boxed = mkBoxedTupleStr -mkTupleStr Unboxed = mkUnboxedTupleStr - -mkBoxedTupleStr :: NameSpace -> Arity -> String -mkBoxedTupleStr ns 0 - | isDataConNameSpace ns = "()" - | otherwise = "Unit" -mkBoxedTupleStr ns 1 - | isDataConNameSpace ns = "MkSolo" -- See Note [One-tuples] - | otherwise = "Solo" -mkBoxedTupleStr ns ar - | isDataConNameSpace ns = '(' : commas ar ++ ")" - | otherwise = "Tuple" ++ showInt ar "" - - -mkUnboxedTupleStr :: NameSpace -> Arity -> String -mkUnboxedTupleStr ns 0 - | isDataConNameSpace ns = "(##)" - | otherwise = "Unit#" -mkUnboxedTupleStr ns 1 - | isDataConNameSpace ns = "(# #)" -- See Note [One-tuples] - | otherwise = "Solo#" -mkUnboxedTupleStr ns ar - | isDataConNameSpace ns = "(#" ++ commas ar ++ "#)" - | otherwise = "Tuple" ++ show ar ++ "#" +mkTupleStr b ns ar = str + where (str, _) = mkTupleStr' ns b ar + +mkTupleStr' :: NameSpace -> Boxity -> Arity -> (String, BuiltInSyntax) +mkTupleStr' ns Boxed 0 + | isDataConNameSpace ns = ("()", BuiltInSyntax) + | otherwise = ("Unit", UserSyntax) +mkTupleStr' ns Boxed 1 + | isDataConNameSpace ns = ("MkSolo", UserSyntax) -- See Note [One-tuples] + | otherwise = ("Solo", UserSyntax) +mkTupleStr' ns Boxed ar + | isDataConNameSpace ns = ('(' : commas ar ++ ")", BuiltInSyntax) + | otherwise = ("Tuple" ++ showInt ar "", UserSyntax) +mkTupleStr' ns Unboxed 0 + | isDataConNameSpace ns = ("(##)", BuiltInSyntax) + | otherwise = ("Unit#", UserSyntax) +mkTupleStr' ns Unboxed 1 + | isDataConNameSpace ns = ("(# #)", BuiltInSyntax) -- See Note [One-tuples] + | otherwise = ("Solo#", UserSyntax) +mkTupleStr' ns Unboxed ar + | isDataConNameSpace ns = ("(#" ++ commas ar ++ "#)", BuiltInSyntax) + | otherwise = ("Tuple" ++ show ar ++ "#", UserSyntax) mkConstraintTupleStr :: Arity -> String mkConstraintTupleStr 0 = "CUnit" @@ -1244,10 +1240,10 @@ mk_tuple Boxed arity = (tycon, tuple_con) boxity = Boxed modu = gHC_INTERNAL_TUPLE - tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq - (ATyCon tycon) UserSyntax - dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq - (AConLike (RealDataCon tuple_con)) BuiltInSyntax + tc_name = mkWiredInName modu occ tc_uniq (ATyCon tycon) built_in + where (occ, built_in) = mkTupleOcc tcName boxity arity + dc_name = mkWiredInName modu occ dc_uniq (AConLike (RealDataCon tuple_con)) built_in + where (occ, built_in) = mkTupleOcc dataName boxity arity tc_uniq = mkTupleTyConUnique boxity arity dc_uniq = mkTupleDataConUnique boxity arity @@ -1278,10 +1274,10 @@ mk_tuple Unboxed arity = (tycon, tuple_con) boxity = Unboxed modu = gHC_TYPES - tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq - (ATyCon tycon) UserSyntax - dc_name = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq - (AConLike (RealDataCon tuple_con)) BuiltInSyntax + tc_name = mkWiredInName modu occ tc_uniq (ATyCon tycon) built_in + where (occ, built_in) = mkTupleOcc tcName boxity arity + dc_name = mkWiredInName modu occ dc_uniq (AConLike (RealDataCon tuple_con)) built_in + where (occ, built_in) = mkTupleOcc dataName boxity arity tc_uniq = mkTupleTyConUnique boxity arity dc_uniq = mkTupleDataConUnique boxity arity @@ -1345,6 +1341,9 @@ soloTyCon = tupleTyCon Boxed 1 soloTyConName :: Name soloTyConName = tyConName soloTyCon +soloDataConName :: Name +soloDataConName = tupleDataConName Boxed 1 + pairTyCon :: TyCon pairTyCon = tupleTyCon Boxed 2 ===================================== compiler/GHC/Types/Name/Ppr.hs ===================================== @@ -123,7 +123,8 @@ mkQualName env = qual_name where , fUNTyConName, unrestrictedFunTyConName , oneDataConName , listTyConName - , manyDataConName ] + , manyDataConName + , soloDataConName ] || isJust (isTupleTyOcc_maybe mod occ) || isJust (isSumTyOcc_maybe mod occ) ===================================== docs/users_guide/9.10.2-notes.rst ===================================== @@ -68,6 +68,10 @@ Compiler specialization rules was added. It was actually added ghc-9.10.1 already but mistakenly not mentioned in the 9.10.1 changelog. +- Fixed re-exports of ``MkSolo`` (:ghc-ticket:`25182`) + +- Fixed the behavior of ``Language.Haskell.TH.mkName "FUN"`` (:ghc-ticket:`25174`) + JavaScript backend ~~~~~~~~~~~~~~~~~~ ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout ===================================== @@ -5481,7 +5481,7 @@ module Prelude.Experimental where data List a = ... pattern Solo :: forall a. a -> Solo a type Solo :: * -> * - data Solo a = ... + data Solo a = MkSolo a type Solo# :: forall (k :: GHC.Types.RuntimeRep). TYPE k -> TYPE (GHC.Types.TupleRep '[k]) data Solo# a = ... type Sum10# :: forall (k0 :: GHC.Types.RuntimeRep) (k1 :: GHC.Types.RuntimeRep) (k2 :: GHC.Types.RuntimeRep) (k3 :: GHC.Types.RuntimeRep) (k4 :: GHC.Types.RuntimeRep) (k5 :: GHC.Types.RuntimeRep) (k6 :: GHC.Types.RuntimeRep) (k7 :: GHC.Types.RuntimeRep) (k8 :: GHC.Types.RuntimeRep) (k9 :: GHC.Types.RuntimeRep). TYPE k0 -> TYPE k1 -> TYPE k2 -> TYPE k3 -> TYPE k4 -> TYPE k5 -> TYPE k6 -> TYPE k7 -> TYPE k8 -> TYPE k9 -> TYPE (GHC.Types.SumRep [k0, k1, k2, k3, k4, k5, k6, k7, k8, k9]) ===================================== testsuite/tests/rename/should_compile/ReExportTuples.hs ===================================== @@ -0,0 +1,4 @@ +module ReExportTuples (module Data.Tuple) where +-- Re-export the entire Data.Tuple module at once + +import Data.Tuple ===================================== testsuite/tests/rename/should_compile/T25182.hs ===================================== @@ -0,0 +1,6 @@ +module T25182 where + +import ReExportTuples + +s :: Solo String +s = MkSolo "hello" \ No newline at end of file ===================================== testsuite/tests/rename/should_compile/all.T ===================================== @@ -223,3 +223,4 @@ test('T22478a', req_th, compile, ['']) test('RecordWildCardDeprecation', normal, multimod_compile, ['RecordWildCardDeprecation', '-Wno-duplicate-exports']) test('T14032b', normal, compile_and_run, ['']) test('T14032d', normal, compile, ['']) +test('T25182', [extra_files(['ReExportTuples.hs'])], multimod_compile, ['T25182', '-v0']) ===================================== testsuite/tests/th/FunNameTH.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE TemplateHaskell #-} + +module FunNameTH where + +import Language.Haskell.TH + +f1 :: forall a. $(conT (mkName "->")) [a] Bool +f1 = null + +f2 :: forall a. $(conT ''(->)) [a] Bool +f2 = null \ No newline at end of file ===================================== testsuite/tests/th/T13776.hs ===================================== @@ -10,6 +10,9 @@ spliceTy1 = (1,2) spliceTy2 :: $(conT ''[] `appT` conT ''Int) spliceTy2 = [] +spliceTy3 :: $(conT ''(->)) [Int] Int +spliceTy3 = sum + spliceExp1 :: (Int, Int) spliceExp1 = $(conE '(,) `appE` litE (integerL 1) `appE` litE (integerL 1)) ===================================== testsuite/tests/th/T13776.stderr ===================================== @@ -1,12 +1,13 @@ +T13776.hs:13:15-27: Splicing type conT ''(->) ======> (->) T13776.hs:10:15-43: Splicing type conT ''[] `appT` conT ''Int ======> [] Int T13776.hs:7:15-62: Splicing type conT ''(,) `appT` conT ''Int `appT` conT ''Int ======> (,) Int Int -T13776.hs:14:15-75: Splicing expression +T13776.hs:17:15-75: Splicing expression conE '(,) `appE` litE (integerL 1) `appE` litE (integerL 1) ======> (,) 1 1 -T13776.hs:17:15-24: Splicing expression conE '[] ======> [] -T13776.hs:20:13-62: Splicing pattern +T13776.hs:20:15-24: Splicing expression conE '[] ======> [] +T13776.hs:23:13-62: Splicing pattern conP '(,) [litP (integerL 1), litP (integerL 1)] ======> (,) 1 1 -T13776.hs:23:13-25: Splicing pattern conP '[] [] ======> [] +T13776.hs:26:13-25: Splicing pattern conP '[] [] ======> [] ===================================== testsuite/tests/th/T25174.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE TemplateHaskell #-} + +module T25174 where + +import Language.Haskell.TH + +data FUN a b = MkFUN (a -> b) + +evenFUN :: $(conT (mkName "FUN")) Int Bool +evenFUN = MkFUN even + ===================================== testsuite/tests/th/all.T ===================================== @@ -614,3 +614,5 @@ test('T24557e', normal, compile, ['']) test('T24702a', normal, compile, ['']) test('T24702b', normal, compile, ['']) test('T24837', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('T25174', normal, compile, ['']) +test('FunNameTH', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_compile/holes.stderr ===================================== @@ -88,7 +88,6 @@ holes.hs:11:15: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] Nothing :: forall a. Maybe a Just :: forall a. a -> Maybe a [] :: forall a. [a] - MkSolo :: forall a. a -> Solo a asTypeOf :: forall a. a -> a -> a id :: forall a. a -> a until :: forall a. (a -> Bool) -> (a -> a) -> a -> a ===================================== testsuite/tests/typecheck/should_compile/holes3.stderr ===================================== @@ -91,7 +91,6 @@ holes3.hs:11:15: error: [GHC-88464] Nothing :: forall a. Maybe a Just :: forall a. a -> Maybe a [] :: forall a. [a] - MkSolo :: forall a. a -> Solo a asTypeOf :: forall a. a -> a -> a id :: forall a. a -> a until :: forall a. (a -> Bool) -> (a -> a) -> a -> a ===================================== testsuite/tests/typecheck/should_compile/valid_hole_fits.stderr ===================================== @@ -1,6 +1,5 @@ [1 of 2] Compiling ValidHoleFits ( ValidHoleFits.hs, ValidHoleFits.o ) [2 of 2] Compiling Foo ( valid_hole_fits.hs, valid_hole_fits.o ) - valid_hole_fits.hs:9:6: warning: [GHC-88464] [-Wdeferred-out-of-scope-variables (in -Wdefault)] Variable not in scope: putStrLn :: String -> IO () Suggested fixes: @@ -148,9 +147,6 @@ valid_hole_fits.hs:34:11: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] with Just @Bool (imported from ‘Data.Maybe’ at valid_hole_fits.hs:5:1-17 (and originally defined in ‘GHC.Internal.Maybe’)) - MkSolo :: forall a. a -> Solo a - with MkSolo @Bool - (bound at ) id :: forall a. a -> a with id @Bool (imported from ‘Prelude’ at valid_hole_fits.hs:3:1-40 @@ -259,3 +255,4 @@ valid_hole_fits.hs:41:8: warning: [GHC-88464] [-Wtyped-holes (in -Wdefault)] with mempty @(String -> IO ()) (imported from ‘Prelude’ at valid_hole_fits.hs:3:1-40 (and originally defined in ‘GHC.Internal.Base’)) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc4470be68fa11ce296cef0684a11c4641f85ffe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc4470be68fa11ce296cef0684a11c4641f85ffe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue Jan 28 21:46:52 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 16:46:52 -0500 Subject: [Git][ghc/ghc][wip/T25641] StgToByteCode: Assert that PUSH_G'd values are lifted Message-ID: <6799504cd83b1_8ffd0f28f09871f@gitlab.mail> Ben Gamari pushed to branch wip/T25641 at Glasgow Haskell Compiler / GHC Commits: 0e5c8400 by Ben Gamari at 2025-01-28T21:46:49+00:00 StgToByteCode: Assert that PUSH_G'd values are lifted We currently do not support top-level unlifted data constructor applications, therefore this is a safe assertion. Pointed out by @sheaf. - - - - - 1 changed file: - compiler/GHC/StgToByteCode.hs Changes: ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -1954,6 +1954,11 @@ pushAtom d p (StgVarArg var) return (unitOL (PUSH_ADDR (getName var)), szb) | otherwise -> do + let varTy = idType var + massertPpr (definitelyLiftedType varTy) $ + vcat [ text "pushAtom: unhandled unlifted type" + , text "var:" <+> ppr var <+> dcolon <+> ppr varTy <> dcolon <+> ppr (typeKind varTy) + ] return (unitOL (PUSH_G (getName var)), szb) pushAtom _ _ (StgLitArg lit) = pushLiteral True lit View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0e5c840054fbdfab751e13f02544ee3d78923947 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0e5c840054fbdfab751e13f02544ee3d78923947 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 01:17:33 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 20:17:33 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/backports-9.12 Message-ID: <679981adee571_d00c1106f648107570@gitlab.mail> Ben Gamari deleted branch wip/backports-9.12 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 01:17:38 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 20:17:38 -0500 Subject: [Git][ghc/ghc][ghc-9.12] 4 commits: binary: Bump to 0.8.9.3 Message-ID: <679981b24ff72_d00c1fdc6cc107727@gitlab.mail> Ben Gamari pushed to branch ghc-9.12 at Glasgow Haskell Compiler / GHC Commits: 05559400 by Ben Gamari at 2025-01-28T11:35:01-05:00 binary: Bump to 0.8.9.3 Only trivial changes present. - - - - - 4b57fd7e by Ben Gamari at 2025-01-28T13:24:51-05:00 Bump parsec to 3.1.18.0 - - - - - 2d0ea607 by Ben Gamari at 2025-01-28T13:36:57-05:00 Bump terminfo to 0.4.1.7 - - - - - d3633636 by Ben Gamari at 2025-01-28T15:52:00-05:00 Bump hpc to 0.7.0.2 - - - - - 4 changed files: - libraries/binary - libraries/hpc - libraries/parsec - libraries/terminfo Changes: ===================================== libraries/binary ===================================== @@ -1 +1 @@ -Subproject commit 2a712db14912dddccf3e2207815e30b9f3049514 +Subproject commit a625eee2eb9dfb4019c051b59d6007c9dded88aa ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 9e29abb785ab4f82c37c7a4e73ec999083955b09 +Subproject commit f321056015dc36b454f323ca4285d684f4f782d3 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 903f9d8561a23376d26a7b857aa9fa5b35531d6f +Subproject commit b87122c1c74b8240e65044a8f600f0427d4dd9c3 ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit a76fac0c60cf6db7ed724d9b5c5067d77a23efc7 +Subproject commit 788ce671cb1cec54c3c9b3ac1c1ba189e8424819 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a6f47532aa7c5e08f9d7549e72839b400d932cb8...d3633636f652bdafc71538c28d27e580ca2ef89f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a6f47532aa7c5e08f9d7549e72839b400d932cb8...d3633636f652bdafc71538c28d27e580ca2ef89f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 01:22:43 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 20:22:43 -0500 Subject: [Git][ghc/ghc][wip/bump-xhtml] Bump hpc to 0.7.0.2 Message-ID: <679982e3ad74d_fcf82c074c4506d@gitlab.mail> Ben Gamari pushed to branch wip/bump-xhtml at Glasgow Haskell Compiler / GHC Commits: 8f7dcac2 by Ben Gamari at 2025-01-28T20:20:17-05:00 Bump hpc to 0.7.0.2 - - - - - 1 changed file: - libraries/hpc Changes: ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 9e29abb785ab4f82c37c7a4e73ec999083955b09 +Subproject commit f321056015dc36b454f323ca4285d684f4f782d3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8f7dcac2be4aaa2426fc46f3ae76262023577de1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8f7dcac2be4aaa2426fc46f3ae76262023577de1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 01:55:40 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Tue, 28 Jan 2025 20:55:40 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/strict-level Message-ID: <67998a9c1529a_fcf826ab9f447612@gitlab.mail> Ben Gamari pushed new branch wip/strict-level at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/strict-level You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 02:45:28 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 28 Jan 2025 21:45:28 -0500 Subject: [Git][ghc/ghc][master] hadrian: fix bootstrap with 9.12.1 Message-ID: <679996484236d_fcf82132ace861727@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e16eae65 by Cheng Shao at 2025-01-27T21:41:39+00:00 hadrian: fix bootstrap with 9.12.1 This patch bumps hadrian index-state to fix bootstrap with 9.12.1. - - - - - 2 changed files: - .gitlab/ci.sh - hadrian/cabal.project Changes: ===================================== .gitlab/ci.sh ===================================== @@ -8,7 +8,7 @@ set -Eeuo pipefail # Configuration: # N.B. You may want to also update the index-state in hadrian/cabal.project. -HACKAGE_INDEX_STATE="2024-10-30T22:56:00Z" +HACKAGE_INDEX_STATE="2025-01-27T17:45:32Z" MIN_HAPPY_VERSION="1.20" MIN_ALEX_VERSION="3.2.6" ===================================== hadrian/cabal.project ===================================== @@ -4,7 +4,7 @@ packages: ./ -- This essentially freezes the build plan for hadrian -- It would be wise to keep this up to date with the state set in .gitlab/ci.sh. -index-state: 2024-10-30T22:56:00Z +index-state: 2025-01-27T17:45:32Z -- unordered-containers-0.2.20-r1 requires template-haskell < 2.22 -- ghc-9.10 has template-haskell-2.22.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e16eae6548743870e77c2c93527bab1d24cff81c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e16eae6548743870e77c2c93527bab1d24cff81c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 02:46:01 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 28 Jan 2025 21:46:01 -0500 Subject: [Git][ghc/ghc][master] base: add SrcLoc changes to changelog, 4.21.0.0 Message-ID: <67999669852f8_fcf8211aa6c06584f@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8071bad8 by Jeffrey Young at 2025-01-28T21:45:32-05:00 base: add SrcLoc changes to changelog, 4.21.0.0 I accidentally dropped this in !13381 - closes #25614 See: - ea4587794b9e3a098f9c02bd6cea2294af2539ce (the 13381 commit) - Issue #25614 - - - - - 1 changed file: - libraries/base/changelog.md Changes: ===================================== libraries/base/changelog.md ===================================== @@ -11,6 +11,7 @@ * `instance Functor NonEmpty` is now specified using `map` (rather than duplicating code). ([CLC proposal #300](https://github.com/haskell/core-libraries-committee/issues/300)) ## 4.21.0.0 *TBA* + * Change `SrcLoc` to be a strict and unboxed (finishing [CLC proposal #55](https://github.com/haskell/core-libraries-committee/issues/55)) * Introduce `Data.Bounded` module exporting the `Bounded` typeclass (finishing [CLC proposal #208](https://github.com/haskell/core-libraries-committee/issues/208)) * Deprecate export of `Bounded` class from `Data.Enum` ([CLC proposal #208](https://github.com/haskell/core-libraries-committee/issues/208)) * `GHC.Desugar` has been deprecated and should be removed in GHC 9.14. ([CLC proposal #216](https://github.com/haskell/core-libraries-committee/issues/216)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8071bad8b185bc9d0f71e08b6520a5d5705e2636 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8071bad8b185bc9d0f71e08b6520a5d5705e2636 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 03:18:43 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Tue, 28 Jan 2025 22:18:43 -0500 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 17 commits: base: add SrcLoc changes to changelog, 4.21.0.0 Message-ID: <67999e12d293d_1353a3c05bc669be@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 8071bad8 by Jeffrey Young at 2025-01-28T21:45:32-05:00 base: add SrcLoc changes to changelog, 4.21.0.0 I accidentally dropped this in !13381 - closes #25614 See: - ea4587794b9e3a098f9c02bd6cea2294af2539ce (the 13381 commit) - Issue #25614 - - - - - 583fc267 by M Farkas-Dyck at 2025-01-28T22:17:13-05:00 Rename `cloneBndrs` and such — now all the monadic ones have an `M` suffix. We now have `cloneBndrs` and `cloneRecIdBndrs` which take a `UniqSupply` argument, and `cloneBndrsM` and `cloneRecIdBndrsM` which rather have a `MonadUnique` constraint. - - - - - 25681b60 by Matthew Farkas-Dyck at 2025-01-28T22:17:13-05:00 Use `Infinite` in unique generation, and clean up some other partial uni patterns as well. Also drop the losing `instance MonadFail UniqSM`. We redefine `getUniquesM` in terms of `Infinite` rather than `[]`, and define another method `getUniqueListM` for the use sites where we actually want a `[]`. Thus, at many sites, we can avoid the partiality of the empty list case. We also define `withUniques`, `withUniquesM`, and `withUniquesM'`, which traverse an arbitrary `Traversable` structure and introduce a `Unique` for each element. This allows us to redefine various functions to operate on more appropriate types than `[]` and avoid further partiality (in the form of incomplete-uni-patterns). - - - - - 1b017761 by M Farkas-Dyck at 2025-01-28T22:17:13-05:00 Use `Infinite` in `GHC.Tc.Deriv.Functor`. Make the list of variables to use in generated code `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - 773ce0f5 by M Farkas-Dyck at 2025-01-28T22:17:13-05:00 Use `Infinite` in `GHC.Runtime.Debugger`. Make the list of available names `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - 6fe0e844 by M Farkas-Dyck at 2025-01-28T22:17:13-05:00 Avoid incomplete-uni-patterns in `GHC.Cmm.DebugBlock`. We do so by changing the type of `BlockContext` to statically (in GHC) exclude the possibility of Cmm statics, and using `NonEmpty` lists of `BlockContext`s in `cmmDebugGen`. - - - - - 363e13f5 by M Farkas-Dyck at 2025-01-28T22:17:13-05:00 Avoid incomplete-uni-patterns in `GHC.Types.Literal`. We do so by introducing `mkLitNumberWrap'` whose ultimate codomain is `Integer` rather than `Literal`, and then use that rather than `mkLitNumberWrap` where we just need the number rather than the `Literal`. - - - - - 3303bedf by M Farkas-Dyck at 2025-01-28T22:17:13-05:00 Avoid incomplete-uni-patterns in `GHC.CmmToAsm.X86.CodeGen`. - Match the vector element list only once in `shuffleInstructions`. - Define `isSuitableFloatingPointLit_maybe` which returns `Just` the width if the lit is indeed suitable. - - - - - 91fc805c by M Farkas-Dyck at 2025-01-28T22:17:13-05:00 Clean up more incomplete uni patterns. At some sites, we merely panic if the `[]` or `Maybe` is empty when we convert to `NonEmpty` or `Identity`, but at least now we make it explicit. At other sites, we are able to use more precise types and avoid the partiality altogether. To do so, we redefine various functions to operate over `Traversable` arguments, so we can use the appropriate shape where known. - - - - - 4c444441 by M Farkas-Dyck at 2025-01-28T22:17:13-05:00 Outline `expectJustPanic`. - - - - - 593bd56f by Marc Scholten at 2025-01-28T22:17:20-05:00 base: Introduce Data.Enum.enumerate (CLC #306) https://github.com/haskell/core-libraries-committee/issues/306 - - - - - 59337372 by Ben Gamari at 2025-01-28T22:17:21-05:00 base: Update description of locking behavior - - - - - 34fb39b3 by Ben Gamari at 2025-01-28T22:17:23-05:00 base: Fix @since annotation of Data.Bounded Fixes #25615. - - - - - 805ed7c4 by Ben Gamari at 2025-01-28T22:17:25-05:00 StgToByteCode: Fix overly-broad handling of Addr# literals Previously we assumed that all unlifted types were `Addr#` but this isn't true. As noted in #25638, unlifted nullary data constructor workers can also appear at the top-level and are obviously not of type `Addr#`. Note that there is more work to be done to properly handle unlifted data constructors (especially nullary; see #25636). However, this is a small step in the right direction. Closes #25641. - - - - - 4bee43b8 by Ben Gamari at 2025-01-28T22:17:25-05:00 StgToByteCode: Assert that PUSH_G'd values are lifted We currently do not support top-level unlifted data constructor applications, therefore this is a safe assertion. Pointed out by @sheaf. - - - - - e5259b46 by Ben Gamari at 2025-01-28T22:17:26-05:00 gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Closes #25654. - - - - - 91833c0b by Matthew Pickering at 2025-01-28T22:17:27-05:00 bytecode: Do not generate `SLIDE x 0` instructions SLIDE x 0 is a no-op as it means to shift x elements of the stack by no spaces. In the interpreter, this results in a loop which copies an array element into the same place. I have instrumented GHCi to count how many of these instructions are interpreted. The workload was `ghc` compiling two simple modules. Total no-op slides: 7793476 Total slides: 11413289 Percentage useless (slides): 68% Percentage uselss of total instructions: 9% - - - - - 30 changed files: - .gitlab-ci.yml - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/List/Infinite.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9955f7371eb210c53f53d0e42216fefb09b4fdad...91833c0be12a22767511a4fa6b774dedbdcef9d4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9955f7371eb210c53f53d0e42216fefb09b4fdad...91833c0be12a22767511a4fa6b774dedbdcef9d4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 07:28:18 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 02:28:18 -0500 Subject: =?UTF-8?Q?[Git][ghc/ghc][master]_9_commits:_Rename_`cloneBndrs`?= =?UTF-8?Q?_and_such_=E2=80=94_now_all_the_monadic_ones_have_an_`M`_suffix.?= Message-ID: <6799d8924b5ae_1a2df439547c9349d@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9dcc7e28 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Rename `cloneBndrs` and such — now all the monadic ones have an `M` suffix. We now have `cloneBndrs` and `cloneRecIdBndrs` which take a `UniqSupply` argument, and `cloneBndrsM` and `cloneRecIdBndrsM` which rather have a `MonadUnique` constraint. - - - - - 643dd3d8 by Matthew Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in unique generation, and clean up some other partial uni patterns as well. Also drop the losing `instance MonadFail UniqSM`. We redefine `getUniquesM` in terms of `Infinite` rather than `[]`, and define another method `getUniqueListM` for the use sites where we actually want a `[]`. Thus, at many sites, we can avoid the partiality of the empty list case. We also define `withUniques`, `withUniquesM`, and `withUniquesM'`, which traverse an arbitrary `Traversable` structure and introduce a `Unique` for each element. This allows us to redefine various functions to operate on more appropriate types than `[]` and avoid further partiality (in the form of incomplete-uni-patterns). - - - - - dd0acc3c by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Tc.Deriv.Functor`. Make the list of variables to use in generated code `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - 4e9adedf by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Runtime.Debugger`. Make the list of available names `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - bed812b7 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Cmm.DebugBlock`. We do so by changing the type of `BlockContext` to statically (in GHC) exclude the possibility of Cmm statics, and using `NonEmpty` lists of `BlockContext`s in `cmmDebugGen`. - - - - - 27587df3 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Types.Literal`. We do so by introducing `mkLitNumberWrap'` whose ultimate codomain is `Integer` rather than `Literal`, and then use that rather than `mkLitNumberWrap` where we just need the number rather than the `Literal`. - - - - - 138de0ff by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.CmmToAsm.X86.CodeGen`. - Match the vector element list only once in `shuffleInstructions`. - Define `isSuitableFloatingPointLit_maybe` which returns `Just` the width if the lit is indeed suitable. - - - - - d8cb3d36 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Clean up more incomplete uni patterns. At some sites, we merely panic if the `[]` or `Maybe` is empty when we convert to `NonEmpty` or `Identity`, but at least now we make it explicit. At other sites, we are able to use more precise types and avoid the partiality altogether. To do so, we redefine various functions to operate over `Traversable` arguments, so we can use the appropriate shape where known. - - - - - f251bd22 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Outline `expectJustPanic`. - - - - - 30 changed files: - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/List/Infinite.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Pipeline/Execute.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Quote.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8071bad8b185bc9d0f71e08b6520a5d5705e2636...f251bd223cdd27e02d688844dadc5e19ea91344a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8071bad8b185bc9d0f71e08b6520a5d5705e2636...f251bd223cdd27e02d688844dadc5e19ea91344a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 07:28:58 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 02:28:58 -0500 Subject: [Git][ghc/ghc][master] base: Introduce Data.Enum.enumerate (CLC #306) Message-ID: <6799d8ba53dd8_1a2df45b76109626c@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a963a1a5 by Marc Scholten at 2025-01-29T02:28:35-05:00 base: Introduce Data.Enum.enumerate (CLC #306) https://github.com/haskell/core-libraries-committee/issues/306 - - - - - 6 changed files: - libraries/base/changelog.md - libraries/base/src/Data/Enum.hs - testsuite/tests/interface-stability/base-exports.stdout - testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs - testsuite/tests/interface-stability/base-exports.stdout-mingw32 - testsuite/tests/interface-stability/base-exports.stdout-ws-32 Changes: ===================================== libraries/base/changelog.md ===================================== @@ -9,6 +9,7 @@ * `Data.List.NonEmpty.{init,last,tails1}` are now defined using only total functions (rather than partial ones). ([CLC proposal #293](https://github.com/haskell/core-libraries-committee/issues/293)) * `Data.List.NonEmpty` functions now have the same laziness as their `Data.List` counterparts (i.e. make them more strict than they currently are) ([CLC proposal #107](https://github.com/haskell/core-libraries-committee/issues/107)) * `instance Functor NonEmpty` is now specified using `map` (rather than duplicating code). ([CLC proposal #300](https://github.com/haskell/core-libraries-committee/issues/300)) + * The `Data.Enum.enumerate` function was introduced ([CLC #306](https://github.com/haskell/core-libraries-committee/issues/306)) ## 4.21.0.0 *TBA* * Change `SrcLoc` to be a strict and unboxed (finishing [CLC proposal #55](https://github.com/haskell/core-libraries-committee/issues/55)) ===================================== libraries/base/src/Data/Enum.hs ===================================== @@ -21,6 +21,34 @@ module Data.Enum ( Enum(..) , {-# DEPRECATED "Bounded should be imported from Data.Bounded" #-} Bounded(..) + , enumerate ) where import GHC.Internal.Enum + +-- | Returns a list of all values of an enum type +-- +-- 'enumerate' is often used to list all values of a custom enum data structure, such as a custom Color enum below: +-- +-- @ +-- data Color = Yellow | Red | Blue +-- deriving (Enum, Bounded, Show) +-- +-- allColors :: [Color] +-- allColors = enumerate +-- -- Result: [Yellow, Red, Blue] +-- @ +-- +-- Note that you need to derive the 'Bounded' type class as well, only 'Enum' is not enough. +-- 'Enum' allows for sequential enumeration, while 'Bounded' provides the 'minBound' and 'maxBound' values. +-- +-- 'enumerate' is commonly used together with the TypeApplications syntax. Here is an example of using 'enumerate' to retrieve all values of the 'Ordering' type: +-- +-- >> enumerate @Ordering +-- [LT, EQ, GT] +-- +-- The '@' symbol here is provided by the TypeApplications language extension. +-- +-- @since base-4.22.0.0 +enumerate :: (Enum a, Bounded a) => [a] +enumerate = [minBound .. maxBound] \ No newline at end of file ===================================== testsuite/tests/interface-stability/base-exports.stdout ===================================== @@ -979,6 +979,7 @@ module Data.Enum where enumFromTo :: a -> a -> [a] enumFromThenTo :: a -> a -> a -> [a] {-# MINIMAL toEnum, fromEnum #-} + enumerate :: forall a. (Enum a, Bounded a) => [a] module Data.Eq where -- Safety: Safe ===================================== testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs ===================================== @@ -979,6 +979,7 @@ module Data.Enum where enumFromTo :: a -> a -> [a] enumFromThenTo :: a -> a -> a -> [a] {-# MINIMAL toEnum, fromEnum #-} + enumerate :: forall a. (Enum a, Bounded a) => [a] module Data.Eq where -- Safety: Safe ===================================== testsuite/tests/interface-stability/base-exports.stdout-mingw32 ===================================== @@ -979,6 +979,7 @@ module Data.Enum where enumFromTo :: a -> a -> [a] enumFromThenTo :: a -> a -> a -> [a] {-# MINIMAL toEnum, fromEnum #-} + enumerate :: forall a. (Enum a, Bounded a) => [a] module Data.Eq where -- Safety: Safe ===================================== testsuite/tests/interface-stability/base-exports.stdout-ws-32 ===================================== @@ -979,6 +979,7 @@ module Data.Enum where enumFromTo :: a -> a -> [a] enumFromThenTo :: a -> a -> a -> [a] {-# MINIMAL toEnum, fromEnum #-} + enumerate :: forall a. (Enum a, Bounded a) => [a] module Data.Eq where -- Safety: Safe View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a963a1a5d38cd6fbb722f3d25c31744238d71b65 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a963a1a5d38cd6fbb722f3d25c31744238d71b65 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 07:29:40 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 02:29:40 -0500 Subject: [Git][ghc/ghc][master] base: Update description of locking behavior Message-ID: <6799d8e455d28_1a2df416bc5099023@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 944712da by Ben Gamari at 2025-01-29T02:29:13-05:00 base: Update description of locking behavior - - - - - 1 changed file: - libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock.hs Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock.hs ===================================== @@ -35,14 +35,20 @@ import GHC.Internal.IO.Handle.Lock.NoOp -- -- Things to be aware of: -- --- 1) This function may block inside a C call. If it does, in order to be able +-- 1. This function may block inside a C call. If it does, in order to be able -- to interrupt it with asynchronous exceptions and/or for other threads to -- continue working, you MUST use threaded version of the runtime system. -- --- 2) The implementation uses 'LockFileEx' on Windows and 'flock' otherwise, +-- 2. The implementation uses relies on any of a number of locking +-- facilities, depending upon what the platform supports: +-- +-- * 'LockFileEx' is used on Windows +-- * On platforms that support it we use the @F_OFD_SETLK@ and @F_OFD_SETLKW@ @fnctl at s. +-- * Otherwise we use @flock@ +-- -- hence all of their caveats also apply here. -- --- 3) On non-Windows platforms that don't support 'flock' (e.g. Solaris) this +-- 3. On non-Windows platforms that don't support 'flock' (e.g. Solaris) this -- function throws 'FileLockingNotImplemented'. We deliberately choose to not -- provide fcntl based locking instead because of its broken semantics. -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/944712dad749f39d087b868d8e5c2126601994f9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/944712dad749f39d087b868d8e5c2126601994f9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 07:31:06 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 02:31:06 -0500 Subject: [Git][ghc/ghc][master] base: Fix @since annotation of Data.Bounded Message-ID: <6799d93aee24_1a2df437d96c105759@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 85abc69c by Ben Gamari at 2025-01-29T02:29:51-05:00 base: Fix @since annotation of Data.Bounded Fixes #25615. - - - - - 1 changed file: - libraries/base/src/Data/Bounded.hs Changes: ===================================== libraries/base/src/Data/Bounded.hs ===================================== @@ -13,7 +13,7 @@ -- -- The 'Bounded' class. -- --- @since 4.22.0.0 +-- @since 4.21.0.0 -- ----------------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85abc69c223a692652c8767c49dacfd1ce6c9bf3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85abc69c223a692652c8767c49dacfd1ce6c9bf3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 07:31:51 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 02:31:51 -0500 Subject: [Git][ghc/ghc][master] 2 commits: StgToByteCode: Fix overly-broad handling of Addr# literals Message-ID: <6799d967eabff_1a2df4f2b78c1100d0@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2ca41c62 by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Fix overly-broad handling of Addr# literals Previously we assumed that all unlifted types were `Addr#` but this isn't true. As noted in #25638, unlifted nullary data constructor workers can also appear at the top-level and are obviously not of type `Addr#`. Note that there is more work to be done to properly handle unlifted data constructors (especially nullary; see #25636). However, this is a small step in the right direction. Closes #25641. - - - - - ec26c54d by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Assert that PUSH_G'd values are lifted We currently do not support top-level unlifted data constructor applications, therefore this is a safe assertion. Pointed out by @sheaf. - - - - - 3 changed files: - compiler/GHC/StgToByteCode.hs - testsuite/tests/codeGen/should_run/T23146/all.T - testsuite/tests/unlifted-datatypes/should_run/all.T Changes: ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -1951,14 +1951,17 @@ pushAtom d p (StgVarArg var) Nothing -- see Note [Generating code for top-level string literal bindings] - | isUnliftedType (idType var) -> do - massert (idType var `eqType` addrPrimTy) + | idType var `eqType` addrPrimTy -> return (unitOL (PUSH_ADDR (getName var)), szb) | otherwise -> do + let varTy = idType var + massertPpr (definitelyLiftedType varTy) $ + vcat [ text "pushAtom: unhandled unlifted type" + , text "var:" <+> ppr var <+> dcolon <+> ppr varTy <> dcolon <+> ppr (typeKind varTy) + ] return (unitOL (PUSH_G (getName var)), szb) - pushAtom _ _ (StgLitArg lit) = pushLiteral True lit pushLiteral :: Bool -> Literal -> BcM (BCInstrList, ByteOff) ===================================== testsuite/tests/codeGen/should_run/T23146/all.T ===================================== @@ -1,4 +1,4 @@ -test('T23146', expect_broken_for(23060, ghci_ways), compile_and_run, ['']) +test('T23146', normal, compile_and_run, ['']) test('T23146_lifted', normal, compile_and_run, ['']) test('T23146_liftedeq', expect_broken_for(23060, ghci_ways), compile_and_run, ['']) test('T23146_lifted_unlifted', normal, compile_and_run, ['']) ===================================== testsuite/tests/unlifted-datatypes/should_run/all.T ===================================== @@ -1,3 +1,3 @@ test('UnlData1', normal, compile_and_run, ['']) -test('UnlGadt1', [exit_code(1), expect_broken_for(23060, ghci_ways)], compile_and_run, ['']) +test('UnlGadt1', exit_code(1), compile_and_run, ['']) test('T23549', normal, multimod_compile_and_run, ['T23549', '']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85abc69c223a692652c8767c49dacfd1ce6c9bf3...ec26c54d818e0cd328276196930313f66b780905 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85abc69c223a692652c8767c49dacfd1ce6c9bf3...ec26c54d818e0cd328276196930313f66b780905 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 07:32:41 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 02:32:41 -0500 Subject: [Git][ghc/ghc][master] gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Message-ID: <6799d9997eb49_1a2df45b7610114376@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8847125f by Ben Gamari at 2025-01-29T02:31:07-05:00 gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Closes #25654. - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -909,6 +909,7 @@ test-primops-label: extends: .test-primops-validate-template rules: - if: '$CI_MERGE_REQUEST_LABELS =~ /.*test-primops.*/' + - *full-ci test-primops-nightly: extends: .test-primops View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8847125fecdccc4dcda45b1dba519c6dd88b4401 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8847125fecdccc4dcda45b1dba519c6dd88b4401 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 07:33:00 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 02:33:00 -0500 Subject: [Git][ghc/ghc][master] bytecode: Do not generate `SLIDE x 0` instructions Message-ID: <6799d9acb10ac_1a2df411fe09011452a@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: bf8c7d6e by Matthew Pickering at 2025-01-29T02:31:44-05:00 bytecode: Do not generate `SLIDE x 0` instructions SLIDE x 0 is a no-op as it means to shift x elements of the stack by no spaces. In the interpreter, this results in a loop which copies an array element into the same place. I have instrumented GHCi to count how many of these instructions are interpreted. The workload was `ghc` compiling two simple modules. Total no-op slides: 7793476 Total slides: 11413289 Percentage useless (slides): 68% Percentage uselss of total instructions: 9% - - - - - 1 changed file: - compiler/GHC/StgToByteCode.hs Changes: ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -548,7 +548,7 @@ returnUnliftedReps d s szb reps = do PUSH_BCO tuple_bco `consOL` unitOL RETURN_TUPLE return ( mkSlideB platform szb (d - s) -- clear to sequel - `consOL` ret) -- go + `appOL` ret) -- go -- construct and return an unboxed tuple returnUnboxedTuple @@ -812,7 +812,7 @@ doTailCall init_d s p fn args = do platform <- profilePlatform <$> getProfile assert (sz == wordSize platform) return () let slide = mkSlideB platform (d - init_d + wordSize platform) (init_d - s) - return (push_fn `appOL` (slide `consOL` unitOL ENTER)) + return (push_fn `appOL` (slide `appOL` unitOL ENTER)) do_pushes !d args reps = do let (push_apply, n, rest_of_reps) = findPushSeq reps (these_args, rest_of_args) = splitAt n args @@ -1531,7 +1531,7 @@ generatePrimCall d s p target _mb_unit _result_ty args (push_target `consOL` push_info `consOL` PUSH_BCO args_bco `consOL` - (mkSlideB platform szb (d - s) `consOL` unitOL PRIMCALL)) + (mkSlideB platform szb (d - s) `appOL` unitOL PRIMCALL)) -- ----------------------------------------------------------------------------- -- Deal with a CCall. @@ -2266,8 +2266,8 @@ unsupportedCConvException = throwGhcException (ProgramError ("Error: bytecode compiler can't handle some foreign calling conventions\n"++ " Workaround: use -fobject-code, or compile this module to .o separately.")) -mkSlideB :: Platform -> ByteOff -> ByteOff -> BCInstr -mkSlideB platform nb db = SLIDE n d +mkSlideB :: Platform -> ByteOff -> ByteOff -> OrdList BCInstr +mkSlideB platform nb db = mkSlideW n d where !n = bytesToWords platform nb !d = bytesToWords platform db View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bf8c7d6edf224c083c90ab3ddac49979ac18ad39 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bf8c7d6edf224c083c90ab3ddac49979ac18ad39 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 10:48:49 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 29 Jan 2025 05:48:49 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/optim-faststring Message-ID: <679a0791ecb04_1e5a1310c90d010404e@gitlab.mail> Matthew Pickering pushed new branch wip/optim-faststring at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/optim-faststring You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 10:49:37 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 29 Jan 2025 05:49:37 -0500 Subject: [Git][ghc/ghc][wip/optim-faststring] 22 commits: Fix for alex-3.5.2.0 (#25623) Message-ID: <679a07c1556d_1e5a131052ef8104222@gitlab.mail> Matthew Pickering pushed to branch wip/optim-faststring at Glasgow Haskell Compiler / GHC Commits: a1d92378 by Brandon Chinn at 2025-01-25T15:11:54-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 62760367 by ARATA Mizuki at 2025-01-27T16:23:06-05:00 x86 NCG: Make MOVD's output format explicit The old design led to inference of a wrong format, losing upper bits of a vector register. Fixes #25659 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - f19ab490 by Simon Hengel at 2025-01-27T16:23:45-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - e16eae65 by Cheng Shao at 2025-01-27T21:41:39+00:00 hadrian: fix bootstrap with 9.12.1 This patch bumps hadrian index-state to fix bootstrap with 9.12.1. - - - - - 8071bad8 by Jeffrey Young at 2025-01-28T21:45:32-05:00 base: add SrcLoc changes to changelog, 4.21.0.0 I accidentally dropped this in !13381 - closes #25614 See: - ea4587794b9e3a098f9c02bd6cea2294af2539ce (the 13381 commit) - Issue #25614 - - - - - 9dcc7e28 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Rename `cloneBndrs` and such — now all the monadic ones have an `M` suffix. We now have `cloneBndrs` and `cloneRecIdBndrs` which take a `UniqSupply` argument, and `cloneBndrsM` and `cloneRecIdBndrsM` which rather have a `MonadUnique` constraint. - - - - - 643dd3d8 by Matthew Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in unique generation, and clean up some other partial uni patterns as well. Also drop the losing `instance MonadFail UniqSM`. We redefine `getUniquesM` in terms of `Infinite` rather than `[]`, and define another method `getUniqueListM` for the use sites where we actually want a `[]`. Thus, at many sites, we can avoid the partiality of the empty list case. We also define `withUniques`, `withUniquesM`, and `withUniquesM'`, which traverse an arbitrary `Traversable` structure and introduce a `Unique` for each element. This allows us to redefine various functions to operate on more appropriate types than `[]` and avoid further partiality (in the form of incomplete-uni-patterns). - - - - - dd0acc3c by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Tc.Deriv.Functor`. Make the list of variables to use in generated code `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - 4e9adedf by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Runtime.Debugger`. Make the list of available names `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - bed812b7 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Cmm.DebugBlock`. We do so by changing the type of `BlockContext` to statically (in GHC) exclude the possibility of Cmm statics, and using `NonEmpty` lists of `BlockContext`s in `cmmDebugGen`. - - - - - 27587df3 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Types.Literal`. We do so by introducing `mkLitNumberWrap'` whose ultimate codomain is `Integer` rather than `Literal`, and then use that rather than `mkLitNumberWrap` where we just need the number rather than the `Literal`. - - - - - 138de0ff by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.CmmToAsm.X86.CodeGen`. - Match the vector element list only once in `shuffleInstructions`. - Define `isSuitableFloatingPointLit_maybe` which returns `Just` the width if the lit is indeed suitable. - - - - - d8cb3d36 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Clean up more incomplete uni patterns. At some sites, we merely panic if the `[]` or `Maybe` is empty when we convert to `NonEmpty` or `Identity`, but at least now we make it explicit. At other sites, we are able to use more precise types and avoid the partiality altogether. To do so, we redefine various functions to operate over `Traversable` arguments, so we can use the appropriate shape where known. - - - - - f251bd22 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Outline `expectJustPanic`. - - - - - a963a1a5 by Marc Scholten at 2025-01-29T02:28:35-05:00 base: Introduce Data.Enum.enumerate (CLC #306) https://github.com/haskell/core-libraries-committee/issues/306 - - - - - 944712da by Ben Gamari at 2025-01-29T02:29:13-05:00 base: Update description of locking behavior - - - - - 85abc69c by Ben Gamari at 2025-01-29T02:29:51-05:00 base: Fix @since annotation of Data.Bounded Fixes #25615. - - - - - 2ca41c62 by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Fix overly-broad handling of Addr# literals Previously we assumed that all unlifted types were `Addr#` but this isn't true. As noted in #25638, unlifted nullary data constructor workers can also appear at the top-level and are obviously not of type `Addr#`. Note that there is more work to be done to properly handle unlifted data constructors (especially nullary; see #25636). However, this is a small step in the right direction. Closes #25641. - - - - - ec26c54d by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Assert that PUSH_G'd values are lifted We currently do not support top-level unlifted data constructor applications, therefore this is a safe assertion. Pointed out by @sheaf. - - - - - 8847125f by Ben Gamari at 2025-01-29T02:31:07-05:00 gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Closes #25654. - - - - - bf8c7d6e by Matthew Pickering at 2025-01-29T02:31:44-05:00 bytecode: Do not generate `SLIDE x 0` instructions SLIDE x 0 is a no-op as it means to shift x elements of the stack by no spaces. In the interpreter, this results in a loop which copies an array element into the same place. I have instrumented GHCi to count how many of these instructions are interpreted. The workload was `ghc` compiling two simple modules. Total no-op slides: 7793476 Total slides: 11413289 Percentage useless (slides): 68% Percentage uselss of total instructions: 9% - - - - - e97bdd8c by Matthew Pickering at 2025-01-29T10:49:25+00:00 compiler: Always load GHC.Data.FastString optimised into GHCi The FastString table is shared between the boot compiler and interpreted compiler. Therefore it's very important the representation of `FastString` matches in both cases. Otherwise, the interpreter will read a FastString from the shared variable but place the fields in the wrong place which leads to segfaults. Ideally this state would not be shared, but for now we can always compile both with `-O2` and this leads to a working interpreter. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/43bafd4709484f41ea0a91d2503b637481b2f05c...e97bdd8cb337c3ea23326d88f83219e84f381a42 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/43bafd4709484f41ea0a91d2503b637481b2f05c...e97bdd8cb337c3ea23326d88f83219e84f381a42 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 10:49:50 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Wed, 29 Jan 2025 05:49:50 -0500 Subject: [Git][ghc/ghc][wip/T24359] WIP: original approach but with TcSSpecPrag Message-ID: <679a07cee3b92_1e5a131052e6c1044b7@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 0481938d by sheaf at 2025-01-29T11:49:33+01:00 WIP: original approach but with TcSSpecPrag - - - - - 14 changed files: - compiler/GHC/Core/Predicate.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Solver/Default.hs - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Equality.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Solver/Solve.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Zonk/Type.hs - + testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Predicate.hs ===================================== @@ -554,8 +554,8 @@ types/kinds are fully settled and zonked. -- | Do a topological sort on a list of tyvars, -- so that binders occur before occurrences --- E.g. given [ a::k, k::*, b::k ] --- it'll return a well-scoped list [ k::*, a::k, b::k ] +-- E.g. given @[ a::k, k::Type, b::k ]@ +-- it'll return a well-scoped list @[ k::Type, a::k, b::k ]@. -- -- This is a deterministic sorting operation -- (that is, doesn't depend on Uniques). ===================================== compiler/GHC/Hs/Binds.hs ===================================== @@ -824,7 +824,8 @@ instance NoAnn AnnSig where -- | Type checker Specialisation Pragmas -- --- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker to the desugarer +-- 'TcSpecPrags' conveys @SPECIALISE@ pragmas from the type checker +-- to the desugarer data TcSpecPrags = IsDefaultMethod -- ^ Super-specialised: a default method should -- be macro-expanded at every call site @@ -834,21 +835,36 @@ data TcSpecPrags type LTcSpecPrag = Located TcSpecPrag -- | Type checker Specialisation Pragma --- This data type is used briefly, to communicate between the typechecker and renamer +-- +-- This data type is used to communicate between the typechecker and +-- the desugarer. data TcSpecPrag - = SpecPrag Id HsWrapper InlinePragma - -- ^ The Id to be specialised, a wrapper that specialises the - -- polymorphic function, and inlining spec for the specialised function - - | SpecPragE { spe_fn_nm :: Name -- The Name of the Id being specialised - , spe_fn_id :: Id -- The Id being specialised - -- The spe_fn_name may differ from (idName spe_fn_id) in the - -- case of instance methods, where the Name is the class-op - -- selector but the spe_fn_id is that for the local method - - , spe_bndrs :: [Var] -- TyVars, EvVars, and Ids - , spe_call :: LHsExpr GhcTc -- The LHS of the RULE: a call of f - , spe_inl :: InlinePragma } + -- | Old-form specialise pragma + = SpecPrag + Id + -- ^ 'Id' to be specialised + HsWrapper + -- ^ wrapper that specialises the polymorphic function + InlinePragma + -- ^ inlining spec for the specialised function + -- | New-form specialise pragma + | SpecPragE + { spe_fn_nm :: Name + -- ^ 'Name' of the 'Id' being specialised + , spe_fn_id :: Id + -- ^ 'Id' being specialised + -- + -- Note that 'spe_fn_nm' may differ from @'idName' 'spe_fn_id'@ + -- in the case of instance methods, where the 'Name' is the + -- class-op selector but the 'spe_fn_id' is that for the local method + , spe_inl :: InlinePragma + -- ^ (optional) INLINE annotation and activation phase annotation + + , spe_bndrs :: [Var] + -- ^ TyVars, EvVars, and Ids + , spe_call :: LHsExpr GhcTc + -- ^ The type-checked specialise expression + } noSpecPrags :: TcSpecPrags noSpecPrags = SpecPrags [] ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -823,7 +823,7 @@ Notice that let { d = d2; d1 = $dfOrdInt } in f @Int @b (d2:Eq b) Do no inlining in this "simple optimiser" phase: use `simpleOptExprNoInline`. E.g. we don't want to turn - let { d1=d; d2=d } in f d d --> f d d + let { d1=d; d2=d } in f d1 d2 --> f d d because the latter is harder to match. (SP2) the function `prepareSpecLHS` takes the simplified LHS `core_call` and @@ -921,14 +921,19 @@ dsSpec poly_rhs (SpecPrag poly_id spec_co spec_inl) rule_bndrs poly_id rule_lhs_args spec_bndrs core_app spec_inl } } -dsSpec poly_rhs (SpecPragE { spe_fn_nm = poly_nm - , spe_fn_id = poly_id - , spe_bndrs = bndrs - , spe_call = the_call - , spe_inl = inl }) +dsSpec poly_rhs ( + SpecPragE + { spe_fn_nm = poly_nm + , spe_fn_id = poly_id + , spe_inl = inl + , spe_bndrs = bndrs + , spe_call = the_call + }) -- SpecPragE case: See Note [Handling new-form SPECIALISE pragmas] in GHC.Tc.Gen.Sig - = do { ds_call <- zapUnspecables $ -- zapUnspecables: see - dsLExpr the_call -- Note [Desugaring RULE left hand sides] + = do { ds_call <- unsetGOptM Opt_EnableRewriteRules $ -- Note [Desugaring RULE left hand sides] + unsetWOptM Opt_WarnIdentities $ + zapUnspecables $ + dsLExpr the_call -- Simplify the (desugared) call; see wrinkle (SP1) -- in Note [Desugaring SPECIALISE pragmas] @@ -1054,7 +1059,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args ; tracePm "dsSpec" (vcat [ text "fun:" <+> ppr poly_id - , text "spec_bndrs:" <+> ppr spec_bndrs + , text "spec_bndrs:" <+> ppr spec_bndrs , text "args:" <+> ppr rule_args ]) ; return (unitOL (spec_id, spec_rhs), rule) } -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because @@ -1077,7 +1082,7 @@ finishSpecPrag poly_nm poly_rhs rule_bndrs poly_id rule_args | all is_nop_arg rule_args, not (isInlinePragma spec_inl) -- The specialisation does nothing. - -- But don't compliain if it is SPECIALISE INLINE (#4444) + -- But don't complain if it is SPECIALISE INLINE (#4444) = Just UselessSpecialiseNoSpecialisation | otherwise ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS, runTcSWithEvBinds ) +import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPragWithEvBinds ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -50,7 +50,7 @@ import GHC.Tc.Utils.Instantiate( topInstantiate, tcInstTypeBndrs ) import GHC.Tc.Utils.Env import GHC.Tc.Types.Origin -import GHC.Tc.Types.Evidence( HsWrapper(..), (<.>), TcEvBinds(..) ) +import GHC.Tc.Types.Evidence import GHC.Tc.Types.Constraint import GHC.Tc.Zonk.TcType @@ -703,17 +703,24 @@ Note [Handling new-form SPECIALISE pragmas] New-form SPECIALISE pragmas are described by GHC Proposal #493. The pragma takes the form of a function application, possibly with intervening -parens and type signatures, with a variable at the head. It may have rule -for-alls at the top. e.g. +parens and type signatures, with a variable at the head: {-# SPECIALISE f1 @Int 3 #-} - {-# SPECIALISE forall x xs. f2 (x:xs) #-} - {-# SPECIALISE f3 :: Int -> Int #-} - {-# SPECIALISE (f4 :: Int -> Int) 5 #-} + {-# SPECIALISE f2 :: Int -> Int #-} + {-# SPECIALISE (f3 :: Int -> Int) 5 #-} + +It may also have rule for-alls at the top, e.g. + + {-# SPECIALISE forall x xs. f4 (x:xs) #-} {-# SPECIALISE forall a. forall x xs. f5 @a @a (x:xs) #-} See `GHC.Rename.Bind.checkSpecESigShape` for the shape-check. +We are going to use the following (perhaps somewhat contrived) example to +demonstrate the subtle aspects of the implementation: + + f :: forall a b c d. (Eq a, Eq b, Eq c, Eq d) => a -> b -> c -> d -> Bool -> blah + {-# SPECIALISE forall t. forall x y z. f (x::[Proxy t]) y y [z] True #-} Example: f :: forall a b. (Eq a, Eq b, Eq c) => a -> b -> c -> Bool -> blah @@ -755,26 +762,46 @@ Note that spec_const_binds = let d1 = $fEqInt d3 = d2 -How it works: +This is done in three parts. + + A. Typechecker: `GHC.Tc.Gen.Sig.tcSpecPrag` + + (1) Typecheck the expression, capturing its constraints + + (2) Simplify these constraints, in special TcSSpecPrag mode + SLD TODO add more details. + + (3) Decide which constraints to quantify over, and quantify. -* `GHC.Tc.Gen.Sig.tcSpecPrag` just typechecks the expression, putting the results - into a `SpecPragE` record. Nothing very exciting happens here. + (4) Emit the residual (non-quantified) constraints, and wrap the + expression in a let binding for those constraints. -* `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` does a little extra work to collect any - free type variables of the LHS. See Note [Free tyvars on rule LHS] in - GHC.Tc.Zonk.Type. These weren't conveniently available earlier. + (5) Store all the information in a 'SpecPragE' record, to be consumed + by the desugarer. -* `GHC.HsToCore.Binds.dsSpec` does the clever stuff: + B. Zonker: `GHC.Tc.Zonk.Type.zonkLTcSpecPrags` - * Simplifies the expression. This is important because a type signature in the - expression will have led to type/dictionary abstractions/applications. Now - it should look like - let in f e1 e1 e3 + The zonker does a little extra work to collect any free type variables + of the LHS. See Note [Free tyvars on rule LHS] in GHC.Tc.Zonk.Type. + These weren't conveniently available earlier. - * `prepareSpecLHS` identifies the `spec_const_binds` (see above), discards - the other dictionary bindings, and decomposes the call. + C. Desugarer: `GHC.HsToCore.Binds.dsSpec`. - * Then it can build the RULE and specialised function. + This is where most of the clever stuff happens. See + Note [Desugaring SPECIALISE pragmas] in GHC.HsToCore.Binds for details, + but in brief: + + (1) Simplify the expression. This is important because a type signature in + the expression will have led to type/dictionary abstractions/applications. + Now it should look like + let in f d1 d2 d3 + + (2) `prepareSpecLHS` identifies the `spec_const_binds`, discards the other + dictionary bindings, and decomposes the call. + + (3) Then we build the specialised function $sf, and concoct a RULE + of the form: + forall @a @b d1 d2 d3. f d1 d2 d3 = $sf d1 d2 d3 Note [Handling old-form SPECIALISE pragmas] @@ -944,38 +971,41 @@ tcSpecPrag poly_id prag@(SpecSig _ fun_name hs_tys inl) ; return (SpecPrag poly_id wrap inl) } tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) - = do { -- Typecheck the expression, spec_e, capturing its constraints + -- For running commentary, see Note [Handling new-form SPECIALISE pragmas] + = do { -- (1) Typecheck the expression, spec_e, capturing its constraints let skol_info_anon = SpecESkol nm - ; traceTc "tcSpecPrag: specSigE1" (ppr nm $$ ppr spec_e) + ; traceTc "tcSpecPrag SpecSigE 1" (ppr nm $$ ppr spec_e) ; skol_info <- mkSkolemInfo skol_info_anon - ; (rhs_tclvl, wanted, (rule_bndrs', (spec_e', _rho))) + ; (rhs_tclvl, wanted, (rule_bndrs', (tc_spec_e, _rho))) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- Simplify the constraints + -- (2) Simplify the constraints, in special TcSSpecPrag mode ; ev_binds_var <- newTcEvBinds ; wanted <- setTcLevel rhs_tclvl $ - runTcSWithEvBinds ev_binds_var $ + runTcSSpecPragWithEvBinds ev_binds_var $ solveWanteds wanted - -- Quantify over the the constraints + -- (3) Quantify over the constraints ; qevs <- mapM newEvVar $ ctsPreds $ approximateWC False wanted + -- (4) Emit the residual (non-quantified) constraints, + -- and wrap the expression in the evidence let bindings ; let tv_bndrs = filter isTyVar rule_bndrs' ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var emptyVarSet tv_bndrs qevs wanted + ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) tc_spec_e ; traceTc "tcSpecPrag:SpecSigE" $ vcat [ text "nm:" <+> ppr nm , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs - , text "spec_e:" <+> ppr spec_e' + , text "spec_e:" <+> ppr tc_spec_e , text "inl:" <+> ppr inl ] - ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) spec_e' ; return [SpecPragE { spe_fn_nm = nm , spe_fn_id = poly_id , spe_bndrs = qevs ++ rule_bndrs' -- Dependency order @@ -1414,9 +1444,9 @@ in `getRuleQuantCts`. Why not? * Equality constraints are unboxed, and that leads to complications For example equality constraints from the LHS will emit coercion hole Wanteds. These don't have a name, so we can't quantify over them directly. - Instead, in `mk_one` in `getRuleQuantCts` in we'd have to invent a new EvVar - for the coercion, fill the hole with the invented EvVar, and then quantify - over the EvVar. Here is old code from `mk_one` + Instead, in `getRuleQuantCts`, we'd have to invent a new EvVar for the + coercion, fill the hole with the invented EvVar, and then quantify over the + EvVar. Here is old code from `mk_one` do { ev_id <- newEvVar pred ; fillCoercionHole hole (mkCoVarCo ev_id) ; return ev_id } @@ -1483,7 +1513,8 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; lhs_wanted <- liftZonkM $ zonkWC lhs_wanted -- Note [The SimplifyRule Plan] step 3 - ; (quant_evs, residual_lhs_wanted) <-getRuleQuantCts lhs_wanted + ; (quant_cts, residual_lhs_wanted) <- getRuleQuantCts lhs_wanted + ; let quant_evs = map ctEvId (bagToList quant_cts) ; traceTc "simplifyRule" $ vcat [ text "LHS of rule" <+> doubleQuotes (ftext name) @@ -1496,7 +1527,7 @@ simplifyRule name tc_lvl lhs_wanted rhs_wanted ; return (quant_evs, residual_lhs_wanted, dont_default) } -getRuleQuantCts :: WantedConstraints -> TcM ([EvVar], WantedConstraints) +getRuleQuantCts :: WantedConstraints -> TcM (Cts, WantedConstraints) -- Extract all the constraints that we can quantify over, -- also returning the depleted WantedConstraints -- @@ -1504,20 +1535,17 @@ getRuleQuantCts :: WantedConstraints -> TcM ([EvVar], WantedConstraints) -- and attempt to solve them from the quantified constraints. Instead -- we /partition/ the WantedConstraints into ones to quantify and ones -- we can't quantify. We could use approximateWC instead, and leave --- `wanted` unchanged; but then we'd have clone fresh binders and +-- `wanted` unchanged; but then we'd have to clone fresh binders and -- generate silly identity bindings. Seems more direct to do this. --- Probably not a big eal wither way. +-- Probably not a big deal wither way. -- -- NB: we must look inside implications, because with -- -fdefer-type-errors we generate implications rather eagerly; -- see GHC.Tc.Utils.Unify.implicationNeeded. Not doing so caused #14732. getRuleQuantCts wc - = do { quant_evs <- mapM mk_one (bagToList quant_cts) - ; return (quant_evs, residual_wc) } + = return $ float_wc emptyVarSet wc where - (quant_cts, residual_wc) = float_wc emptyVarSet wc - float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_errors = errs }) = ( simple_yes `andCts` implic_yes @@ -1542,17 +1570,6 @@ getRuleQuantCts wc EqPred {} -> False -- Note [RULE quantification over equalities] _ -> tyCoVarsOfCt ct `disjointVarSet` skol_tvs - mk_one :: Ct -> TcM EvVar - mk_one ct - | CtWanted { ctev_dest = dest } <- ctEvidence ct - , EvVarDest ev_id <- dest - -- HoleDest can't happen because we don't quantify - -- over EqPred: See rule_quant_ct above - = return ev_id - - | otherwise - = pprPanic "getRuleQuantCts" (ppr ct) - {- Note [Quantifying over equalities in RULES] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Solver/Default.hs ===================================== @@ -973,7 +973,7 @@ tryDefaultGroup wanteds (Proposal assignments) errInvalidDefaultedTyVar :: WantedConstraints -> Proposal -> NonEmpty TcTyVar -> TcS () errInvalidDefaultedTyVar wanteds (Proposal assignments) problematic_tvs - = failTcS $ TcRnInvalidDefaultedTyVar tidy_wanteds tidy_assignments tidy_problems + = failWithTcS $ TcRnInvalidDefaultedTyVar tidy_wanteds tidy_assignments tidy_problems where proposal_tvs = concatMap (\(tv, ty) -> tv : tyCoVarsOfTypeList ty) assignments tidy_env = tidyFreeTyCoVars emptyTidyEnv $ proposal_tvs ++ NE.toList problematic_tvs ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -3,6 +3,7 @@ -- | Solving Class constraints CDictCan module GHC.Tc.Solver.Dict ( solveDict, solveDictNC, + shortCutSolver, checkInstanceOK, matchLocalInst, chooseInstance, makeSuperClasses, mkStrictSuperClasses, @@ -727,7 +728,9 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys do { -- First to try to solve it /completely/ from top level instances -- See Note [Shortcut solving] dflags <- getDynFlags - ; short_cut_worked <- shortCutSolver dflags ev_w ev_i + ; short_cut_worked <- if wantShortCut dflags ev_w ev_i + then shortCutSolver dflags ev_w + else return False ; if short_cut_worked then stopWith ev_w "interactDict/solved from instance" @@ -755,31 +758,42 @@ try_inert_dicts inerts dict_w@(DictCt { di_ev = ev_w, di_cls = cls, di_tys = tys = do { traceTcS "tryInertDicts:no" (ppr dict_w $$ ppr cls <+> ppr tys) ; continueWith () } --- See Note [Shortcut solving] -shortCutSolver :: DynFlags - -> CtEvidence -- Work item - -> CtEvidence -- Inert we want to try to replace - -> TcS Bool -- True <=> success -shortCutSolver dflags ev_w ev_i - | isWanted ev_w - , isGiven ev_i +-- | See Note [Shortcut solving] +wantShortCut :: DynFlags + -> CtEvidence -- ^ Work item + -> CtEvidence -- ^ Inert we want to try to replace + -> Bool +wantShortCut dflags ev_w ev_i = + and + [ isWanted ev_w + , isGiven ev_i -- We are about to solve a [W] constraint from a [G] constraint. We take -- a moment to see if we can get a better solution using an instance. -- Note that we only do this for the sake of performance. Exactly the same -- programs should typecheck regardless of whether we take this step or -- not. See Note [Shortcut solving] - , not (isIPLikePred (ctEvPred ev_w)) -- Not for implicit parameters (#18627) - - , not (xopt LangExt.IncoherentInstances dflags) + , not (xopt LangExt.IncoherentInstances dflags) -- If IncoherentInstances is on then we cannot rely on coherence of proofs -- in order to justify this optimization: The proof provided by the -- [G] constraint's superclass may be different from the top-level proof. -- See Note [Shortcut solving: incoherence] - , gopt Opt_SolveConstantDicts dflags + , gopt Opt_SolveConstantDicts dflags -- Enabled by the -fsolve-constant-dicts flag + ] +-- | See Note [Shortcut solving] +shortCutSolver :: DynFlags + -> CtEvidence -- Work item + -> TcS Bool -- True <=> success +shortCutSolver dflags ev_w + | isIPLikePred (ctEvPred ev_w) + -- Not for implicit parameters (#18627) + -- TODO: we should probably also reject QCs, + -- e.g. ( forall a. Eq a => IP "ip" a ) + = return False + | otherwise = do { ev_binds_var <- getTcEvBindsVar ; ev_binds <- assertPpr (not (isCoEvBindsVar ev_binds_var )) (ppr ev_w) $ getTcEvBindsMap ev_binds_var @@ -795,8 +809,6 @@ shortCutSolver dflags ev_w ev_i ; setSolvedDicts solved_dicts' ; return True } } - | otherwise - = return False where -- This `CtLoc` is used only to check the well-staged condition of any -- candidate DFun. Our subgoals all have the same stage as our root @@ -806,46 +818,51 @@ shortCutSolver dflags ev_w ev_i try_solve_from_instance -- See Note [Shortcut try_solve_from_instance] :: (EvBindMap, DictMap DictCt) -> CtEvidence -> MaybeT TcS (EvBindMap, DictMap DictCt) - try_solve_from_instance (ev_binds, solved_dicts) ev - | let pred = ctEvPred ev - , ClassPred cls tys <- classifyPredType pred - = do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w - ; lift $ warn_custom_warn_instance inst_res loc_w - -- See Note [Implementation of deprecated instances] - ; case inst_res of - OneInst { cir_new_theta = preds - , cir_mk_ev = mk_ev - , cir_canonical = canonical - , cir_what = what } - | safeOverlap what - , all isTyFamFree preds -- Note [Shortcut solving: type families] - -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls - , di_tys = tys, di_pend_sc = doNotExpand } - solved_dicts' = addSolvedDict dict_ct solved_dicts - -- solved_dicts': it is important that we add our goal - -- to the cache before we solve! Otherwise we may end - -- up in a loop while solving recursive dictionaries. - - ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) - ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred - ; lift $ checkReductionDepth loc' pred - - - ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds - -- Emit work for subgoals but use our local cache - -- so we can solve recursive dictionaries. - - ; let ev_tm = mk_ev (map getEvExpr evc_vs) - ev_binds' = extendEvBinds ev_binds $ - mkWantedEvBind (ctEvEvId ev) canonical ev_tm - - ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ - freshGoals evc_vs } - - _ -> mzero } + try_solve_from_instance (ev_binds, solved_dicts) ev = + case classifyPredType pred of + ClassPred cls tys -> + do { inst_res <- lift $ matchGlobalInst dflags True cls tys loc_w + ; lift $ warn_custom_warn_instance inst_res loc_w + -- See Note [Implementation of deprecated instances] + ; case inst_res of + OneInst { cir_new_theta = preds + , cir_mk_ev = mk_ev + , cir_canonical = canonical + , cir_what = what } + | safeOverlap what + , all isTyFamFree preds -- Note [Shortcut solving: type families] + -> do { let dict_ct = DictCt { di_ev = ev, di_cls = cls + , di_tys = tys, di_pend_sc = doNotExpand } + solved_dicts' = addSolvedDict dict_ct solved_dicts + -- solved_dicts': it is important that we add our goal + -- to the cache before we solve! Otherwise we may end + -- up in a loop while solving recursive dictionaries. - | otherwise - = mzero + ; lift $ traceTcS "shortCutSolver: found instance" (ppr preds) + ; loc' <- lift $ checkInstanceOK (ctEvLoc ev) what pred + ; lift $ checkReductionDepth loc' pred + + + ; evc_vs <- mapM (new_wanted_cached ev loc' solved_dicts') preds + -- Emit work for subgoals but use our local cache + -- so we can solve recursive dictionaries. + + ; let ev_tm = mk_ev (map getEvExpr evc_vs) + ev_binds' = extendEvBinds ev_binds $ + mkWantedEvBind (ctEvEvId ev) canonical ev_tm + + ; foldlM try_solve_from_instance (ev_binds', solved_dicts') $ + freshGoals evc_vs } + + _other_inst_res -> mzero } + + ForAllPred _tvs _theta _body -> + -- TODO: implement short-cut solving for quantified constraints + mzero + + _other_pred -> mzero + where + pred = ctEvPred ev -- Use a local cache of solved dicts while emitting EvVars for new work @@ -868,13 +885,16 @@ shortCutSolver dflags ev_w ev_i tryInstances :: DictCt -> SolverStage () tryInstances dict_ct - = Stage $ do { inerts <- getInertSet - ; try_instances inerts dict_ct } + = Stage $ do { dflags <- getDynFlags + ; inerts <- getInertSet + ; mode <- getModeTcS + ; try_instances inerts dflags mode dict_ct } -try_instances :: InertSet -> DictCt -> TcS (StopOrContinue ()) +try_instances :: InertSet -> DynFlags -> TcSMode -> DictCt -> TcS (StopOrContinue ()) -- Try to use type-class instance declarations to simplify the constraint -try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls - , di_tys = xis }) +try_instances inerts dflags mode + work_item@(DictCt { di_ev = ev, di_cls = cls + , di_tys = xis }) | isGiven ev -- Never use instances for Given constraints = continueWith () -- See Note [No Given/Given fundeps] @@ -883,17 +903,26 @@ try_instances inerts work_item@(DictCt { di_ev = ev, di_cls = cls = do { setEvBindIfWanted ev EvCanonical (ctEvTerm solved_ev) ; stopWith ev "Dict/Top (cached)" } + | TcSSpecPrag <- mode + -- In TcSSpecPrag mode, we only want to "fully solve" constraints + -- from instances. Making partial progress using instances is + -- actively harmful; see Note [Handling new-form SPECIALISE pragmas]. + = do { shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag DictCt: short-cut fully solved Wanted from instances" + else continueWith () + } + | otherwise -- Wanted, but not cached - = do { dflags <- getDynFlags - ; lkup_res <- matchClassInst dflags inerts cls xis dict_loc - ; case lkup_res of - OneInst { cir_what = what } - -> do { insertSafeOverlapFailureTcS what work_item - ; updSolvedDicts what work_item - ; chooseInstance ev lkup_res } - _ -> -- NoInstance or NotSure - -- We didn't solve it; so try functional dependencies - continueWith () } + = do { lkup_res <- matchClassInst dflags inerts cls xis dict_loc + ; case lkup_res of + OneInst { cir_what = what } + -> do { insertSafeOverlapFailureTcS what work_item + ; updSolvedDicts what work_item + ; chooseInstance ev lkup_res } + _ -> -- NoInstance or NotSure + -- We didn't solve it; so try functional dependencies + continueWith () } where dict_loc = ctEvLoc ev @@ -940,10 +969,12 @@ checkInstanceOK loc what pred | otherwise = loc -matchClassInst :: DynFlags -> InertSet +matchClassInst :: DynFlags + -> InertSet -> Class -> [Type] -> CtLoc -> TcS ClsInstResult matchClassInst dflags inerts clas tys loc + -- First check whether there is an in-scope Given that could -- match this constraint. In that case, do not use any instance -- whether top level, or local quantified constraints. ===================================== compiler/GHC/Tc/Solver/Equality.hs ===================================== @@ -2018,8 +2018,9 @@ finishCanWithIrred :: CtIrredReason -> CtEvidence -> TcS (StopOrContinue (Either IrredCt a)) finishCanWithIrred reason ev = do { -- Abort fast if we have any insoluble Wanted constraints, - -- and the TcS abort-if-insoluble flag is on. - when (isInsolubleReason reason) tryEarlyAbortTcS + -- and the TcSMode is TcsHoleFits + mode <- getModeTcS + ; when (mode == TcSHoleFits && isInsolubleReason reason) failTcS ; continueWith $ Left $ IrredCt { ir_ev = ev, ir_reason = reason } } ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -14,9 +14,10 @@ module GHC.Tc.Solver.Monad ( -- The TcS monad - TcS, runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, - failTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, - runTcSEqualities, + TcS, TcSMode(..), + runTcS, runTcSEarlyAbort, runTcSWithEvBinds, runTcSInerts, + runTcSEqualities, runTcSSpecPragWithEvBinds, + failTcS, failWithTcS, warnTcS, addErrTcS, wrapTcS, ctLocWarnTcS, nestTcS, nestImplicTcS, setEvBindsTcS, emitImplicationTcS, emitTvImplicationTcS, emitFunDepWanteds, @@ -37,7 +38,7 @@ module GHC.Tc.Solver.Monad ( stopWithStage, nopStage, -- Tracing etc - panicTcS, traceTcS, tryEarlyAbortTcS, + panicTcS, traceTcS, getModeTcS, traceFireTcS, bumpStepCountTcS, csTraceTcS, wrapErrTcS, wrapWarnTcS, resetUnificationFlag, setUnificationFlag, @@ -824,6 +825,8 @@ added. This is initialised from the innermost implication constraint. data TcSEnv = TcSEnv { + tcs_mode :: TcSMode, + tcs_ev_binds :: EvBindsVar, tcs_unified :: IORef Int, @@ -841,15 +844,27 @@ data TcSEnv tcs_inerts :: IORef InertSet, -- Current inert set - -- Whether to throw an exception if we come across an insoluble constraint. - -- Used to fail-fast when checking for hole-fits. See Note [Speeding up - -- valid hole-fits]. - tcs_abort_on_insoluble :: Bool, - -- See Note [WorkList priorities] in GHC.Tc.Solver.InertSet tcs_worklist :: IORef WorkList -- Current worklist } +data TcSMode + = TcSVanilla + + | TcSHoleFits -- ^ Throw an exception if we come across an insoluble constraint, + -- to fail-fast when checking for hole-fits. + -- + -- See Note [Speeding up valid hole-fits]. + + | TcSSpecPrag -- ^ Don't use instance declarations or unpack forall constraints; + -- used when simplifying a SPECIALISE pragma. + deriving( Eq ) + +instance Outputable TcSMode where + ppr TcSVanilla = text "TcSVanilla" + ppr TcSHoleFits = text "TcSHoleFits" + ppr TcSSpecPrag = text "TcSSpecPrag" + --------------- newtype TcS a = TcS { unTcS :: TcSEnv -> TcM a } deriving (Functor) @@ -910,17 +925,17 @@ wrapWarnTcS :: TcM a -> TcS a wrapWarnTcS = wrapTcS panicTcS :: SDoc -> TcS a -failTcS :: TcRnMessage -> TcS a +failTcS :: TcS a +failWithTcS :: TcRnMessage -> TcS a warnTcS, addErrTcS :: TcRnMessage -> TcS () -failTcS = wrapTcS . TcM.failWith +failTcS = wrapTcS TcM.failM +failWithTcS = wrapTcS . TcM.failWith warnTcS msg = wrapTcS (TcM.addDiagnostic msg) addErrTcS = wrapTcS . TcM.addErr panicTcS doc = pprPanic "GHC.Tc.Solver.Monad" doc -tryEarlyAbortTcS :: TcS () --- Abort (fail in the monad) if the abort_on_insoluble flag is on -tryEarlyAbortTcS - = mkTcS (\env -> when (tcs_abort_on_insoluble env) TcM.failM) +getModeTcS :: TcS TcSMode +getModeTcS = mkTcS (\env -> return (tcs_mode env)) -- | Emit a warning within the 'TcS' monad at the location given by the 'CtLoc'. ctLocWarnTcS :: CtLoc -> TcRnMessage -> TcS () @@ -976,11 +991,17 @@ csTraceTcM mk_doc msg }) } {-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] -runTcS :: TcS a -- What to run - -> TcM (a, EvBindMap) +runTcSWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSWithEvBinds = runTcSWorker True TcSVanilla + +-- | This version of 'runTcSWithEvBinds' uses the 'TcSSpecPrag' mode. +runTcSSpecPragWithEvBinds :: EvBindsVar -> TcS a -> TcM a +runTcSSpecPragWithEvBinds = runTcSWorker True TcSSpecPrag + +runTcS :: TcS a -> TcM (a, EvBindMap) runTcS tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; res <- runTcSWithEvBinds ev_binds_var tcs + ; res <- runTcSWorker True TcSVanilla ev_binds_var tcs ; ev_binds <- TcM.getTcEvBindsMap ev_binds_var ; return (res, ev_binds) } @@ -990,51 +1011,47 @@ runTcS tcs runTcSEarlyAbort :: TcS a -> TcM a runTcSEarlyAbort tcs = do { ev_binds_var <- TcM.newTcEvBinds - ; runTcSWithEvBinds' True True ev_binds_var tcs } + ; runTcSWorker True TcSHoleFits ev_binds_var tcs } -- | This can deal only with equality constraints. runTcSEqualities :: TcS a -> TcM a runTcSEqualities thing_inside - = do { ev_binds_var <- TcM.newNoTcEvBinds - ; runTcSWithEvBinds ev_binds_var thing_inside } + = do { ev_binds_var <- TcM.newNoTcEvBinds -- No bindings + ; runTcSWorker True TcSVanilla ev_binds_var thing_inside } -- | A variant of 'runTcS' that takes and returns an 'InertSet' for -- later resumption of the 'TcS' session. runTcSInerts :: InertSet -> TcS a -> TcM (a, InertSet) -runTcSInerts inerts tcs = do - ev_binds_var <- TcM.newTcEvBinds - runTcSWithEvBinds' False False ev_binds_var $ do - setInertSet inerts - a <- tcs - new_inerts <- getInertSet - return (a, new_inerts) - -runTcSWithEvBinds :: EvBindsVar - -> TcS a - -> TcM a -runTcSWithEvBinds = runTcSWithEvBinds' True False - -runTcSWithEvBinds' :: Bool -- ^ Restore type variable cycles afterwards? - -- Don't if you want to reuse the InertSet. - -- See also Note [Type equality cycles] - -- in GHC.Tc.Solver.Equality - -> Bool - -> EvBindsVar - -> TcS a - -> TcM a -runTcSWithEvBinds' restore_cycles abort_on_insoluble ev_binds_var tcs +runTcSInerts inerts tcs + = do { ev_binds_var <- TcM.newTcEvBinds + ; runTcSWorker False TcSVanilla ev_binds_var $ + do { setInertSet inerts + ; a <- tcs + ; new_inerts <- getInertSet + ; return (a, new_inerts) } } + +-- runTcSWorker is not exported +runTcSWorker :: Bool -- ^ Restore type variable cycles afterwards? + -- Don't if you want to reuse the InertSet. + -- See also Note [Type equality cycles] + -- in GHC.Tc.Solver.Equality + -> TcSMode + -> EvBindsVar + -> TcS a + -> TcM a +runTcSWorker restore_cycles mode ev_binds_var tcs = do { unified_var <- TcM.newTcRef 0 ; step_count <- TcM.newTcRef 0 ; inert_var <- TcM.newTcRef emptyInert ; wl_var <- TcM.newTcRef emptyWorkList ; unif_lvl_var <- TcM.newTcRef Nothing - ; let env = TcSEnv { tcs_ev_binds = ev_binds_var - , tcs_unified = unified_var - , tcs_unif_lvl = unif_lvl_var - , tcs_count = step_count - , tcs_inerts = inert_var - , tcs_abort_on_insoluble = abort_on_insoluble - , tcs_worklist = wl_var } + ; let env = TcSEnv { tcs_mode = mode + , tcs_ev_binds = ev_binds_var + , tcs_unified = unified_var + , tcs_unif_lvl = unif_lvl_var + , tcs_count = step_count + , tcs_inerts = inert_var + , tcs_worklist = wl_var } -- Run the computation ; res <- unTcS tcs env @@ -1091,12 +1108,7 @@ nestImplicTcS :: EvBindsVar -> TcLevel -> TcS a -> TcS a nestImplicTcS ref inner_tclvl (TcS thing_inside) - = TcS $ \ TcSEnv { tcs_unified = unified_var - , tcs_inerts = old_inert_var - , tcs_count = count - , tcs_unif_lvl = unif_lvl - , tcs_abort_on_insoluble = abort_on_insoluble - } -> + = TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var }) -> do { inerts <- TcM.readTcRef old_inert_var ; let nest_inert = inerts { inert_cycle_breakers = pushCycleBreakerVarStack (inert_cycle_breakers inerts) @@ -1105,13 +1117,9 @@ nestImplicTcS ref inner_tclvl (TcS thing_inside) -- All other InertSet fields are inherited ; new_inert_var <- TcM.newTcRef nest_inert ; new_wl_var <- TcM.newTcRef emptyWorkList - ; let nest_env = TcSEnv { tcs_count = count -- Inherited - , tcs_unif_lvl = unif_lvl -- Inherited - , tcs_ev_binds = ref - , tcs_unified = unified_var - , tcs_inerts = new_inert_var - , tcs_abort_on_insoluble = abort_on_insoluble - , tcs_worklist = new_wl_var } + ; let nest_env = env { tcs_ev_binds = ref + , tcs_inerts = new_inert_var + , tcs_worklist = new_wl_var } ; res <- TcM.setTcLevel inner_tclvl $ thing_inside nest_env ===================================== compiler/GHC/Tc/Solver/Solve.hs ===================================== @@ -923,7 +923,7 @@ solveSimpleWanteds simples -- See Note [The solveSimpleWanteds loop] go n limit wc | n `intGtLimit` limit - = failTcS $ TcRnSimplifierTooManyIterations simples limit wc + = failWithTcS $ TcRnSimplifierTooManyIterations simples limit wc | isEmptyBag (wc_simple wc) = return (n,wc) @@ -1053,7 +1053,7 @@ solveCt (CNonCanonical ev) = solveNC ev solveCt (CIrredCan (IrredCt { ir_ev = ev })) = solveNC ev solveCt (CEqCan (EqCt { eq_ev = ev, eq_eq_rel = eq_rel - , eq_lhs = lhs, eq_rhs = rhs })) + , eq_lhs = lhs, eq_rhs = rhs })) = solveEquality ev eq_rel (canEqLHSType lhs) rhs solveCt (CQuantCan (QCI { qci_ev = ev, qci_pend_sc = pend_sc })) @@ -1211,8 +1211,29 @@ solveForAllNC ev tvs theta pred solveForAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType -> ExpansionFuel -> TcS (StopOrContinue Void) -- Precondition: already rewritten by inert set -solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) - tvs theta pred _fuel +solveForAll ev tvs theta pred fuel + = do { mode <- getModeTcS + ; solve_forAll ev tvs theta pred fuel mode + } + +solve_forAll :: CtEvidence -> [TcTyVar] -> TcThetaType -> PredType + -> ExpansionFuel -> TcSMode + -> TcS (StopOrContinue Void) +solve_forAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_loc = loc }) + tvs theta pred _fuel _mode +{- SLD TODO + | TcSSpecPrag <- mode + = do { dflags <- getDynFlags + ; shortcut_worked <- shortCutSolver dflags ev + ; if shortcut_worked + then stopWith ev "TcSSpecPrag QC: short-cut fully solved Wanted from instances" + else do { let qci = QCI { qci_ev = ev, qci_tvs = tvs + , qci_pred = pred, qci_pend_sc = fuel } + ; addInertForAll qci + ; stopWith ev "TcSSpecPrag QC: Wanted kept as inert" } + } + | otherwise +-} = -- See Note [Solving a Wanted forall-constraint] TcS.setSrcSpan (getCtLocEnvLoc $ ctLocEnv loc) $ -- This setSrcSpan is important: the emitImplicationTcS uses that @@ -1259,7 +1280,7 @@ solveForAll ev@(CtWanted { ctev_dest = dest, ctev_rewriters = rewriters, ctev_lo _ -> pSizeType pred -- See Note [Solving a Given forall-constraint] -solveForAll ev@(CtGiven {}) tvs _theta pred fuel +solve_forAll ev@(CtGiven {}) tvs _theta pred fuel _mode = do { addInertForAll qci ; stopWith ev "Given forall-constraint" } where ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -373,10 +373,15 @@ data EvBindsVar } instance Data.Data TcEvBinds where - -- Placeholder; we can't travers into TcEvBinds + -- Placeholder; we can't traverse into TcEvBinds toConstr _ = abstractConstr "TcEvBinds" gunfold _ _ = error "gunfold" dataTypeOf _ = Data.mkNoRepType "TcEvBinds" +instance Data.Data EvBind where + -- Placeholder; we can't traverse into EvBind + toConstr _ = abstractConstr "TcEvBind" + gunfold _ _ = error "gunfold" + dataTypeOf _ = Data.mkNoRepType "EvBind" {- Note [Coercion evidence only] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Zonk/Type.hs ===================================== @@ -862,12 +862,14 @@ zonkLTcSpecPrags ps ; skol_tvs_ref <- lift $ newTcRef [] ; setZonkType (SkolemiseFlexi skol_tvs_ref) $ -- SkolemiseFlexi: see Note [Free tyvars on rule LHS] - runZonkBndrT (zonkCoreBndrsX bndrs) $ \bndrs' -> + runZonkBndrT (zonkCoreBndrsX bndrs) $ \ bndrs' -> do { spec_e' <- zonkLExpr spec_e ; skol_tvs <- lift $ readTcRef skol_tvs_ref - ; return (L loc (prag { spe_fn_id = poly_id' - , spe_bndrs = skol_tvs ++ bndrs' - , spe_call = spec_e' })) } } + ; return (L loc (prag { spe_fn_id = poly_id' + , spe_bndrs = skol_tvs ++ bndrs' + , spe_call = spec_e' + })) + }} {- ************************************************************************ ===================================== testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs ===================================== @@ -0,0 +1,83 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE QuantifiedConstraints #-} + +module DsSpecPragmas where + +import Control.Monad.ST ( ST ) + +-- Some specialise pragmas that are difficult to generate the correct RULE for. + +-------------------------------------------------------------------------------- + +f1 :: ( Num a, Eq b ) => a -> b -> Int +f1 _ _ = 111 + +-- Make sure we don't generate a rule with an LHS of the form +-- +-- forall @e (d :: Eq e). f @[e] ($fEqList d) = ... +-- +-- but rather +-- +-- forall @e (d :: Eq [e]). f @[e] d = ... +{-# SPECIALISE f1 :: Eq [e] => Word -> [e] -> Int #-} + +-------------------------------------------------------------------------------- + +f2 :: ( Eq a, Eq b ) => a -> b -> Int +f2 a b = if ( a == a ) == ( b == b ) then 1 else 2 + +-- Make sure the rule LHS is of the form +-- +-- f2 @c @c d1 d2 and not f2 @c @c d d +{-# SPECIALISE f2 :: Eq c => c -> c -> Int #-} + +-------------------------------------------------------------------------------- + +f3 :: ( Eq a, forall x. Eq x => Eq ( f x ) ) => f a -> Bool +f3 z = z == z + +-- Discharge the quantified constraint but keep the 'Eq' constraint +{-# SPECIALISE f3 :: Eq c => [ c ] -> Bool #-} + +-- Discharge the 'Eq' constraint but keep the quantified constraint +{-# SPECIALISE f3 :: ( forall y. Eq y => Eq ( g y ) ) => g Int -> Bool #-} + +-------------------------------------------------------------------------------- + +f4 :: Monad m => a -> m a +f4 = return + +-- Check we can deal with locally quantified variables in constraints, +-- in this case 'Monad (ST s)'. +{-# SPECIALISE f4 :: b -> ST s b #-} + +-------------------------------------------------------------------------------- + +type family T a where + T Int = Word +data D a = D a (T a) +deriving stock instance (Eq a, Eq (T a)) => Eq (D a) + +f5 :: Eq a => a -> Bool +f5 x = x == x + +-- Discharge a dictionary constraint using a top-level instance +-- whose context contains a type family application. +{-# SPECIALISE f5 :: D Int -> Bool #-} + + +f6 :: ( Eq a, Eq ( T a ), forall x. ( Eq x, Eq ( T x ) ) => Eq ( f x ) ) => f a -> Bool +f6 z = z == z + +-- Discharge a quantified constraint using a top-level instance +-- whose context includes a type family application. +{-# SPECIALISE f6 :: D Int -> Bool #-} + +-- Quantify over this same quantified constraint, but discharge the +-- other dictionary constraints. +{-# SPECIALISE f6 :: ( forall x. ( Eq x, Eq ( T x ) ) => Eq ( f x ) ) => f Int -> Bool #-} + +-------------------------------------------------------------------------------- ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -502,6 +502,7 @@ test('T23491d', [extra_files(['T23491.hs']), grep_errmsg(r'Static argument')], m test('T23074', normal, compile, ['-O -ddump-rules']) test('T23272', [only_ways(['ghci']), extra_hc_opts('-fno-unoptimized-core-for-interpreter -O')], ghci_script, ['T23272.script']) test('T23567', [extra_files(['T23567A.hs'])], multimod_compile, ['T23567', '-O -v0']) +test('DsSpecPragmas', normal, compile, ['-O -ddump-rules']) # The -ddump-simpl of T22404 should have no let-bindings test('T22404', [only_ways(['optasm']), check_errmsg(r'let') ], compile, ['-ddump-simpl -dsuppress-uniques']) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -738,6 +738,7 @@ test('ExplicitSpecificityA1', normal, compile, ['']) test('ExplicitSpecificityA2', normal, compile, ['']) test('ExplicitSpecificity4', normal, compile, ['']) test('RuleEqs', normal, compile, ['']) +test('SpecPragmas', normal, compile, ['']) test('T17775-viewpats-a', normal, compile, ['']) test('T17775-viewpats-b', normal, compile_fail, ['']) test('T17775-viewpats-c', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0481938d0b1afc3f514c58a8335d1344537e60a7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0481938d0b1afc3f514c58a8335d1344537e60a7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 11:34:13 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 29 Jan 2025 06:34:13 -0500 Subject: [Git][ghc/ghc][wip/optim-faststring] compiler: Always load GHC.Data.FastString optimised into GHCi Message-ID: <679a1235cea19_221746c0850792f1@gitlab.mail> Matthew Pickering pushed to branch wip/optim-faststring at Glasgow Haskell Compiler / GHC Commits: 5ca004bd by Matthew Pickering at 2025-01-29T11:33:58+00:00 compiler: Always load GHC.Data.FastString optimised into GHCi The FastString table is shared between the boot compiler and interpreted compiler. Therefore it's very important the representation of `FastString` matches in both cases. Otherwise, the interpreter will read a FastString from the shared variable but place the fields in the wrong place which leads to segfaults. Ideally this state would not be shared, but for now we can always compile both with `-O2` and this leads to a working interpreter. - - - - - 1 changed file: - compiler/GHC/Data/FastString.hs Changes: ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -2,10 +2,19 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE CPP #-} {-# OPTIONS_GHC -O2 -funbox-strict-fields #-} +#if MIN_VERSION_GLASGOW_HASKELL(9,8,0,0) +{-# OPTIONS_GHC -fno-unoptimized-core-for-interpreter #-} +#endif -- We always optimise this, otherwise performance of a non-optimised -- compiler is severely affected +-- +-- Also important, if you load this module into GHCi then the data representation of +-- FastString has to match that of the host compiler due to the shared FastString +-- table. Otherwise you will get segfaults when the table is consulted and the fields +-- from the FastString are in an incorrect order. -- | -- There are two principal string types used internally by GHC: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ca004bd9dc2e80dae3ca559f286f97c8619bc98 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ca004bd9dc2e80dae3ca559f286f97c8619bc98 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 11:34:30 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 29 Jan 2025 06:34:30 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/bco_name_improve Message-ID: <679a124631950_221746113f5079499@gitlab.mail> Matthew Pickering pushed new branch wip/bco_name_improve at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bco_name_improve You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 11:34:44 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 29 Jan 2025 06:34:44 -0500 Subject: [Git][ghc/ghc][wip/bco_name_improve] interpreter: Always print unit and module name in BCO_NAME instruction Message-ID: <679a1254af4fd_221746c087879680@gitlab.mail> Matthew Pickering pushed to branch wip/bco_name_improve at Glasgow Haskell Compiler / GHC Commits: d257bf3a by Matthew Pickering at 2025-01-29T11:34:35+00:00 interpreter: Always print unit and module name in BCO_NAME instruction Currently the BCO_Name instruction is a bit difficult to use since the names are not qualified by the module they come from. When you have a very generic name such as "wildX4", it becomes impossible to work out which module the identifier comes from. Fixes #25694 - - - - - 1 changed file: - compiler/GHC/StgToByteCode.hs Changes: ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -240,11 +240,12 @@ ppBCEnv p -- Create a BCO and do a spot of peephole optimisation on the insns -- at the same time. mkProtoBCO - :: (Outputable name) - => Platform - -> Bool -- ^ True <=> label with @BCO_NAME@ instruction - -- see Note [BCO_NAME] - -> name + :: + Platform + -> Maybe Module + -- ^ Just cur_mod <=> label with @BCO_NAME@ instruction + -- see Note [BCO_NAME] + -> Name -> BCInstrList -> Either [CgStgAlt] (CgStgRhs) -- ^ original expression; for debugging only @@ -253,7 +254,7 @@ mkProtoBCO -> [StgWord] -- ^ bitmap -> Bool -- ^ True <=> is a return point, rather than a function -> [FFIInfo] - -> ProtoBCO name + -> ProtoBCO Name mkProtoBCO platform _add_bco_name nm instrs_ordlist origin arity bitmap_size bitmap is_ret ffis = ProtoBCO { protoBCOName = nm, @@ -267,9 +268,9 @@ mkProtoBCO platform _add_bco_name nm instrs_ordlist origin arity bitmap_size bit where #if MIN_VERSION_rts(1,0,3) maybe_add_bco_name instrs - | _add_bco_name = BCO_NAME str : instrs - where - str = BS.pack $ showSDocOneLine defaultSDocContext (ppr nm) + | Just cur_mod <- _add_bco_name = + let str = BS.pack $ showSDocOneLine defaultSDocContext (pprFullName cur_mod nm) + in BCO_NAME str : instrs #endif maybe_add_bco_name instrs = instrs @@ -1398,7 +1399,7 @@ Note [unboxed tuple bytecodes and tuple_BCO] tupleBCO :: Platform -> NativeCallInfo -> [(PrimRep, ByteOff)] -> [FFIInfo] -> ProtoBCO Name tupleBCO platform args_info args = - mkProtoBCO platform False invented_name body_code (Left []) + mkProtoBCO platform Nothing invented_name body_code (Left []) 0{-no arity-} bitmap_size bitmap False{-is alts-} where {- @@ -1419,7 +1420,7 @@ tupleBCO platform args_info args = primCallBCO :: Platform -> NativeCallInfo -> [(PrimRep, ByteOff)] -> [FFIInfo] -> ProtoBCO Name primCallBCO platform args_info args = - mkProtoBCO platform False invented_name body_code (Left []) + mkProtoBCO platform Nothing invented_name body_code (Left []) 0{-no arity-} bitmap_size bitmap False{-is alts-} where {- @@ -2359,8 +2360,12 @@ getHscEnv = BcM $ \st -> return (st, bcm_hsc_env st) getProfile :: BcM Profile getProfile = targetProfile <$> getDynFlags -shouldAddBcoName :: BcM Bool -shouldAddBcoName = gopt Opt_AddBcoName <$> getDynFlags +shouldAddBcoName :: BcM (Maybe Module) +shouldAddBcoName = do + add <- gopt Opt_AddBcoName <$> getDynFlags + if add + then Just <$> getCurrentModule + else return Nothing emitBc :: ([FFIInfo] -> ProtoBCO Name) -> BcM (ProtoBCO Name) emitBc bco View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d257bf3ae97f26dcfe614e01d1f8b3c1516029a0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d257bf3ae97f26dcfe614e01d1f8b3c1516029a0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 12:15:21 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 29 Jan 2025 07:15:21 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/fix-interp-stats Message-ID: <679a1bd9c62e5_22174685b0d890611@gitlab.mail> Matthew Pickering pushed new branch wip/fix-interp-stats at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fix-interp-stats You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 13:56:39 2025 From: gitlab at gitlab.haskell.org (Andreas Klebinger (@AndreasK)) Date: Wed, 29 Jan 2025 08:56:39 -0500 Subject: [Git][ghc/ghc][wip/andreask/9.10-backports] Update ghc-experimental-exports. Message-ID: <679a3397d93bc_2537643e5bfc62134@gitlab.mail> Andreas Klebinger pushed to branch wip/andreask/9.10-backports at Glasgow Haskell Compiler / GHC Commits: 07f72b53 by Andreas Klebinger at 2025-01-29T14:32:39+01:00 Update ghc-experimental-exports. We moved primops into ghc-experimental in a patch we backported. However some of the definitions moved don't exist on the 9.10 branch so we have to update the exports. - - - - - 1 changed file: - testsuite/tests/interface-stability/ghc-experimental-exports.stdout Changes: ===================================== testsuite/tests/interface-stability/ghc-experimental-exports.stdout ===================================== @@ -4803,37 +4803,13 @@ module GHC.PrimOps where float2Double# :: Float# -> Double# float2Int# :: Float# -> Int# fmaddDouble# :: Double# -> Double# -> Double# -> Double# - fmaddDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# -> DoubleX2# - fmaddDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# -> DoubleX4# - fmaddDoubleX8# :: DoubleX8# -> DoubleX8# -> DoubleX8# -> DoubleX8# fmaddFloat# :: Float# -> Float# -> Float# -> Float# - fmaddFloatX16# :: FloatX16# -> FloatX16# -> FloatX16# -> FloatX16# - fmaddFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# -> FloatX4# - fmaddFloatX8# :: FloatX8# -> FloatX8# -> FloatX8# -> FloatX8# fmsubDouble# :: Double# -> Double# -> Double# -> Double# - fmsubDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# -> DoubleX2# - fmsubDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# -> DoubleX4# - fmsubDoubleX8# :: DoubleX8# -> DoubleX8# -> DoubleX8# -> DoubleX8# fmsubFloat# :: Float# -> Float# -> Float# -> Float# - fmsubFloatX16# :: FloatX16# -> FloatX16# -> FloatX16# -> FloatX16# - fmsubFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# -> FloatX4# - fmsubFloatX8# :: FloatX8# -> FloatX8# -> FloatX8# -> FloatX8# fnmaddDouble# :: Double# -> Double# -> Double# -> Double# - fnmaddDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# -> DoubleX2# - fnmaddDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# -> DoubleX4# - fnmaddDoubleX8# :: DoubleX8# -> DoubleX8# -> DoubleX8# -> DoubleX8# fnmaddFloat# :: Float# -> Float# -> Float# -> Float# - fnmaddFloatX16# :: FloatX16# -> FloatX16# -> FloatX16# -> FloatX16# - fnmaddFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# -> FloatX4# - fnmaddFloatX8# :: FloatX8# -> FloatX8# -> FloatX8# -> FloatX8# fnmsubDouble# :: Double# -> Double# -> Double# -> Double# - fnmsubDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# -> DoubleX2# - fnmsubDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# -> DoubleX4# - fnmsubDoubleX8# :: DoubleX8# -> DoubleX8# -> DoubleX8# -> DoubleX8# fnmsubFloat# :: Float# -> Float# -> Float# -> Float# - fnmsubFloatX16# :: FloatX16# -> FloatX16# -> FloatX16# -> FloatX16# - fnmsubFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# -> FloatX4# - fnmsubFloatX8# :: FloatX8# -> FloatX8# -> FloatX8# -> FloatX8# fork# :: forall {q :: RuntimeRep} (a :: TYPE q). (State# RealWorld -> (# State# RealWorld, a #)) -> State# RealWorld -> (# State# RealWorld, ThreadId# #) forkOn# :: forall {q :: RuntimeRep} (a :: TYPE q). Int# -> (State# RealWorld -> (# State# RealWorld, a #)) -> State# RealWorld -> (# State# RealWorld, ThreadId# #) freezeArray# :: forall {l :: Levity} d (a :: TYPE (BoxedRep l)). MutableArray# d a -> Int# -> Int# -> State# d -> (# State# d, Array# a #) @@ -5106,11 +5082,9 @@ module GHC.PrimOps where intToInt64# :: Int# -> Int64# intToInt8# :: Int# -> Int8# isByteArrayPinned# :: ByteArray# -> Int# - isByteArrayWeaklyPinned# :: ByteArray# -> Int# isCurrentThreadBound# :: State# RealWorld -> (# State# RealWorld, Int# #) isEmptyMVar# :: forall {l :: Levity} d (a :: TYPE (BoxedRep l)). MVar# d a -> State# d -> (# State# d, Int# #) isMutableByteArrayPinned# :: forall d. MutableByteArray# d -> Int# - isMutableByteArrayWeaklyPinned# :: forall d. MutableByteArray# d -> Int# isTrue# :: Int# -> Bool keepAlive# :: forall {l :: Levity} {r :: RuntimeRep} (a :: TYPE (BoxedRep l)) d (b :: TYPE r). a -> State# d -> (State# d -> b) -> b killThread# :: forall a. ThreadId# -> a -> State# RealWorld -> State# RealWorld @@ -5150,71 +5124,7 @@ module GHC.PrimOps where makeStablePtr# :: forall {l :: Levity} (a :: TYPE (BoxedRep l)). a -> State# RealWorld -> (# State# RealWorld, StablePtr# a #) maskAsyncExceptions# :: forall {q :: RuntimeRep} (a :: TYPE q). (State# RealWorld -> (# State# RealWorld, a #)) -> State# RealWorld -> (# State# RealWorld, a #) maskUninterruptible# :: forall {q :: RuntimeRep} (a :: TYPE q). (State# RealWorld -> (# State# RealWorld, a #)) -> State# RealWorld -> (# State# RealWorld, a #) - maxDouble# :: Double# -> Double# -> Double# - maxDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# - maxDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# - maxDoubleX8# :: DoubleX8# -> DoubleX8# -> DoubleX8# - maxFloat# :: Float# -> Float# -> Float# - maxFloatX16# :: FloatX16# -> FloatX16# -> FloatX16# - maxFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# - maxFloatX8# :: FloatX8# -> FloatX8# -> FloatX8# - maxInt16X16# :: Int16X16# -> Int16X16# -> Int16X16# - maxInt16X32# :: Int16X32# -> Int16X32# -> Int16X32# - maxInt16X8# :: Int16X8# -> Int16X8# -> Int16X8# - maxInt32X16# :: Int32X16# -> Int32X16# -> Int32X16# - maxInt32X4# :: Int32X4# -> Int32X4# -> Int32X4# - maxInt32X8# :: Int32X8# -> Int32X8# -> Int32X8# - maxInt64X2# :: Int64X2# -> Int64X2# -> Int64X2# - maxInt64X4# :: Int64X4# -> Int64X4# -> Int64X4# - maxInt64X8# :: Int64X8# -> Int64X8# -> Int64X8# - maxInt8X16# :: Int8X16# -> Int8X16# -> Int8X16# - maxInt8X32# :: Int8X32# -> Int8X32# -> Int8X32# - maxInt8X64# :: Int8X64# -> Int8X64# -> Int8X64# maxTupleSize :: Int - maxWord16X16# :: Word16X16# -> Word16X16# -> Word16X16# - maxWord16X32# :: Word16X32# -> Word16X32# -> Word16X32# - maxWord16X8# :: Word16X8# -> Word16X8# -> Word16X8# - maxWord32X16# :: Word32X16# -> Word32X16# -> Word32X16# - maxWord32X4# :: Word32X4# -> Word32X4# -> Word32X4# - maxWord32X8# :: Word32X8# -> Word32X8# -> Word32X8# - maxWord64X2# :: Word64X2# -> Word64X2# -> Word64X2# - maxWord64X4# :: Word64X4# -> Word64X4# -> Word64X4# - maxWord64X8# :: Word64X8# -> Word64X8# -> Word64X8# - maxWord8X16# :: Word8X16# -> Word8X16# -> Word8X16# - maxWord8X32# :: Word8X32# -> Word8X32# -> Word8X32# - maxWord8X64# :: Word8X64# -> Word8X64# -> Word8X64# - minDouble# :: Double# -> Double# -> Double# - minDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# - minDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# - minDoubleX8# :: DoubleX8# -> DoubleX8# -> DoubleX8# - minFloat# :: Float# -> Float# -> Float# - minFloatX16# :: FloatX16# -> FloatX16# -> FloatX16# - minFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# - minFloatX8# :: FloatX8# -> FloatX8# -> FloatX8# - minInt16X16# :: Int16X16# -> Int16X16# -> Int16X16# - minInt16X32# :: Int16X32# -> Int16X32# -> Int16X32# - minInt16X8# :: Int16X8# -> Int16X8# -> Int16X8# - minInt32X16# :: Int32X16# -> Int32X16# -> Int32X16# - minInt32X4# :: Int32X4# -> Int32X4# -> Int32X4# - minInt32X8# :: Int32X8# -> Int32X8# -> Int32X8# - minInt64X2# :: Int64X2# -> Int64X2# -> Int64X2# - minInt64X4# :: Int64X4# -> Int64X4# -> Int64X4# - minInt64X8# :: Int64X8# -> Int64X8# -> Int64X8# - minInt8X16# :: Int8X16# -> Int8X16# -> Int8X16# - minInt8X32# :: Int8X32# -> Int8X32# -> Int8X32# - minInt8X64# :: Int8X64# -> Int8X64# -> Int8X64# - minWord16X16# :: Word16X16# -> Word16X16# -> Word16X16# - minWord16X32# :: Word16X32# -> Word16X32# -> Word16X32# - minWord16X8# :: Word16X8# -> Word16X8# -> Word16X8# - minWord32X16# :: Word32X16# -> Word32X16# -> Word32X16# - minWord32X4# :: Word32X4# -> Word32X4# -> Word32X4# - minWord32X8# :: Word32X8# -> Word32X8# -> Word32X8# - minWord64X2# :: Word64X2# -> Word64X2# -> Word64X2# - minWord64X4# :: Word64X4# -> Word64X4# -> Word64X4# - minWord64X8# :: Word64X8# -> Word64X8# -> Word64X8# - minWord8X16# :: Word8X16# -> Word8X16# -> Word8X16# - minWord8X32# :: Word8X32# -> Word8X32# -> Word8X32# - minWord8X64# :: Word8X64# -> Word8X64# -> Word8X64# minusAddr# :: Addr# -> Addr# -> Int# minusDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# minusDoubleX4# :: DoubleX4# -> DoubleX4# -> DoubleX4# @@ -5731,7 +5641,7 @@ module GHC.PrimOps where sameSmallMutableArray# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). SmallMutableArray# s a -> SmallMutableArray# s a -> Int# sameTVar# :: forall {l :: Levity} s (a :: TYPE (BoxedRep l)). TVar# s a -> TVar# s a -> Int# seq :: forall {r :: RuntimeRep} a (b :: TYPE r). a -> b -> b - seq# :: forall a s. a -> State# s -> (# State# s, a #) + seq# :: forall a d. a -> State# d -> (# State# d, a #) setAddrRange# :: Addr# -> Int# -> Int# -> State# RealWorld -> State# RealWorld setByteArray# :: forall d. MutableByteArray# d -> Int# -> Int# -> Int# -> State# d -> State# d setThreadAllocationCounter# :: Int64# -> State# RealWorld -> State# RealWorld @@ -5739,36 +5649,6 @@ module GHC.PrimOps where shiftRL# :: Word# -> Int# -> Word# shrinkMutableByteArray# :: forall d. MutableByteArray# d -> Int# -> State# d -> State# d shrinkSmallMutableArray# :: forall {l :: Levity} d (a :: TYPE (BoxedRep l)). SmallMutableArray# d a -> Int# -> State# d -> State# d - shuffleDoubleX2# :: DoubleX2# -> DoubleX2# -> (# Int#, Int# #) -> DoubleX2# - shuffleDoubleX4# :: DoubleX4# -> DoubleX4# -> (# Int#, Int#, Int#, Int# #) -> DoubleX4# - shuffleDoubleX8# :: DoubleX8# -> DoubleX8# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> DoubleX8# - shuffleFloatX16# :: FloatX16# -> FloatX16# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> FloatX16# - shuffleFloatX4# :: FloatX4# -> FloatX4# -> (# Int#, Int#, Int#, Int# #) -> FloatX4# - shuffleFloatX8# :: FloatX8# -> FloatX8# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> FloatX8# - shuffleInt16X16# :: Int16X16# -> Int16X16# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int16X16# - shuffleInt16X32# :: Int16X32# -> Int16X32# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int16X32# - shuffleInt16X8# :: Int16X8# -> Int16X8# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int16X8# - shuffleInt32X16# :: Int32X16# -> Int32X16# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int32X16# - shuffleInt32X4# :: Int32X4# -> Int32X4# -> (# Int#, Int#, Int#, Int# #) -> Int32X4# - shuffleInt32X8# :: Int32X8# -> Int32X8# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int32X8# - shuffleInt64X2# :: Int64X2# -> Int64X2# -> (# Int#, Int# #) -> Int64X2# - shuffleInt64X4# :: Int64X4# -> Int64X4# -> (# Int#, Int#, Int#, Int# #) -> Int64X4# - shuffleInt64X8# :: Int64X8# -> Int64X8# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int64X8# - shuffleInt8X16# :: Int8X16# -> Int8X16# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int8X16# - shuffleInt8X32# :: Int8X32# -> Int8X32# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int8X32# - shuffleInt8X64# :: Int8X64# -> Int8X64# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Int8X64# - shuffleWord16X16# :: Word16X16# -> Word16X16# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word16X16# - shuffleWord16X32# :: Word16X32# -> Word16X32# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word16X32# - shuffleWord16X8# :: Word16X8# -> Word16X8# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word16X8# - shuffleWord32X16# :: Word32X16# -> Word32X16# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word32X16# - shuffleWord32X4# :: Word32X4# -> Word32X4# -> (# Int#, Int#, Int#, Int# #) -> Word32X4# - shuffleWord32X8# :: Word32X8# -> Word32X8# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word32X8# - shuffleWord64X2# :: Word64X2# -> Word64X2# -> (# Int#, Int# #) -> Word64X2# - shuffleWord64X4# :: Word64X4# -> Word64X4# -> (# Int#, Int#, Int#, Int# #) -> Word64X4# - shuffleWord64X8# :: Word64X8# -> Word64X8# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word64X8# - shuffleWord8X16# :: Word8X16# -> Word8X16# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word8X16# - shuffleWord8X32# :: Word8X32# -> Word8X32# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word8X32# - shuffleWord8X64# :: Word8X64# -> Word8X64# -> (# Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int#, Int# #) -> Word8X64# sinDouble# :: Double# -> Double# sinFloat# :: Float# -> Float# sinhDouble# :: Double# -> Double# @@ -10558,7 +10438,6 @@ instance forall a. GHC.Internal.Real.RealFrac a => GHC.Internal.Real.RealFrac (G instance forall a. GHC.Internal.Show.Show a => GHC.Internal.Show.Show (GHC.Internal.Data.Ord.Down a) -- Defined in ‘GHC.Internal.Data.Ord’ instance forall a. GHC.Internal.Show.Show (GHC.Internal.Ptr.FunPtr a) -- Defined in ‘GHC.Internal.Ptr’ instance forall a. GHC.Internal.Show.Show (GHC.Internal.Ptr.Ptr a) -- Defined in ‘GHC.Internal.Ptr’ -instance GHC.Internal.Show.Show GHC.Internal.IO.MaskingState -- Defined in ‘GHC.Internal.IO’ instance GHC.Classes.Eq GHC.Types.Bool -- Defined in ‘GHC.Classes’ instance GHC.Classes.Eq GHC.Types.Char -- Defined in ‘GHC.Classes’ instance GHC.Classes.Eq GHC.Types.Double -- Defined in ‘GHC.Classes’ @@ -10592,7 +10471,6 @@ instance forall a. GHC.Classes.Eq (GHC.Internal.Ptr.FunPtr a) -- Defined in ‘G instance forall a. GHC.Classes.Eq (GHC.Internal.Ptr.Ptr a) -- Defined in ‘GHC.Internal.Ptr’ instance forall a. GHC.Classes.Eq a => GHC.Classes.Eq (GHC.Internal.Base.NonEmpty a) -- Defined in ‘GHC.Internal.Base’ instance GHC.Classes.Eq GHC.Internal.Base.Void -- Defined in ‘GHC.Internal.Base’ -instance GHC.Classes.Eq GHC.Internal.IO.MaskingState -- Defined in ‘GHC.Internal.IO’ instance GHC.Classes.Ord GHC.Types.Bool -- Defined in ‘GHC.Classes’ instance GHC.Classes.Ord GHC.Types.Char -- Defined in ‘GHC.Classes’ instance GHC.Classes.Ord GHC.Types.Double -- Defined in ‘GHC.Classes’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/07f72b53c15d773c11e3be76cadde4188e402e76 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/07f72b53c15d773c11e3be76cadde4188e402e76 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 17:46:15 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 29 Jan 2025 12:46:15 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/ghci-force-background Message-ID: <679a696764bf0_294be8f66bc027310@gitlab.mail> Matthew Pickering pushed new branch wip/ghci-force-background at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghci-force-background You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 17:46:44 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Wed, 29 Jan 2025 12:46:44 -0500 Subject: [Git][ghc/ghc][wip/ghci-force-background] ghci: Force bytecode to be evaluated after loading Message-ID: <679a6984169df_294be8ef68982759@gitlab.mail> Matthew Pickering pushed to branch wip/ghci-force-background at Glasgow Haskell Compiler / GHC Commits: 2a66eb15 by Matthew Pickering at 2025-01-29T17:46:32+00:00 ghci: Force bytecode to be evaluated after loading Behaviour before: Bytecode is forced when you need it to evaluate an expression in the interpreter. Behaviour after: Bytecode is forced in parallel, in the background, after the initial load is completed. The goal is to increase percieved responsiveness of the interpreter after a reload. If you do a reload and at a later point perform evaluation, now the evaluation will start immediately, rather than waiting first for all the byte code to be compiled. Since the bytecode is evaluated in the background, the prompt can still be used like normal to evaluate expressions or perform other queries. The thunks are evaluated in parallel by creating a spark for each thunk, thus if another reload is perfomed then the sparks will be discarded as the thunks in question will no longer be evaluated. - - - - - 2 changed files: - compiler/GHC/Unit/Home/PackageTable.hs - ghc/GHCi/UI.hs Changes: ===================================== compiler/GHC/Unit/Home/PackageTable.hs ===================================== @@ -47,6 +47,7 @@ module GHC.Unit.Home.PackageTable -- ** More Traversal-based queries , hptCollectDependencies , hptCollectObjects + , hptCollectByteCode , hptCollectModules -- ** Memory dangerous queries @@ -248,6 +249,12 @@ hptCollectObjects HPT{table} = do return $ foldr ((:) . expectJust "collectObjects" . homeModInfoObject) [] hpt +hptCollectByteCode :: HomePackageTable -> IO [Linkable] +hptCollectByteCode HPT{table} = do + hpt <- readIORef table + return $ + catMaybes $ foldr ((:) . homeModInfoByteCode) [] hpt + -- | Collect all module ifaces in the HPT -- -- $O(n)$ in the number of modules in the HPT. ===================================== ghc/GHCi/UI.hs ===================================== @@ -94,6 +94,8 @@ import GHC.Unit.Finder as Finder import GHC.Unit.Module.Graph (filterToposortToModules) import GHC.Unit.Module.ModSummary +import GHC.Linker.Types + import GHC.Data.StringBuffer import GHC.Utils.Outputable import GHC.Utils.Logger @@ -176,6 +178,8 @@ import GHC.TopHandler ( topHandler ) import qualified GHC.Unit.Module.Graph as GHC +import GHC.Conc.Sync ( par, pseq, forkIO ) + ----------------------------------------------------------------------------- data GhciSettings = GhciSettings { @@ -2170,6 +2174,34 @@ afterLoad ok load_type = do modulesLoadedMsg ok loaded_mods load_type graph <- GHC.getModuleGraph setContextAfterLoad (isReload load_type) (Just graph) + forceByteCode + +-- | Force any compiled bytecode in the background +-- +-- During compilation the compiler leaves thunks when producing bytecode, so that +-- the result is not forced before it is needed. (Especially important when doing recompilation +-- checking) +-- +-- However, after the reload is complete, the interpreter will otherwise be idle, so +-- force those thunks in parallel so that when the user comes to write in the prompt +-- the response is faster. +forceByteCode :: GhciMonad m => m () +forceByteCode = do + hsc_env <- GHC.getSession + -- Spawn a new thread, so the thunks are forced completely in the background of the main thread + -- and we can get to the prompt as fast as possible. + void $ liftIO $ forkIO $ do + all_linkables <- liftIO (concat <$> traverse (hptCollectByteCode . homeUnitEnv_hpt) (hsc_HUG hsc_env)) + liftIO $ evaluate $ foldr (\x u -> force x `pseq` u) () all_linkables + + where + + force :: Linkable -> () + force (Linkable _ _ ps) = foldr (\a u -> force_part a `par` u) () ps + + force_part (LazyBCOs x _) = x `par` () + force_part _ = () + setContextAfterLoad :: GhciMonad m => Bool -> Maybe GHC.ModuleGraph -> m () setContextAfterLoad keep_ctxt Nothing = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a66eb15f744d876acedf7a42db7cdd2196bd6e9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a66eb15f744d876acedf7a42db7cdd2196bd6e9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 17:53:33 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Wed, 29 Jan 2025 12:53:33 -0500 Subject: [Git][ghc/ghc][wip/romes/25170-simpl] 2 commits: tweaks Message-ID: <679a6b1d71e8b_294be8ef685c307ef@gitlab.mail> Rodrigo Mesquita pushed to branch wip/romes/25170-simpl at Glasgow Haskell Compiler / GHC Commits: 47c0da99 by Rodrigo Mesquita at 2025-01-29T10:48:58+00:00 tweaks - - - - - 97108cc2 by Rodrigo Mesquita at 2025-01-29T17:53:22+00:00 More fixes - - - - - 4 changed files: - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Data/List/SetOps.hs - compiler/GHC/Types/Id/Make.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Iteration.hs ===================================== @@ -2308,48 +2308,55 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args -- See Note [Rewrite rules and inlining] -- See also Note [Trying rewrite rules] -rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args - , ai_rewrite = TryRules _nr_wanted rules }) cont +rebuildCall env original_info@(ArgInfo { ai_fun = fun, ai_args = rev_args + , ai_rewrite = TryRules _nr_wanted rules }) original_cont | [] <- rev_args = -- Try rewrite rules on unsimplified arguments, then once more when all -- arguments have been simplified (below). See Note [TODO] - let (unsimp_info, res_cont') = take_unsimpl cont - in applyRules (ai_args unsimp_info) res_cont' + let (unsimp_info, res_cont') = take_unsimpl_rev original_cont + in -- pprTrace "rebuildCall:1" (ppr original_info $$ ppr original_cont $$ ppr unsimp_info $$ ppr res_cont') $ + applyRules False unsimp_info res_cont' | no_more_args = -- We've accumulated a simplified call in -- so try rewrite rules; see Note [RULES apply to simplified arguments] -- See also Note [Rules for recursive functions] - applyRules rev_args cont + applyRules True original_info original_cont where - applyRules rev_args' cont' = do - mb_match <- tryRules env rules fun (reverse rev_args') cont' + applyRules are_simpl info' cont' = do + mb_match <- tryRules env rules are_simpl fun (reverse $ ai_args info') cont' case mb_match of - Just (env', rhs, cont'') -> simplExprF env' rhs cont'' - Nothing -> rebuildCall env (info { ai_rewrite = TryInlining }) cont' + Just (env', rhs, cont'') -> + pprTrace "Match:1" (text "aresimpl:" <+> ppr are_simpl + $$ ppr info' $$ text "rhs:" <+> ppr rhs $$ text "origcont:" <+> ppr cont' $$ text "newcont:" <+> ppr cont'') $ + pprTrace "before try rules" (text "env:" <+> ppr (seInScope env) <+> ppr (seIdSubst env)) + $ pprTrace "after try rules" (text "env':" <+> ppr (seInScope env') <+> ppr (seIdSubst env')) + $ simplExprF env' rhs cont'' + Nothing -> rebuildCall env (original_info { ai_rewrite = TryInlining }) original_cont -- If we have run out of arguments, just try the rules; there might -- be some with lower arity. Casts get in the way -- they aren't -- allowed on rule LHSs - no_more_args = case cont of + no_more_args = case original_cont of ApplyToTy {} -> False ApplyToVal {} -> False _ -> True + take_unsimpl_rev k + | (i, k') <- take_unsimpl k + = (i{ ai_args = reverse (ai_args i) }, k') take_unsimpl ApplyToVal { sc_arg = arg, sc_hole_ty = fun_ty, sc_cont = k } | (i, k') <- take_unsimpl k = (addValArgTo i arg fun_ty, k') take_unsimpl ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = k } | (i, k') <- take_unsimpl k = (addTyArgTo i arg_ty hole_ty, k') - take_unsimpl CastIt { sc_co = co, sc_opt = opt, sc_cont = k } + take_unsimpl CastIt { sc_co = co, sc_opt = _opt, sc_cont = k } | (i, k') <- take_unsimpl k - = (addCastTo i co', k') - where -- must still simpl coercions - co' = optOutCoercion env co opt + = (addCastTo i co, k') take_unsimpl k - = (info, k) + = (original_info, k) ---------- Simplify type applications and casts -------------- rebuildCall env info (CastIt { sc_co = co, sc_opt = opt, sc_cont = cont }) @@ -2465,7 +2472,7 @@ tryInlining env logger var cont | not (logHasDumpFlag logger Opt_D_verbose_core2core) = when (isExternalName (idName var)) $ log_inlining $ - sep [text "Inlining done:", nest 4 (ppr var)] + sep [text "Inlining done:", nest 4 (ppr var)] $$ sep [text "Inlining continuation:", nest 4 (ppr cont)] | otherwise = log_inlining $ sep [text "Inlining done: " <> ppr var, @@ -2599,12 +2606,13 @@ See Note [No free join points in arityType] in GHC.Core.Opt.Arity -} tryRules :: SimplEnv -> [CoreRule] + -> Bool -- Are the arguments already simplified? -> Id -> [ArgSpec] -- In /normal, forward/ order -> SimplCont -> SimplM (Maybe (SimplEnv, CoreExpr, SimplCont)) -tryRules env rules fn args call_cont +tryRules env rules are_simpl fn args call_cont | null rules = return Nothing @@ -2613,10 +2621,11 @@ tryRules env rules fn args call_cont (argInfoAppArgs args) rules -- Fire a rule for the function = do { logger <- getLogger + ; pprTraceM "tryRules" (text "rule:" <+> ppr rule $$ text "rhs:" <+> ppr rule_rhs $$ text "lookedup" <+> ppr fn <+> ppr (argInfoAppArgs args)) ; checkedTick (RuleFired (ruleName rule)) - ; let cont' = pushSimplifiedArgs zapped_env - (drop (ruleArity rule) args) - call_cont + ; let cont' = pushArgs zapped_env + (drop (ruleArity rule) args) + call_cont -- (ruleArity rule) says how -- many args the rule consumed @@ -2634,7 +2643,10 @@ tryRules env rules fn args call_cont where ropts = seRuleOpts env - zapped_env = zapSubstEnv env -- See Note [zapSubstEnv] + zapped_env | are_simpl = zapSubstEnv env -- See Note [zapSubstEnv] + | otherwise = env -- (we only zap when the arguments are already simplified) + pushArgs | are_simpl = pushSimplifiedArgs + | otherwise = pushUnsimplifiedArgs printRuleModule rule = parens (maybe (text "BUILTIN") @@ -2685,7 +2697,7 @@ trySeqRules :: SimplEnv -- See Note [User-defined RULES for seq] trySeqRules in_env scrut rhs cont = do { rule_base <- getSimplRules - ; tryRules in_env (getRules rule_base seqId) seqId out_args rule_cont } + ; tryRules in_env (getRules rule_base seqId) True seqId out_args rule_cont } where no_cast_scrut = drop_casts scrut scrut_ty = exprType no_cast_scrut ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -33,7 +33,7 @@ module GHC.Core.Opt.Simplify.Utils ( ArgInfo(..), ArgSpec(..), RewriteCall(..), mkArgInfo, addValArgTo, addCastTo, addTyArgTo, argInfoExpr, argInfoAppArgs, - pushSimplifiedArgs, pushSimplifiedRevArgs, + pushSimplifiedArgs, pushSimplifiedRevArgs, pushUnsimplifiedArgs, isStrictArgInfo, lazyArgContext, abstractFloats, @@ -405,12 +405,13 @@ argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as -pushSimplifiedArgs, pushSimplifiedRevArgs +pushSimplifiedArgs, pushSimplifiedRevArgs, pushUnsimplifiedArgs :: SimplEnv -> [ArgSpec] -- In normal, forward order for pushSimplifiedArgs, -- in /reverse/ order for pushSimplifiedRevArgs -> SimplCont -> SimplCont pushSimplifiedArgs env args cont = foldr (pushSimplifiedArg env) cont args +pushUnsimplifiedArgs env args cont = foldr (pushUnsimplifiedArg env) cont args pushSimplifiedRevArgs env args cont = foldl' (\k a -> pushSimplifiedArg env a k) cont args pushSimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont @@ -423,6 +424,15 @@ pushSimplifiedArg env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont pushSimplifiedArg _ (CastBy c) cont = CastIt { sc_co = c, sc_cont = cont, sc_opt = True } +pushUnsimplifiedArg :: SimplEnv -> ArgSpec -> SimplCont -> SimplCont +pushUnsimplifiedArg _env (TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty }) cont + = ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont } +pushUnsimplifiedArg env (ValArg { as_arg = arg, as_hole_ty = hole_ty }) cont + = ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = NoDup + , sc_hole_ty = hole_ty, sc_cont = cont } +pushUnsimplifiedArg _ (CastBy c) cont + = CastIt { sc_co = c, sc_cont = cont, sc_opt = False } + argInfoExpr :: OutId -> [ArgSpec] -> OutExpr -- NB: the [ArgSpec] is reversed so that the first arg -- in the list is the last one in the application ===================================== compiler/GHC/Data/List/SetOps.hs ===================================== @@ -40,7 +40,7 @@ import Data.List.NonEmpty (NonEmpty(..)) import Data.Ord (comparing) import qualified Data.Set as S -getNth :: Outputable a => [a] -> Int -> a +getNth :: (HasCallStack, Outputable a) => [a] -> Int -> a getNth xs n = assertPpr (xs `lengthExceeds` n) (ppr n $$ ppr xs) $ xs !! n ===================================== compiler/GHC/Types/Id/Make.hs ===================================== @@ -566,7 +566,7 @@ mkDictSelRhs clas val_index -- varToCoreExpr needed for equality superclass selectors -- sel a b d = case x of { MkC _ (g:a~b) _ -> CO g } -dictSelRule :: Int -> Arity -> RuleFun +dictSelRule :: HasCallStack => Int -> Arity -> RuleFun -- Tries to persuade the argument to look like a constructor -- application, using exprIsConApp_maybe, and then selects -- from it View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/00ee0bc075441642724255007586d2720673aa61...97108cc2f21665aebea5101f930f8d902b573610 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/00ee0bc075441642724255007586d2720673aa61...97108cc2f21665aebea5101f930f8d902b573610 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 19:24:49 2025 From: gitlab at gitlab.haskell.org (Patrick (@soulomoon)) Date: Wed, 29 Jan 2025 14:24:49 -0500 Subject: [Git][ghc/ghc][wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax] 41 commits: Rework built-in and punned names (#25174, #25179, #25180, #25182) Message-ID: <679a80818cfa5_2cb252ab7bb0102846@gitlab.mail> Patrick pushed to branch wip/soulomoon/25647-allow-newtype-instance-in-gadt-syntax at Glasgow Haskell Compiler / GHC Commits: 51e3ec83 by Vladislav Zavialov at 2025-01-22T20:41:32+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 85c60aea by Teo Camarasu at 2025-01-23T18:06:21-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4495e48f by Brandon Chinn at 2025-01-24T11:54:24-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 4f8fc11e by Brandon Chinn at 2025-01-24T11:54:24-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - e7ab778f by Matthew Pickering at 2025-01-24T11:55:01-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - c3593101 by Sylvain Henry at 2025-01-24T23:12:20-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 70f7741a by Jens Petersen at 2025-01-24T23:12:58-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - a1d92378 by Brandon Chinn at 2025-01-25T15:11:54-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 62760367 by ARATA Mizuki at 2025-01-27T16:23:06-05:00 x86 NCG: Make MOVD's output format explicit The old design led to inference of a wrong format, losing upper bits of a vector register. Fixes #25659 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - f19ab490 by Simon Hengel at 2025-01-27T16:23:45-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - e16eae65 by Cheng Shao at 2025-01-27T21:41:39+00:00 hadrian: fix bootstrap with 9.12.1 This patch bumps hadrian index-state to fix bootstrap with 9.12.1. - - - - - 8071bad8 by Jeffrey Young at 2025-01-28T21:45:32-05:00 base: add SrcLoc changes to changelog, 4.21.0.0 I accidentally dropped this in !13381 - closes #25614 See: - ea4587794b9e3a098f9c02bd6cea2294af2539ce (the 13381 commit) - Issue #25614 - - - - - 9dcc7e28 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Rename `cloneBndrs` and such — now all the monadic ones have an `M` suffix. We now have `cloneBndrs` and `cloneRecIdBndrs` which take a `UniqSupply` argument, and `cloneBndrsM` and `cloneRecIdBndrsM` which rather have a `MonadUnique` constraint. - - - - - 643dd3d8 by Matthew Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in unique generation, and clean up some other partial uni patterns as well. Also drop the losing `instance MonadFail UniqSM`. We redefine `getUniquesM` in terms of `Infinite` rather than `[]`, and define another method `getUniqueListM` for the use sites where we actually want a `[]`. Thus, at many sites, we can avoid the partiality of the empty list case. We also define `withUniques`, `withUniquesM`, and `withUniquesM'`, which traverse an arbitrary `Traversable` structure and introduce a `Unique` for each element. This allows us to redefine various functions to operate on more appropriate types than `[]` and avoid further partiality (in the form of incomplete-uni-patterns). - - - - - dd0acc3c by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Tc.Deriv.Functor`. Make the list of variables to use in generated code `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - 4e9adedf by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Runtime.Debugger`. Make the list of available names `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - bed812b7 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Cmm.DebugBlock`. We do so by changing the type of `BlockContext` to statically (in GHC) exclude the possibility of Cmm statics, and using `NonEmpty` lists of `BlockContext`s in `cmmDebugGen`. - - - - - 27587df3 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Types.Literal`. We do so by introducing `mkLitNumberWrap'` whose ultimate codomain is `Integer` rather than `Literal`, and then use that rather than `mkLitNumberWrap` where we just need the number rather than the `Literal`. - - - - - 138de0ff by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.CmmToAsm.X86.CodeGen`. - Match the vector element list only once in `shuffleInstructions`. - Define `isSuitableFloatingPointLit_maybe` which returns `Just` the width if the lit is indeed suitable. - - - - - d8cb3d36 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Clean up more incomplete uni patterns. At some sites, we merely panic if the `[]` or `Maybe` is empty when we convert to `NonEmpty` or `Identity`, but at least now we make it explicit. At other sites, we are able to use more precise types and avoid the partiality altogether. To do so, we redefine various functions to operate over `Traversable` arguments, so we can use the appropriate shape where known. - - - - - f251bd22 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Outline `expectJustPanic`. - - - - - a963a1a5 by Marc Scholten at 2025-01-29T02:28:35-05:00 base: Introduce Data.Enum.enumerate (CLC #306) https://github.com/haskell/core-libraries-committee/issues/306 - - - - - 944712da by Ben Gamari at 2025-01-29T02:29:13-05:00 base: Update description of locking behavior - - - - - 85abc69c by Ben Gamari at 2025-01-29T02:29:51-05:00 base: Fix @since annotation of Data.Bounded Fixes #25615. - - - - - 2ca41c62 by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Fix overly-broad handling of Addr# literals Previously we assumed that all unlifted types were `Addr#` but this isn't true. As noted in #25638, unlifted nullary data constructor workers can also appear at the top-level and are obviously not of type `Addr#`. Note that there is more work to be done to properly handle unlifted data constructors (especially nullary; see #25636). However, this is a small step in the right direction. Closes #25641. - - - - - ec26c54d by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Assert that PUSH_G'd values are lifted We currently do not support top-level unlifted data constructor applications, therefore this is a safe assertion. Pointed out by @sheaf. - - - - - 8847125f by Ben Gamari at 2025-01-29T02:31:07-05:00 gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Closes #25654. - - - - - bf8c7d6e by Matthew Pickering at 2025-01-29T02:31:44-05:00 bytecode: Do not generate `SLIDE x 0` instructions SLIDE x 0 is a no-op as it means to shift x elements of the stack by no spaces. In the interpreter, this results in a loop which copies an array element into the same place. I have instrumented GHCi to count how many of these instructions are interpreted. The workload was `ghc` compiling two simple modules. Total no-op slides: 7793476 Total slides: 11413289 Percentage useless (slides): 68% Percentage uselss of total instructions: 9% - - - - - a47dd756 by Patrick at 2025-01-29T19:24:45+00:00 update kcConDecl to also consider the result type in newtype GADT instance - - - - - e33618ff by Patrick at 2025-01-29T19:24:45+00:00 peek at the result kind - - - - - 49d62647 by Patrick at 2025-01-29T19:24:45+00:00 test if gadt has UserSuppliedResultKind in lhs, we let tc_res_kind to unify with rhs result kind if not to gain more inference - - - - - ac11b35d by Patrick at 2025-01-29T19:24:45+00:00 format and remove getTyConResultKind - - - - - 17f99f41 by Patrick at 2025-01-29T19:24:45+00:00 format - - - - - ca2e1273 by Patrick at 2025-01-29T19:24:45+00:00 add comment - - - - - e26a2e79 by Patrick at 2025-01-29T19:24:45+00:00 cleanup - - - - - f2da933a by Patrick at 2025-01-29T19:24:45+00:00 cleanup - - - - - d8e56d10 by Patrick at 2025-01-29T19:24:45+00:00 update T25611a - - - - - 67da4cd4 by Patrick at 2025-01-29T19:24:45+00:00 rename and add note - - - - - 8cc0272d by Patrick at 2025-01-29T19:24:45+00:00 update note - - - - - 67da6f95 by Patrick at 2025-01-29T19:24:45+00:00 update note - - - - - 19560b50 by Patrick at 2025-01-29T19:24:45+00:00 format - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6df0b1b34b6bd307db0087ce9d3852bf24980c01...19560b50b390175bf6f9173f639ee08fcec29ef2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6df0b1b34b6bd307db0087ce9d3852bf24980c01...19560b50b390175bf6f9173f639ee08fcec29ef2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed Jan 29 23:11:23 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 18:11:23 -0500 Subject: =?UTF-8?Q?[Git][ghc/ghc][wip/marge=5Fbot=5Fbatch=5Fmerge=5Fjob]_18?= =?UTF-8?Q?_commits:_Rename_`cloneBndrs`_and_such_=E2=80=94_now_all_the?= =?UTF-8?Q?_monadic_ones_have_an_`M`_suffix.?= Message-ID: <679ab59b76330_324755dd985c51093@gitlab.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 9dcc7e28 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Rename `cloneBndrs` and such — now all the monadic ones have an `M` suffix. We now have `cloneBndrs` and `cloneRecIdBndrs` which take a `UniqSupply` argument, and `cloneBndrsM` and `cloneRecIdBndrsM` which rather have a `MonadUnique` constraint. - - - - - 643dd3d8 by Matthew Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in unique generation, and clean up some other partial uni patterns as well. Also drop the losing `instance MonadFail UniqSM`. We redefine `getUniquesM` in terms of `Infinite` rather than `[]`, and define another method `getUniqueListM` for the use sites where we actually want a `[]`. Thus, at many sites, we can avoid the partiality of the empty list case. We also define `withUniques`, `withUniquesM`, and `withUniquesM'`, which traverse an arbitrary `Traversable` structure and introduce a `Unique` for each element. This allows us to redefine various functions to operate on more appropriate types than `[]` and avoid further partiality (in the form of incomplete-uni-patterns). - - - - - dd0acc3c by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Tc.Deriv.Functor`. Make the list of variables to use in generated code `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - 4e9adedf by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Runtime.Debugger`. Make the list of available names `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - bed812b7 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Cmm.DebugBlock`. We do so by changing the type of `BlockContext` to statically (in GHC) exclude the possibility of Cmm statics, and using `NonEmpty` lists of `BlockContext`s in `cmmDebugGen`. - - - - - 27587df3 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Types.Literal`. We do so by introducing `mkLitNumberWrap'` whose ultimate codomain is `Integer` rather than `Literal`, and then use that rather than `mkLitNumberWrap` where we just need the number rather than the `Literal`. - - - - - 138de0ff by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.CmmToAsm.X86.CodeGen`. - Match the vector element list only once in `shuffleInstructions`. - Define `isSuitableFloatingPointLit_maybe` which returns `Just` the width if the lit is indeed suitable. - - - - - d8cb3d36 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Clean up more incomplete uni patterns. At some sites, we merely panic if the `[]` or `Maybe` is empty when we convert to `NonEmpty` or `Identity`, but at least now we make it explicit. At other sites, we are able to use more precise types and avoid the partiality altogether. To do so, we redefine various functions to operate over `Traversable` arguments, so we can use the appropriate shape where known. - - - - - f251bd22 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Outline `expectJustPanic`. - - - - - a963a1a5 by Marc Scholten at 2025-01-29T02:28:35-05:00 base: Introduce Data.Enum.enumerate (CLC #306) https://github.com/haskell/core-libraries-committee/issues/306 - - - - - 944712da by Ben Gamari at 2025-01-29T02:29:13-05:00 base: Update description of locking behavior - - - - - 85abc69c by Ben Gamari at 2025-01-29T02:29:51-05:00 base: Fix @since annotation of Data.Bounded Fixes #25615. - - - - - 2ca41c62 by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Fix overly-broad handling of Addr# literals Previously we assumed that all unlifted types were `Addr#` but this isn't true. As noted in #25638, unlifted nullary data constructor workers can also appear at the top-level and are obviously not of type `Addr#`. Note that there is more work to be done to properly handle unlifted data constructors (especially nullary; see #25636). However, this is a small step in the right direction. Closes #25641. - - - - - ec26c54d by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Assert that PUSH_G'd values are lifted We currently do not support top-level unlifted data constructor applications, therefore this is a safe assertion. Pointed out by @sheaf. - - - - - 8847125f by Ben Gamari at 2025-01-29T02:31:07-05:00 gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Closes #25654. - - - - - bf8c7d6e by Matthew Pickering at 2025-01-29T02:31:44-05:00 bytecode: Do not generate `SLIDE x 0` instructions SLIDE x 0 is a no-op as it means to shift x elements of the stack by no spaces. In the interpreter, this results in a loop which copies an array element into the same place. I have instrumented GHCi to count how many of these instructions are interpreted. The workload was `ghc` compiling two simple modules. Total no-op slides: 7793476 Total slides: 11413289 Percentage useless (slides): 68% Percentage uselss of total instructions: 9% - - - - - 48a9c19b by Zubin Duggal at 2025-01-29T18:11:04-05:00 hackage-doc-tarball: Allow ghc-boot-th to be uploaded to hackage It can't refer to files outside its source directory, so patch that part out. This is OK because those files are only used while bootstrapping. Also add ghci to the list of packages to be uploaded Fixes #25687 - - - - - 682c248b by Roman S at 2025-01-29T18:11:10-05:00 Fix Control.Arrow (***) diagram (fixes #25698) - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/rel_eng/upload_ghc_libs.py - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Iteration.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Subst.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/List/Infinite.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Pipeline/Execute.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/91833c0be12a22767511a4fa6b774dedbdcef9d4...682c248b6789830ce97ba0f3f1699fa45db49615 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/91833c0be12a22767511a4fa6b774dedbdcef9d4...682c248b6789830ce97ba0f3f1699fa45db49615 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 02:41:42 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 21:41:42 -0500 Subject: [Git][ghc/ghc][master] hackage-doc-tarball: Allow ghc-boot-th to be uploaded to hackage Message-ID: <679ae6e6925d0_37c172112c48c1035a7@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7bfc93a7 by Zubin Duggal at 2025-01-29T21:41:17-05:00 hackage-doc-tarball: Allow ghc-boot-th to be uploaded to hackage It can't refer to files outside its source directory, so patch that part out. This is OK because those files are only used while bootstrapping. Also add ghci to the list of packages to be uploaded Fixes #25687 - - - - - 1 changed file: - .gitlab/rel_eng/upload_ghc_libs.py Changes: ===================================== .gitlab/rel_eng/upload_ghc_libs.py ===================================== @@ -93,6 +93,11 @@ def prep_ghc(): build_copy_file(PACKAGES['ghc'], 'GHC/Platform/Constants.hs') build_copy_file(PACKAGES['ghc'], 'GHC/Settings/Config.hs') +def prep_ghc_boot_th(): + # Drop ghc-internal from `hs-source-dirs` as Hackage rejects this + modify_file(PACKAGES['ghc-boot-th'], 'ghc-boot-th.cabal', + lambda s: s.replace('../ghc-internal/src', '')) + PACKAGES = { pkg.name: pkg for pkg in [ @@ -105,9 +110,10 @@ PACKAGES = { Package('template-haskell', Path("libraries/template-haskell"), no_prep), Package('ghc-heap', Path("libraries/ghc-heap"), no_prep), Package('ghc-boot', Path("libraries/ghc-boot"), prep_ghc_boot), - Package('ghc-boot-th', Path("libraries/ghc-boot-th"), no_prep), + Package('ghc-boot-th', Path("libraries/ghc-boot-th"), prep_ghc_boot_th), Package('ghc-compact', Path("libraries/ghc-compact"), no_prep), Package('ghc', Path("compiler"), prep_ghc), + Package('ghci', Path("libraries/ghci"), no_prep), ] } # Dict[str, Package] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7bfc93a7054d48bee6779d38808534f1d7ca06f0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7bfc93a7054d48bee6779d38808534f1d7ca06f0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 02:42:32 2025 From: gitlab at gitlab.haskell.org (Marge Bot (@marge-bot)) Date: Wed, 29 Jan 2025 21:42:32 -0500 Subject: [Git][ghc/ghc][master] Fix Control.Arrow (***) diagram (fixes #25698) Message-ID: <679ae7188b7b6_37c172112c57c107446@gitlab.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 704eeb02 by Roman S at 2025-01-29T21:42:05-05:00 Fix Control.Arrow (***) diagram (fixes #25698) - - - - - 1 changed file: - libraries/ghc-internal/src/GHC/Internal/Control/Arrow.hs Changes: ===================================== libraries/ghc-internal/src/GHC/Internal/Control/Arrow.hs ===================================== @@ -131,10 +131,10 @@ class Category a => Arrow a where -- The default definition may be overridden with a more efficient -- version if desired. -- - -- > b ╭─────╮ b' + -- > b ╭─────╮ c -- > >───┼─ f ─┼───> -- > >───┼─ g ─┼───> - -- > c ╰─────╯ c' + -- > b'╰─────╯ c' (***) :: a b c -> a b' c' -> a (b,b') (c,c') f *** g = first f >>> arr swap >>> first g >>> arr swap where swap ~(x,y) = (y,x) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/704eeb02b072543bcb795113a50adf201fe709ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/704eeb02b072543bcb795113a50adf201fe709ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 03:44:42 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 29 Jan 2025 22:44:42 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/backports-9.12 Message-ID: <679af5aad94fa_3ac26f459de05456d@gitlab.mail> Ben Gamari pushed new branch wip/backports-9.12 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/backports-9.12 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 03:57:54 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 29 Jan 2025 22:57:54 -0500 Subject: [Git][ghc/ghc] Deleted branch wip/ghc-9.6.7-backports Message-ID: <679af8c249321_3ac26facca245786a@gitlab.mail> Ben Gamari deleted branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 03:57:55 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Wed, 29 Jan 2025 22:57:55 -0500 Subject: [Git][ghc/ghc][ghc-9.6] 80 commits: set RELEASE=NO Message-ID: <679af8c3d52a9_3ac26fae9dcc580e9@gitlab.mail> Ben Gamari pushed to branch ghc-9.6 at Glasgow Haskell Compiler / GHC Commits: 65e3257e by Luite Stegeman at 2025-01-15T04:45:48+01:00 set RELEASE=NO - - - - - 158539b7 by Krzysztof Gogolewski at 2025-01-16T09:49:57+01:00 Fix IPE test A helper function was defined in a different module than used. To reproduce: ./hadrian/build test --test-root-dirs=testsuite/tests/rts/ipe (cherry picked from commit 3e606230e904482f900a43a25aa4584567f25d87) - - - - - e4bf5cb6 by Matthew Craven at 2025-01-16T09:49:57+01:00 testsuite: Give the pre_cmd for mhu-perf more time (cherry picked from commit dba03aababff057c03e2d92677de02d8375cd23a) - - - - - d44184fc by Cheng Shao at 2025-01-16T09:49:57+01:00 testsuite: give pre_cmd for mhu-perf 5x time (cherry picked from commit 0820750140af2972ca254a42c0fdc537f3b7c447) - - - - - 87b712cb by Luite Stegeman at 2025-01-16T09:49:57+01:00 testsuite: mark T7919 as fragile it occasionally fails on multiple platforms - - - - - c5082d90 by Zubin Duggal at 2025-01-16T09:49:57+01:00 testsuite: Skip MultiLayerModulesTH_OneShot on darwin See #24177 (cherry picked from commit 1bf7ce0e3ec4be3bacea015c42a2a218c33bea43) - - - - - 28acd4a3 by Rodrigo Mesquita at 2025-01-16T09:49:57+01:00 testsuite: Skip MultiLayerModulesTH_Make on darwin The recent toolchain upgrade on darwin machines resulted in the MultiLayerModulesTH_Make test metrics varying too much from the baseline, ultimately blocking the CI pipelines. This commit skips the test on darwin to temporarily avoid failures due to the environment change in the runners. However, the metrics divergence is being investigated still (tracked in #24177) (cherry picked from commit 929ba2f95a92d382dd72f4a9151ea7cfa0ec97f1) - - - - - 4177160a by Arnaud Spiwack at 2025-01-16T09:49:57+01:00 Push coercions across multiplicity boundaries Per the new `Note [Linting linearity]`, we want optimisations over trying to preserve linearity. This will avoid preventing inlinings and reductions and make linear programs more efficient. (cherry picked from commit bf9344d24157986ea013210e7cb9a5953670e0e2) - - - - - f96ea4b6 by Arnaud Spiwack at 2025-01-16T09:49:58+01:00 Allow CPR on unrestricted constructors Per the new `Note [Linting linearity]`, we want optimisations over trying to preserve linearity. This will allow CPR to handle `Ur`, in particular. (cherry picked from commit 981e5e11f41a11c0d58fa61faea2fe4a5ef02d00) - - - - - 593c211b by Cheng Shao at 2025-01-16T09:49:58+01:00 rts: fix --disable-large-address-space This patch moves ACQUIRE_ALLOC_BLOCK_SPIN_LOCK/RELEASE_ALLOC_BLOCK_SPIN_LOCK from Storage.h to HeapAlloc.h. When --disable-large-address-space is passed to configure, the code in HeapAlloc.h makes use of these two macros. Fixes #23385. (cherry picked from commit a8f0435fc5516ad978064eeabcc24776b6b86351) - - - - - b4856589 by mimi.vx at 2025-01-16T09:49:58+01:00 Update rdt-theme to latest upstream version Fixes https://gitlab.haskell.org/ghc/ghc/-/issues/23444 (cherry picked from commit 70526f5bd8886126f49833ef20604a2c6477780a) - - - - - 3605e890 by ur4t at 2025-01-16T09:49:58+01:00 GHCi: fix improper location of ghci_history file Fixes #24266 (cherry picked from commit 6f0a62db5dc79640433c61e83ea1427665304869) - - - - - 6e7cba0c by Andreas Klebinger at 2025-01-16T09:49:58+01:00 Fix ffi callbacks with >6 args and non-64bit args. Check for ptr/int arguments rather than 64-bit width arguments when counting integer register arguments. The old approach broke when we stopped using exclusively W64-sized types to represent sub-word sized integers. Fixes #24314 (cherry picked from commit de589554386fc173a9019922851c05bb727e3450) - - - - - f0bfe936 by Andreas Klebinger at 2025-01-16T09:49:58+01:00 RTS: Emit warning when -M < -H Fixes #24487 (cherry picked from commit 23c3e624fbb9089d96ff33d043b157e4edd43a79) - - - - - f4628440 by Simon Peyton Jones at 2025-01-16T09:49:58+01:00 Don't generate wrappers for `type data` constructors with StrictData Previously, the logic for checking if a data constructor needs a wrapper or not would take into account whether the constructor's fields have explicit strictness (e.g., `data T = MkT !Int`), but the logic would _not_ take into account whether `StrictData` was enabled. This meant that something like `type data T = MkT Int` would incorrectly generate a wrapper for `MkT` if `StrictData` was enabled, leading to the horrible errors seen in #24620. To fix this, we disable generating wrappers for `type data` constructors altogether. Fixes #24620. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> (cherry picked from commit 5e4f4ba835fd24135759ee7a2d0d5c636a8a1505) - - - - - 3ccef3dd by Zubin Duggal at 2025-01-16T09:49:58+01:00 compiler: Fingerprint -fwrite-if-simplified-core We need to recompile if this flag is changed because later modules might depend on the simplified core for this module if -fprefer-bytecode is enabled. Fixes #24656 (cherry picked from commit dddc9dff0547733a10e7f505612ab9df3a7c21b6) - - - - - 67ff4e77 by Cheng Shao at 2025-01-16T09:49:58+01:00 rts: fix checkClosure error message This patch fixes an error message in checkClosure() when the closure has already been evacuated. The previous logic was meant to print the evacuated closure's type in the error message, but it was completely wrong, given info was not really an info table, but a tagged pointer that points to the closure's new address. (cherry picked from commit 0d3bc2fa3a9a8c342ec34bb9d32e493655a4ec69) - - - - - e66bcd5c by Sylvain Henry at 2025-01-16T09:49:58+01:00 Linker: use m32 allocator for sections when NEED_PLT (#24432) Use M32 allocator to avoid fragmentation when allocating ELF sections. We already did this when NEED_PLT was undefined. Failing to do this led to relocations impossible to fulfil (#24432). (cherry picked from commit 5104ee615503617a1c124fe1d92f6aa2d263b7d0) - - - - - ceae2621 by Sylvain Henry at 2025-01-16T09:49:58+01:00 RTS: allow M32 allocation outside of 4GB range when assuming -fPIC (cherry picked from commit 52d6698479f951e07def237b0474ee22d27e621a) - - - - - 3449cfd3 by Sylvain Henry at 2025-01-16T09:49:58+01:00 Linker: fix stub offset Remove unjustified +8 offset that leads to memory corruption (cf discussion in #24432). (cherry picked from commit c34fef56367142fa55e9861092f64cc7b9946fa1) - - - - - e6ba4f69 by Peter Trommler at 2025-01-16T09:49:58+01:00 X86 NCG: Fix argument promotion in foreign C calls Promote 8 bit and 16 bit signed arguments by sign extension. Fixes #25018 (cherry picked from commit a82121b3b6fdc2ac47211f71871b3ab21e5f6276) - - - - - ff24528f by Andreas Klebinger at 2025-01-16T09:49:58+01:00 Fix -freg-graphs for FP and AARch64 NCG (#24941). It seems we reserve 8 registers instead of four for global regs based on the layout in Note [AArch64 Register assignments]. I'm not sure it's neccesary, but for now we just accept this state of affairs and simple update -fregs-graph to account for this. (cherry picked from commit 3f89ab92da74c4ed45da68fe92ff81e7b9caa53d) - - - - - d1943f05 by doyougnu at 2025-01-16T09:49:58+01:00 Rts linker: add case for pc-rel 64 relocation part of the upstream haskell.nix patches (cherry picked from commit bfe4b3d3bbb98b39169fad063c6c32f06d167756) - - - - - 4c304809 by Simon Peyton Jones at 2025-01-16T09:49:58+01:00 Address #25055, by disabling case-of-runRW# in Gentle phase See Note [Case-of-case and full laziness] in GHC.Driver.Config.Core.Opt.Simplify (cherry picked from commit de5d9852dbdd367611bf9e45e69c723d26351992) - - - - - 5e50569d by Sylvain Henry at 2025-01-16T09:49:58+01:00 Only lookup ghcversion.h file in the RTS include-dirs by default. The code was introduced in 3549c952b535803270872adaf87262f2df0295a4. It used `getPackageIncludePath` which name doesn't convey that it looks into all include paths of the preload units too. So this behavior is probably unintentional and it should be ok to change it. Fix #25106 (cherry picked from commit f954f42823f6ca3588425a0d543d93ace86d89e4) - - - - - dab9025d by Matthew Pickering at 2025-01-16T09:49:58+01:00 driver: Fix -Wmissing-home-modules when multiple units have the same module name It was assumed that module names were unique but that isn't true with multiple units. The fix is quite simple, maintain a set of `(ModuleName, UnitId)` and query that to see whether the module has been specified. Fixes #25122 (cherry picked from commit 951ce3d5904a1d34d49787d444f99e251e24d4e7) - - - - - f2bb55d8 by Sylvain Henry at 2025-01-16T09:49:58+01:00 Cmm: don't perform unsound optimizations on 32-bit compiler hosts - beef61351b240967b49169d27a9a19565cf3c4af enabled the use of MO_Add/MO_Sub for 64-bit operations in the C and LLVM backends - 6755d833af8c21bbad6585144b10e20ac4a0a1ab did the same for the x86 NCG backend However we store some literal values as `Int` in the compiler. As a result, some Cmm optimizations transformed target 64-bit literals into compiler `Int`. If the compiler is 32-bit, this leads to computing with wrong literals (see #24893 and #24700). This patch disables these Cmm optimizations for 32-bit compilers. This is unsatisfying (optimizations shouldn't be compiler-word-size dependent) but it fixes the bug and it makes the patch easy to backport. A proper fix would be much more invasive but it shall be implemented in the future. Co-authored-by: amesgen <amesgen at amesgen.de> (cherry picked from commit 7446a09a2d5b04b95cd43c03659b5647853124ce) - - - - - 70410779 by Sylvain Henry at 2025-01-16T09:49:58+01:00 AARCH64 linker: skip NONE relocations This patch is part of the patches upstreamed from haskell.nix. See https://github.com/input-output-hk/haskell.nix/pull/1960 for the original report/patch. (cherry picked from commit c749bdfd3e21d712dc2b966482eb010165bdeebe) - - - - - cb2cccf8 by Sylvain Henry at 2025-01-16T09:49:58+01:00 JS: support rubbish static literals (#25177) Support for rubbish dynamic literals was added in #24664. This patch does the same for static literals. Fix #25177 (cherry picked from commit 5092dbff750ee5b6fd082b7eed8574922a2b0bf4) - - - - - cb95a3ca by Matthew Pickering at 2025-01-16T09:49:58+01:00 driver: Fix -working-dir for foreign files -working-dir definitely needs more serious testing, there are some easy ways to test this. * Modify Cabal to call ghc using -working-dir rather than changing directory. * Modify the testsuite to run ghc using `-working-dir` rather than running GHC with cwd = temporary directory. However this will have to wait until after 9.12. Fixes #25150 (cherry picked from commit c20d51867c824e32c61bd1e002680bef268e4f51) - - - - - 9177b8ed by Sylvain Henry at 2025-01-16T09:49:58+01:00 Fix interaction between fork and kqueue (#24672) A kqueue file descriptor isn't inherited by a child created with fork. As such we mustn't try to close this file descriptor as we would close a random one, e.g. the one used by timerfd. Fix #24672 (cherry picked from commit e7a26d7a6faf1ea534e036c5085a0a027dbb6f5f) - - - - - cfc9f465 by Simon Peyton Jones at 2025-01-16T09:49:58+01:00 Consider Wanteds with rewriters as insoluble This MR fixes #25325 See GHC.Tc.Types.Constraint, Note [Insoluble Wanteds], especially (IW2) There is a small change in the error message for T14172, but it looks entirely acceptable to me. (cherry picked from commit 083703a12cd34369e7ed2f0efc4a5baee47aedab) - - - - - df04f6e8 by Cheng Shao at 2025-01-16T09:49:59+01:00 rts: fix pointer overflow undefined behavior in bytecode interpreter This patch fixes an unnoticed undefined behavior in the bytecode interpreter. It can be caught by building `rts/Interpreter.c` with `-fsanitize=pointer-overflow`, the warning message is something like: ``` rts/Interpreter.c:1369:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1369:13 rts/Interpreter.c:1265:13: runtime error: addition of unsigned offset to 0x004200197660 overflowed to 0x004200197658 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1265:13 rts/Interpreter.c:1645:13: runtime error: addition of unsigned offset to 0x0042000b22f8 overflowed to 0x0042000b22f0 SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior rts/Interpreter.c:1645:13 ``` Whenever we do something like `SpW(-1)`, the negative argument is implicitly converted to an unsigned integer type and causes pointer arithmetic overflow. It happens to be harmless for most targets since overflowing would wrap the result to desired value, but it's still coincidental and undefined behavior. Furthermore, it causes real damage to the wasm backend, given clang-20 will emit invalid wasm code that crashes at run-time for this kind of C code! (see https://github.com/llvm/llvm-project/issues/108770) The fix here is adding some explicit casts to ensure we always use the signed `ptrdiff_t` type as right hand operand of pointer arithmetic. (cherry picked from commit 5bcfefd5bb73c18a9bad63d1813968832b696f9a) - - - - - 69020c2a by Sebastian Graf at 2025-01-16T09:49:59+01:00 DmdAnal: Make `prompt#` lazy (#25439) This applies the same treatment to `prompt#` as for `catch#`. See `Note [Strictness for mask/unmask/catch/prompt]`. Fixes #25439. (cherry picked from commit 00d58ae18a7ce8db6b2d57261a08ba8c1c2549b5) - - - - - 1da62d87 by Cristiano Moraes at 2025-01-16T09:49:59+01:00 configure: Find C++ probing when GCC version is the latest but G++ is old #23118 (cherry picked from commit 78ad81ecef846f73fee0f6c1a86cd6f19aa29b21) - - - - - 56158983 by Ben Gamari at 2025-01-16T09:49:59+01:00 rts/linker/Elf: Resolve _GLOBAL_OFFSET_TABLE_ (cherry picked from commit 639f0149b3deabb641fcf38b693c6f07f252be11) - - - - - 17495fe4 by Ben Gamari at 2025-01-16T09:49:59+01:00 rts/linker: Fix out-of-bounds mapping logic Previously the structure of `mmapInRegion` concealed a subtle bug concerning handling of `mmap` returning mappings below the beginning of the desired region. Specifically, we would reset `p = result + bytes` and then again reset `p = region->start` before looping around for another iteration. This resulted in an infinite loop on FreeBSD. Fixes #25492. (cherry picked from commit 292ed74ea908b64490e91346b890cbebdcde37d0) - - - - - e118f013 by Ben Gamari at 2025-01-16T09:49:59+01:00 rts/linker: Clarify debug output (cherry picked from commit 20912f5bac6fe4146172accc1849d9b762eb45e3) - - - - - b9ab7244 by Ben Gamari at 2025-01-16T09:49:59+01:00 rts(setNumCapabilities): Assert that n_caps < MAX_N_CAPS It was noticed in #25560 that this would previously be allowed, resulting in a segfault. I will add a proper exception in `base` in a future commit. (cherry picked from commit f08a72eb484193934c56e34366b277f4d7247a24) - - - - - 686b07e6 by Ben Gamari at 2025-01-16T09:49:59+01:00 ghc-internal: Fix inconsistent FFI import types The foreign imports of `enabled_capabilities` and `getNumberOfProcessors` were declared as `CInt` whereas they are defined as `uint32_t`. (cherry picked from commit e10d31ad849b5f7c1f052e7c93f7c7aaf85918c9) - - - - - 5c86fbe7 by Ben Gamari at 2025-01-16T09:49:59+01:00 rts: Mention maximum capability count in users guide Addresses #25560. (cherry picked from commit 06265655bfe6b48cde6923a933d81c9889a443a3) - - - - - 8703a14a by Ben Gamari at 2025-01-16T09:49:59+01:00 rts/Capability: Move induction variable declaration into `for`s Just a stylistic change. (cherry picked from commit d488470ba302760cfd2f3515d9338d1d75f84dd5) - - - - - 258c0cf5 by Ben Gamari at 2025-01-16T09:49:59+01:00 rts: Determine max_n_capabilities at RTS startup Previously the maximum number of capabilities supported by the RTS was statically capped at 256. However, this bound is uncomfortably low given the size of today's machine. While supporting unbounded, fully-dynamic adjustment would be nice, it is complex and so instead we do something simpler: Probe the logical core count at RTS startup and use this as the static bound for the rest of our execution. This should avoid users running into the capability limit on large machines while avoiding wasting memory on a large capabilities array for most users and keeping complexity at bay. Addresses #25560. (cherry picked from commit 71f050b74eaa2fdc2ca5da53f85497ac94ab6a2a) - - - - - fd2f2b9b by Ben Gamari at 2025-01-16T09:49:59+01:00 testsuite: Introduce req_c_rts As suggested by @hsyl20, this is intended to mark tests that rely on the behavior of the C RTS. (cherry picked from commit 1e84b41108d96cb721dd11281105fdf621105a12) - - - - - e03165b2 by Ben Gamari at 2025-01-16T09:49:59+01:00 testsuite: Add test for #25560 (cherry picked from commit 683115a40fd989a287fa51efe140af9448526098) - - - - - 6233f3ec by Zubin Duggal at 2025-01-16T09:49:59+01:00 release-ci: remove release-x86_64-linux-deb11-release+boot_nonmoving_gc job There is no reason to have this release build or distribute this variation. This configuration is for testing purposes only. (cherry picked from commit 13503451dc7661ca392e758396449d17ce196283) - - - - - 611c6ef6 by Ben Gamari at 2025-01-16T09:49:59+01:00 ghci: Don't rely on Uniques in BRK_FUN This is a partial backport of the treatment given to modules names in !10448, removing the dependence of BRK_FUN on the representation of `Unique`. (cherry picked from commit ea2ea2d58c6d3b8b80becfe89f5ca23ee82235de) - - - - - 9fe9c3ea by Luite Stegeman at 2025-01-16T09:49:59+01:00 bump version to 9.6.7 - - - - - 0c16eef4 by Jaro Reinders at 2025-01-16T09:49:59+01:00 Refactor Unique to be represented by Word64 In #22010 we established that Int was not always sufficient to store all the uniques we generate during compilation on 32-bit platforms. This commit addresses that problem by using Word64 instead of Int for uniques. The core of the change is in GHC.Core.Types.Unique and GHC.Core.Types.Unique.Supply. However, the representation of uniques is used in many other places, so those needed changes too. Additionally, the RTS has been extended with an atomic_inc64 operation. One major change from this commit is the introduction of the Word64Set and Word64Map data types. These are adapted versions of IntSet and IntMap from the containers package. These are planned to be upstreamed in the future. As a natural consequence of these changes, the compiler will be a bit slower and take more space on 32-bit platforms. Our CI tests indicate around a 5% residency increase. Metric Increase: CoOpt_Read CoOpt_Singletons LargeRecord ManyAlternatives ManyConstructors MultiComponentModules MultiComponentModulesRecomp MultiLayerModulesTH_OneShot RecordUpdPerf T10421 T10547 T12150 T12227 T12234 T12425 T12707 T13035 T13056 T13253 T13253-spj T13379 T13386 T13719 T14683 T14697 T14766 T15164 T15703 T16577 T16875 T17516 T18140 T18223 T18282 T18304 T18698a T18698b T18923 T1969 T19695 T20049 T21839c T3064 T3294 T4801 T5030 T5321FD T5321Fun T5631 T5642 T5837 T6048 T783 T8095 T9020 T9198 T9233 T9630 T9675 T9872a T9872b T9872b_defer T9872c T9872d T9961 TcPlugin_RewritePerf UniqLoop WWRec hard_hole_fits MultiLayerModulesTH_Make T21839r mhu-perf Metric Decrease: MultiLayerModulesTH_Make (cherry picked from commit 9edcb1fb02d799acd4a7d0c145796aecb6e54ea3) - - - - - 20e54e46 by Matthew Pickering at 2025-01-16T09:49:59+01:00 compiler: Remove unused `containers.h` include Fixes #23712 (cherry picked from commit 02e6a6ceac761d62ed30817b9525d952bca599ac) - - - - - 79d45d15 by Matthew Pickering at 2025-01-16T09:49:59+01:00 ghcup-metadata: Add dlOutput field ghcup now requires us to add this field which specifies where it should download the bindist to. See https://gitlab.haskell.org/ghc/ghcup-metadata/-/issues/1 for some more discussion. (cherry picked from commit bc478bee6e7e46bcf30212ab94545a83bdeb0203) - - - - - 795e225a by Ben Gamari at 2025-01-16T09:49:59+01:00 ghcup-metadata: Don't populate dlOutput unless necessary ghcup can apparently infer the output name of an artifact from its URL. Consequently, we should only include the `dlOutput` field when it would differ from the filename of `dlUri`. Fixes #24547. (cherry picked from commit 6d398066b6084a971248da8ce37bc40c53a83525) - - - - - 70ba59d0 by Ben Gamari at 2025-01-16T09:49:59+01:00 mk-ghcup-metadata: Fix directory of testsuite tarball As reported in #24546, the `dlTest` artifact should be extracted into the `testsuite` directory. (cherry picked from commit 9d936c5799daadf96392211b03e38520925aea17) - - - - - d3f1c038 by Ben Gamari at 2025-01-16T09:49:59+01:00 hadrian: Set -this-package-name When constructing the GHC flags for a package Hadrian must take care to set `-this-package-name` in addition to `-this-unit-id`. This hasn't broken until now as we have not had any uses of qualified package imports. However, this will change with `filepath-1.5` and the corresponding `unix` bump, breaking `hadrian/multi-ghci`. (cherry picked from commit d7ee12ead407718ae757d6ff4eeaabbe41aa29ad) - - - - - 9f9a3b26 by ARATA Mizuki at 2025-01-16T09:49:59+01:00 Fix LLVM version detection With a recent LLVM, `llc -version` emits the version on the first line if the vendor is set. It emits the version on the second line otherwise. Therefore, we need to check the both lines to detect the version. GHC now emits a warning if it fails to detect the LLVM version, so we can notice if the output of `llc -version` changes in the future. Also, the warning for using LLVM < 10 on s390x is removed, because we assume LLVM >= 13 now. This fixes the definition of __GLASGOW_HASKELL_LLVM__ macro. Fixes #25606 (cherry picked from commit a928c326011f1a6bef3289a4c36d4e19b5951229) - - - - - b44c46a2 by Luite Stegeman at 2025-01-16T09:49:59+01:00 Add flags for switching off speculative evaluation. We found that speculative evaluation can increase the amount of allocations in some circumstances. This patch adds new flags for selectively disabling speculative evaluation, allowing us to test the effect of the optimization. The new flags are: -fspec-eval globally enable speculative evaluation -fspec-eval-dictfun enable speculative evaluation for dictionary functions (no effect if speculative evaluation is globally disabled) The new flags are on by default for all optimisation levels. See #25284 (cherry picked from commit 2309975247543a4f77009ea5c3c7a8ebe06dc60b) - - - - - 0e2dfdc2 by Luite Stegeman at 2025-01-16T09:49:59+01:00 hadrian/CI: don't fail on unused imports in filepath package this allows us to update the filepath submodule - - - - - 1b9bf605 by Luite Stegeman at 2025-01-16T09:49:59+01:00 Bump bytestring submodule to 0.11.5.4 - - - - - 0d21b8a2 by Andrew Lelechenko at 2025-01-16T09:49:59+01:00 Bump submodule array to 0.5.8.0 (cherry picked from commit 80769bc9f56541601796366485283a697c52a18b) - - - - - 43cd9ed2 by Luite Stegeman at 2025-01-16T09:49:59+01:00 Bump unix submodule to 2.8.6.0 - - - - - 92e22bdc by Luite Stegeman at 2025-01-16T09:49:59+01:00 Bump submodule filepath to 1.4.301.0 - - - - - 3574768a by Matthew Pickering at 2025-01-17T13:31:06+01:00 ci: Add nightly & release ubuntu-22.04 jobs This adds build of bindists on ubuntu-22.04 on nightly and release pipelines. We also update ghcup-metadata to provide ubuntu-22.04 bindists on ubuntu-22.04. Fixes #25317 (cherry picked from commit 504900755e3297c000a3bcf4f20eaae1f10298f4) - - - - - 0da317a1 by Luite Stegeman at 2025-01-20T05:39:34+01:00 libraries/base: bump base version and update changelog - - - - - 61d41711 by Andreas Klebinger at 2025-01-20T05:39:34+01:00 Compacting GC: Handle black holes in large objects. As #14497 showed black holes can appear inside large objects when we capture a computation and later blackhole it like we do for AP_STACK closures. Fixes #24791 (cherry picked from commit 6cee2272f75edcd85cb950e98d1d390964f17add) - - - - - 24d82823 by Zubin Duggal at 2025-01-27T02:55:36+01:00 ghcup metadata: output metadata fragment in CI (cherry picked from commit 52b58a660e735b20961d792d8fa9267f01247a50) - - - - - f196f1fe by Zubin Duggal at 2025-01-27T02:55:36+01:00 ghcup metatdata: use fedora33 for redhat Redhat 9 doesn't have libtinfo.so.5 anymore (cherry picked from commit dc86785eb43afd1bd292287c064fb5ad94fe8c7f) - - - - - a44d7518 by Zubin Duggal at 2025-01-27T02:55:36+01:00 ghcup metadata: still use centos for redhat <9 (cherry picked from commit 660b17ae6a52cbca94e15cb4e1d96f8ef9aa5a54) - - - - - 50e7fc9d by Zubin Duggal at 2025-01-27T02:55:36+01:00 rel-eng: ghcup metadata generation: generated yaml anchors with meaningful names (cherry picked from commit 9084fc8824b6ec53c3fabf82b22f2c93933d01ff) - - - - - ef6261f5 by Luite Stegeman at 2025-01-27T02:55:36+01:00 CI: run ghc-in-ghci job through ci.sh to get the correct environment This ensures that CABAL_DIR and HOME are set correctly, fixing a problem where the hackage index state wasn't picked up. - - - - - 72b36c8a by Luite Stegeman at 2025-01-27T02:55:36+01:00 CI: allow both lower and upper bounds for the happy version This fixes CI when newer-than-supported happy is available in the package index. - - - - - 648ed53f by Luite Stegeman at 2025-01-27T02:55:36+01:00 hadrian: Bump directory bound to >=1.3.9 Earlier versions of `directory` are racy on Windows due to #24382. Also includes necessary Hadrian bootstrap plan bump. Fixes #24382. based on commit 9ad346ec8bfa22a2843f8d2c8d998133d0715702 - - - - - d293481a by Zubin Duggal at 2025-01-27T02:55:36+01:00 release: copy index.html from correct directory (cherry picked from commit cbfd0829cd61928976c9eb17ba4af18272466063) - - - - - af3e9b37 by Cheng Shao at 2025-01-27T02:55:36+01:00 ghc-bignum: update gmp to 6.3.0 This patch bumps the gmp-tarballs submodule and updates gmp to 6.3.0. The tarball format is now xz, and gmpsrc.patch has been patched into the tarball so hadrian no longer needs to deal with patching logic when building in-tree GMP. (cherry picked from commit 6399d52ba10d510a94c9db6552a4ea8aae8e003b) - - - - - a38a8838 by Luite Stegeman at 2025-01-27T02:55:36+01:00 Update autoconf scripts Scripts taken from autoconf [00b15927496058d23e6258a28d8996f87cf1f191][1]. [1]: https://git.savannah.gnu.org/cgit/config.git/commit/?id=00b15927496058d23e6258a28d8996f87cf1f191 - - - - - 9962117e by Luite Stegeman at 2025-01-27T02:55:36+01:00 add 9.6.7 release notes - - - - - c43b4373 by Luite Stegeman at 2025-01-27T02:55:36+01:00 update CI images - - - - - 9ba693cb by Luite Stegeman at 2025-01-27T02:55:36+01:00 hadrian: don't pass -this-package-name to GHC 9.2 it's not supported - - - - - 4f593930 by Sylvain Henry at 2025-01-27T02:55:36+01:00 JS: fake support for native adjustors (#25159) The JS backend doesn't support adjustors (I believe) and in any case if it ever supports them it will be a native support, not one via libffi. (cherry picked from commit 03055c71446c8f1265de3a6ccb5bc9e09827821e) - - - - - f7c7f0c2 by Matthew Pickering at 2025-01-27T02:55:36+01:00 hadrian: Make sure ffi headers are built before using a compiler When we are using ffi adjustors then we rely on `ffi.h` and `ffitarget.h` files during code generation when compiling stubs. Therefore we need to add this dependency to the build system (which this patch does). Reproducer, configure with `--enable-libffi-adjustors` and then build "_build/stage1/libraries/ghc-prim/build/GHC/Types.p_o". Observe that this fails before this patch and works afterwards. Fixes #24864 Co-authored-by: Sylvain Henry <sylvain at haskus.fr> (cherry picked from commit 0167e472e7035d31591777983d8e35528aceefff) - - - - - 254defb9 by Luite Stegeman at 2025-01-28T03:24:41+01:00 add workaround for incorrect build ordering this should fix CI failures mentioning missing files in the ghc-bignum package see #23942 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/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/Types/Prim.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/ByteCode/Instr.hs - compiler/GHC/ByteCode/Types.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/Dominators.hs - compiler/GHC/Cmm/LRegSet.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/CmmToAsm/AArch64/Instr.hs - compiler/GHC/CmmToAsm/AArch64/Ppr.hs - compiler/GHC/CmmToAsm/AArch64/Regs.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/CFG/Dominators.hs - compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs - compiler/GHC/CmmToAsm/Wasm/Asm.hs - compiler/GHC/CmmToAsm/Wasm/FromCmm.hs - compiler/GHC/CmmToAsm/Wasm/Types.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a18c0fa2edcd61b0c3b470661791b09501c4c2b...254defb9fc0a3aff38d0b10c482fbeb2009d7637 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a18c0fa2edcd61b0c3b470661791b09501c4c2b...254defb9fc0a3aff38d0b10c482fbeb2009d7637 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 10:27:11 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 30 Jan 2025 05:27:11 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25675 Message-ID: <679b53ffc179e_89c2153352c52633@gitlab.mail> Simon Peyton Jones pushed new branch wip/T25675 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25675 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 10:48:14 2025 From: gitlab at gitlab.haskell.org (Simon Peyton Jones (@simonpj)) Date: Thu, 30 Jan 2025 05:48:14 -0500 Subject: [Git][ghc/ghc][wip/T25675] Deal correctly with Given CallStack constraints Message-ID: <679b58ee1bc82_89c21abefdc57772@gitlab.mail> Simon Peyton Jones pushed to branch wip/T25675 at Glasgow Haskell Compiler / GHC Commits: bcb23bb0 by Simon Peyton Jones at 2025-01-30T10:47:49+00:00 Deal correctly with Given CallStack constraints As #25675 showed, the CallStack solving mechanism was failing to account for Given CallStack constraints. This small patch fixes it and improves the Notes. - - - - - 7 changed files: - compiler/GHC/Tc/Solver/Dict.hs - compiler/GHC/Tc/Solver/Types.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Types/Origin.hs - + testsuite/tests/profiling/should_run/T25675.hs - + testsuite/tests/profiling/should_run/T25675.stdout - testsuite/tests/profiling/should_run/all.T Changes: ===================================== compiler/GHC/Tc/Solver/Dict.hs ===================================== @@ -140,7 +140,7 @@ canDictCt ev cls tys | CtWanted { ctev_rewriters = rewriters } <- ev , Just ip_name <- isCallStackPred cls tys - , isPushCallStackOrigin orig + , Just fun_fs <- isPushCallStackOrigin_maybe orig -- If we're given a CallStack constraint that arose from a function -- call, we need to push the current call-site onto the stack instead -- of solving it directly from a given. @@ -159,8 +159,7 @@ canDictCt ev cls tys -- Then we solve the wanted by pushing the call-site -- onto the newly emitted CallStack - ; let ev_cs = EvCsPushCall (callStackOriginFS orig) - (ctLocSpan loc) (ctEvExpr new_ev) + ; let ev_cs = EvCsPushCall fun_fs (ctLocSpan loc) (ctEvExpr new_ev) ; solveCallStack ev ev_cs ; continueWith (DictCt { di_ev = new_ev, di_cls = cls ===================================== compiler/GHC/Tc/Solver/Types.hs ===================================== @@ -134,7 +134,7 @@ emptyDictMap = emptyTcAppMap findDict :: DictMap a -> CtLoc -> Class -> [Type] -> Maybe a findDict m loc cls tys | Just {} <- isCallStackPred cls tys - , isPushCallStackOrigin (ctLocOrigin loc) + , Just {} <- isPushCallStackOrigin_maybe (ctLocOrigin loc) = Nothing -- See Note [Solving CallStack constraints] | otherwise @@ -156,7 +156,7 @@ foldDicts = foldTcAppMap {- Note [Solving CallStack constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -See also Note [Overview of implicit CallStacks] in GHc.Tc.Types.Evidence. +See Note [Overview of implicit CallStacks] in GHc.Tc.Types.Evidence. Suppose f :: HasCallStack => blah. Then ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -655,7 +655,6 @@ Conclusion: a new wanted coercion variable should be made mutable. [Notice though that evidence variables that bind coercion terms from super classes will be "given" and hence rigid] - Note [Overview of implicit CallStacks] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (See https://gitlab.haskell.org/ghc/ghc/wikis/explicit-call-stack/implicit-locations) @@ -667,12 +666,13 @@ to constraints of type GHC.Stack.Types.HasCallStack, an alias type HasCallStack = (?callStack :: CallStack) -Implicit parameters of type GHC.Stack.Types.CallStack (the name is not -important) are solved in three steps: +Implicit parameters of type GHC.Stack.Types.CallStack (the /name/ of the +implicit parameter is not important, see (CS5) below) are solved as follows: -1. Explicit, user-written occurrences of `?stk :: CallStack` - which have IPOccOrigin, are solved directly from the given IP, - just like a regular IP; see GHC.Tc.Solver.Dict.tryInertDicts. +1. Plan NORMAL. Explicit, user-written occurrences of `?stk :: CallStack`, which + have IPOccOrigin, are solved directly from the given IP, just like any other + implicit-parameter constraint; see GHC.Tc.Solver.Dict.tryInertDicts. We can + solve it from a Given or from another Wanted, if the two have the same type. For example, the occurrence of `?stk` in @@ -681,44 +681,35 @@ important) are solved in three steps: will be solved for the `?stk` in `error`s context as before. -2. In a function call, instead of simply passing the given IP, we first - append the current call-site to it. For example, consider a - call to the callstack-aware `error` above. - - foo :: (?stk :: CallStack) => a - foo = error "undefined!" - - Here we want to take the given `?stk` and append the current - call-site, before passing it to `error`. In essence, we want to - rewrite `foo "undefined!"` to +2. Plan PUSH. A /function call/ with a CallStack constraint, such as + a call to `foo` where + foo :: (?stk :: CallStack) => a + will give rise to a Wanted constraint + [W] d :: (?stk :: CallStack) CtOrigin = OccurrenceOf "foo" - let ?stk = pushCallStack ?stk - in foo "undefined!" + We do /not/ solve this constraint from Givens, or from other + Wanteds. Rather, have a built-in mechanism in that solves it thus: + d := EvCsPushCall "foo"
d2 + [W] d2 :: (?stk :: CallStack) CtOrigin = IPOccOrigin - We achieve this as follows: + That is, `d` is a call-stack that has the `foo` call-site pushed on top of + `d2`, which can now be solved normally (as in (1) above). This is done in two + places: + - In GHC.Tc.Solver.Dict.canDictNC we do the pushing. + - In GHC.Tc.Solver.Types.findDict we arrrange /not/ to solve a plan-PUSH + constraint by forcing a "miss" in the lookup in the inert set - * At a call of foo :: (?stk :: CallStack) => blah - we emit a Wanted - [W] d1 : IP "stk" CallStack - with CtOrigin = OccurrenceOf "foo" +3. For a CallStack constraint, we choose how to solve it based on its CtOrigin: - * We /solve/ this constraint, in GHC.Tc.Solver.Dict.canDictNC - by emitting a NEW Wanted - [W] d2 :: IP "stk" CallStack - with CtOrigin = IPOccOrigin + * solve it normally (plan NORMAL above) + - IPOccOrigin (discussed above) + - GivenOrigin (see (CS1) below) - and solve d1 = EvCsPushCall "foo" (EvId d1) + * push an item on the stack and emit a new constraint (plan PUSH above) + - OccurrenceOf "foo" (discused above) + - anything else (see (CS1) below) - * The new Wanted, for `d2` will be solved per rule (1), ie as a regular IP. - -3. We use the predicate isPushCallStackOrigin to identify whether we - want to do (1) solve directly, or (2) push and then solve directly. - Key point (see #19918): the CtOrigin where we want to push an item on the - call stack can include IfThenElseOrigin etc, when RebindableSyntax is - involved. See the defn of fun_orig in GHC.Tc.Gen.App.tcInstFun; it is - this CtOrigin that is pinned on the constraints generated by functions - in the "expansion" for rebindable syntax. c.f. GHC.Rename.Expr - Note [Handling overloaded and rebindable constructs] + This choice is by the predicate isPushCallStackOrigin_maybe 4. We default any insoluble CallStacks to the empty CallStack. Suppose `undefined` did not request a CallStack, ie @@ -754,21 +745,38 @@ and the call to `error` in `undefined`, but *not* the call to `head` in `g`, because `head` did not explicitly request a CallStack. -Important Details: -- GHC should NEVER report an insoluble CallStack constraint. +Wrinkles + +(CS1) Which CtOrigins should qualify for plan PUSH? Certainly ones that arise + from a function call like (f a b). -- GHC should NEVER infer a CallStack constraint unless one was requested + But (see #19918) when RebindableSyntax is involved we can function call whose + CtOrigin is somethign like `IfThenElseOrigin`. See the defn of fun_orig in + GHC.Tc.Gen.App.tcInstFun; it is this CtOrigin that is pinned on the + constraints generated by functions in the "expansion" for rebindable + syntax. c.f. GHC.Rename.Expr Note [Handling overloaded and rebindable + constructs]. + + So isPushCallStackOrigin_maybe has a fall-through for "anything else", and + assumes that we should adopt plan PUSH for it. + + However we should /not/ take this fall-through for Given constraints + (#25675). So isPushCallStackOrigin_maybe identifies Givens as plan NORMAL. + +(CS2) GHC should NEVER report an insoluble CallStack constraint. + +(CS3) GHC should NEVER infer a CallStack constraint unless one was requested with a partial type signature (See GHC.Tc.Solver..pickQuantifiablePreds). -- A CallStack (defined in GHC.Stack.Types) is a [(String, SrcLoc)], +(CS4)- A CallStack (defined in GHC.Stack.Types) is a [(String, SrcLoc)], where the String is the name of the binder that is used at the SrcLoc. SrcLoc is also defined in GHC.Stack.Types and contains the package/module/file name, as well as the full source-span. Both CallStack and SrcLoc are kept abstract so only GHC can construct new values. -- We will automatically solve any wanted CallStack regardless of the - name of the IP, i.e. +(CS5) We will automatically solve any wanted CallStack regardless of the + /name/ of the IP, i.e. f = show (?stk :: CallStack) g = show (?loc :: CallStack) @@ -782,17 +790,16 @@ Important Details: the printed CallStack will NOT include head's call-site. This reflects the standard scoping rules of implicit-parameters. -- An EvCallStack term desugars to a CoreExpr of type `IP "some str" CallStack`. +(CS6) An EvCallStack term desugars to a CoreExpr of type `IP "some str" CallStack`. The desugarer will need to unwrap the IP newtype before pushing a new call-site onto a given stack (See GHC.HsToCore.Binds.dsEvCallStack) -- When we emit a new wanted CallStack from rule (2) we set its origin to +(CS7) When we emit a new wanted CallStack in plan PUSH we set its origin to `IPOccOrigin ip_name` instead of the original `OccurrenceOf func` (see GHC.Tc.Solver.Dict.tryInertDicts). This is a bit shady, but is how we ensure that the new wanted is solved like a regular IP. - -} mkEvCast :: EvExpr -> TcCoercion -> EvTerm ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -27,7 +27,7 @@ module GHC.Tc.Types.Origin ( TypedThing(..), TyVarBndrs(..), -- * CallStack - isPushCallStackOrigin, callStackOriginFS, + isPushCallStackOrigin_maybe, -- * FixedRuntimeRep origin FixedRuntimeRepOrigin(..), @@ -983,18 +983,19 @@ pprNonLinearPatternReason OtherPatternReason = empty * * ********************************************************************* -} -isPushCallStackOrigin :: CtOrigin -> Bool --- Do we want to solve this IP constraint directly (return False) +isPushCallStackOrigin_maybe :: CtOrigin -> Maybe FastString +-- Do we want to solve this IP constraint normally (return Nothing) -- or push the call site (return True) --- See Note [Overview of implicit CallStacks] in GHc.Tc.Types.Evidence -isPushCallStackOrigin (IPOccOrigin {}) = False -isPushCallStackOrigin _ = True - - -callStackOriginFS :: CtOrigin -> FastString --- This is the string that appears in the CallStack -callStackOriginFS (OccurrenceOf fun) = occNameFS (getOccName fun) -callStackOriginFS orig = mkFastString (showSDocUnsafe (pprCtO orig)) +-- See Note [Overview of implicit CallStacks] esp (CS1) in GHC.Tc.Types.Evidence +isPushCallStackOrigin_maybe (GivenOrigin {}) = Nothing +isPushCallStackOrigin_maybe (GivenSCOrigin {}) = Nothing +isPushCallStackOrigin_maybe (IPOccOrigin {}) = Nothing +isPushCallStackOrigin_maybe (OccurrenceOf fun) = Just (occNameFS (getOccName fun)) +isPushCallStackOrigin_maybe orig = Just orig_fs + -- This fall-through case is important to deal with call stacks + -- that arise from rebindable syntax (#19919) + where + orig_fs = mkFastString (showSDocUnsafe (pprCtO orig)) {- ************************************************************************ ===================================== testsuite/tests/profiling/should_run/T25675.hs ===================================== @@ -0,0 +1,21 @@ +{-# LANGUAGE ImplicitParams #-} + +module Main where + +import Data.Maybe +import Debug.Trace +import GHC.IsList +import GHC.Stack + +hd (c:cs) = c +hd [] = error "urk" + +what :: (HasCallStack) => Int +what = + let cs = getCallStack callStack + in srcLocStartCol (snd (hd cs)) + +main :: IO () +main = + let ?callStack = fromList [] + in print (what, what) ===================================== testsuite/tests/profiling/should_run/T25675.stdout ===================================== @@ -0,0 +1 @@ +(14,20) ===================================== testsuite/tests/profiling/should_run/all.T ===================================== @@ -232,3 +232,5 @@ test('scc-prof-overloaded-calls002', # Need optimizations to get rid of unwanted overloaded calls ['-O -fno-prof-auto -fprof-late-overloaded-calls'] ) + +test('T25675', [], compile_and_run, ['-dcore-lint']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bcb23bb07d85b83ba055218c63a1c959ccc0e9db -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bcb23bb07d85b83ba055218c63a1c959ccc0e9db You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 11:37:17 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 30 Jan 2025 06:37:17 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/romes/25170-idea4 Message-ID: <679b646de2c99_abd71547f7c785a5@gitlab.mail> Rodrigo Mesquita pushed new branch wip/romes/25170-idea4 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/25170-idea4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 12:01:17 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 30 Jan 2025 07:01:17 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/generic-length Message-ID: <679b6a0da5472_abd71b02c64973e2@gitlab.mail> Matthew Pickering pushed new branch wip/generic-length at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/generic-length You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 14:35:55 2025 From: gitlab at gitlab.haskell.org (Rodrigo Mesquita (@alt-romes)) Date: Thu, 30 Jan 2025 09:35:55 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/romes/25170-idea5 Message-ID: <679b8e4bceca0_ebac8b0e794994a7@gitlab.mail> Rodrigo Mesquita pushed new branch wip/romes/25170-idea5 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/25170-idea5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 15:59:33 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Thu, 30 Jan 2025 10:59:33 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/spec-assembler Message-ID: <679ba1e567399_ebac81d1698c1243ea@gitlab.mail> Matthew Pickering pushed new branch wip/spec-assembler at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/spec-assembler You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 18:25:13 2025 From: gitlab at gitlab.haskell.org (Torsten Schmits (@torsten.schmits)) Date: Thu, 30 Jan 2025 13:25:13 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/torsten.schmits/cross-package-objects-old Message-ID: <679bc409aa4e2_1385e113d218c900f4@gitlab.mail> Torsten Schmits pushed new branch wip/torsten.schmits/cross-package-objects-old at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/torsten.schmits/cross-package-objects-old You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 19:06:12 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 30 Jan 2025 14:06:12 -0500 Subject: [Git][ghc/ghc][wip/backports-9.12] upload-ghc-libs: Drop more references to ghc-internal from ghc-boot-th Message-ID: <679bcda441c90_1385e1189856892456@gitlab.mail> Ben Gamari pushed to branch wip/backports-9.12 at Glasgow Haskell Compiler / GHC Commits: afec4b75 by Ben Gamari at 2025-01-30T14:05:41-05:00 upload-ghc-libs: Drop more references to ghc-internal from ghc-boot-th - - - - - 1 changed file: - .gitlab/rel_eng/upload_ghc_libs.py Changes: ===================================== .gitlab/rel_eng/upload_ghc_libs.py ===================================== @@ -94,9 +94,23 @@ def prep_ghc(): build_copy_file(PACKAGES['ghc'], 'GHC/Settings/Config.hs') def prep_ghc_boot_th(): - # Drop ghc-internal from `hs-source-dirs` as Hackage rejects this + # Drop references to `ghc-internal` from `hs-source-dirs` as Hackage rejects + # out-of-sdist references and this packages is only uploaded for documentation + # purposes. modify_file(PACKAGES['ghc-boot-th'], 'ghc-boot-th.cabal', - lambda s: s.replace('../ghc-internal/src', '')) + lambda s: s.replace('../ghc-internal/src', '') + .replace('GHC.Internal.TH.Lib.Map', '') + .replace('GHC.Internal.TH.PprLib', '') + .replace('GHC.Internal.TH.Ppr', '') + .replace('GHC.Internal.TH.Lib,', '') + .replace('GHC.Internal.TH.Lib', '') + .replace('GHC.Internal.TH.Lift,', '') + .replace('GHC.Internal.TH.Quote,', '') + .replace('GHC.Internal.TH.Syntax', '') + .replace('GHC.Internal.ForeignSrcLang', '') + .replace('GHC.Internal.LanguageExtensions', '') + .replace('GHC.Internal.Lexeme', '') + ) PACKAGES = { pkg.name: pkg View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/afec4b75c2d0e9f5c462a86d9f3697acf30355c7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/afec4b75c2d0e9f5c462a86d9f3697acf30355c7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 19:10:02 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 30 Jan 2025 14:10:02 -0500 Subject: [Git][ghc/ghc] Pushed new branch cherry-pick-afec4b75 Message-ID: <679bce8aa2b96_1385e11ad00ec94014@gitlab.mail> Ben Gamari pushed new branch cherry-pick-afec4b75 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/cherry-pick-afec4b75 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 19:56:29 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 30 Jan 2025 14:56:29 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/ghc-9.10.2-submodules Message-ID: <679bd96d9bd76_1385e1256d3d8102619@gitlab.mail> Ben Gamari pushed new branch wip/ghc-9.10.2-submodules at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghc-9.10.2-submodules You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 21:05:35 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 30 Jan 2025 16:05:35 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.10.2-submodules] 10 commits: filepath: Bump to 1.5.4.0 Message-ID: <679be99fcd86c_1a8309c140845664@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10.2-submodules at Glasgow Haskell Compiler / GHC Commits: e4c7dbda by Ben Gamari at 2025-01-30T16:03:34-05:00 filepath: Bump to 1.5.4.0 - - - - - 042008c0 by Ben Gamari at 2025-01-30T16:03:34-05:00 hpc: Bump to 0.7.0.2 - - - - - cef02bdd by Ben Gamari at 2025-01-30T16:03:34-05:00 parsec: Bump to 3.1.18.0 - - - - - 6a7003a2 by Ben Gamari at 2025-01-30T16:03:34-05:00 process: Bump to 1.6.25.0 - - - - - 5bef1a53 by Ben Gamari at 2025-01-30T16:03:34-05:00 terminfo: Bump to 0.4.1.7 - - - - - 7658be09 by Ben Gamari at 2025-01-30T16:03:34-05:00 text: Bump to 2.1.2 - - - - - 8be194f3 by Ben Gamari at 2025-01-30T16:03:34-05:00 unix: Bump to 2.8.6.0 - - - - - 1849fc14 by Ben Gamari at 2025-01-30T16:03:34-05:00 exceptions: Bump to 0.10.9 - - - - - 8f9b73fb by Ben Gamari at 2025-01-30T16:03:34-05:00 Win32: Bump to 2.14.1.0 - - - - - f99228ef by Ben Gamari at 2025-01-30T16:05:03-05:00 directory: Bump to 1.3.8.5 - - - - - 10 changed files: - libraries/Win32 - libraries/directory - libraries/exceptions - libraries/filepath - libraries/hpc - libraries/parsec - libraries/process - libraries/terminfo - libraries/text - libraries/unix Changes: ===================================== libraries/Win32 ===================================== @@ -1 +1 @@ -Subproject commit 350ebd43f9a8d9e1ca767b0000f95bdfb42a5471 +Subproject commit 027cbcf0de25d681823ea92fb545a2604c3a6a8b ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit e8ee4d5565ec82272ca612034ba6029993e23fd0 ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit d9fba07b664e3c48f011baca1a8a204292ca2722 +Subproject commit 0b6abb3ac433c7d1d5c6f6a5a45b37f7c486e33b ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 87a09e296ea6fc137a0b32edda1bd0f54332642e +Subproject commit 65b0f8f31aac4a306135e27734988327f8eb1e6f ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 +Subproject commit 37c56cf932e429950a199d0b1f39796677b052c5 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 +Subproject commit b87122c1c74b8240e65044a8f600f0427d4dd9c3 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit dfbe62c7d9fc84d2550fc7e7db993dc0aa143ef5 +Subproject commit a5a3865df6ff36358fdc987d3c860d2970993c06 ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 500399a1497dfe1786ba67d6d2bfced4832f3fed +Subproject commit 788ce671cb1cec54c3c9b3ac1c1ba189e8424819 ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit cdb9e13b39079904eed9d75cd332b66ee0cad0c0 +Subproject commit ee0a8f8b9a4bd3fdad23e9ac0db56e7f08ce35cd ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 +Subproject commit 6be36ed54cc035c0f095d24bf3a451638d45513c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/321f8e25c14a3babe28b269cceb324b125bd0b30...f99228ef8a272e1a73a0b2e172c0ec65909492e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/321f8e25c14a3babe28b269cceb324b125bd0b30...f99228ef8a272e1a73a0b2e172c0ec65909492e2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 22:22:24 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Thu, 30 Jan 2025 17:22:24 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.10.2-submodules] 10 commits: filepath: Bump to 1.5.4.0 Message-ID: <679bfba0b1931_1a8309fd87845120@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10.2-submodules at Glasgow Haskell Compiler / GHC Commits: 7b39edfd by Ben Gamari at 2025-01-30T17:22:00-05:00 filepath: Bump to 1.5.4.0 - - - - - 7963503e by Ben Gamari at 2025-01-30T17:22:00-05:00 hpc: Bump to 0.7.0.2 - - - - - f39e1b98 by Ben Gamari at 2025-01-30T17:22:00-05:00 parsec: Bump to 3.1.18.0 - - - - - d7e864f9 by Ben Gamari at 2025-01-30T17:22:01-05:00 process: Bump to 1.6.25.0 - - - - - 51c51eaf by Ben Gamari at 2025-01-30T17:22:01-05:00 terminfo: Bump to 0.4.1.7 - - - - - 97e39773 by Ben Gamari at 2025-01-30T17:22:01-05:00 text: Bump to 2.1.2 - - - - - df6eae2e by Ben Gamari at 2025-01-30T17:22:01-05:00 unix: Bump to 2.8.6.0 - - - - - 6b5c1517 by Ben Gamari at 2025-01-30T17:22:01-05:00 exceptions: Bump to 0.10.9 - - - - - 8ed46cda by Ben Gamari at 2025-01-30T17:22:01-05:00 Win32: Bump to 2.14.1.0 - - - - - fbc80375 by Ben Gamari at 2025-01-30T17:22:01-05:00 directory: Bump to 1.3.8.5 - - - - - 10 changed files: - libraries/Win32 - libraries/directory - libraries/exceptions - libraries/filepath - libraries/hpc - libraries/parsec - libraries/process - libraries/terminfo - libraries/text - libraries/unix Changes: ===================================== libraries/Win32 ===================================== @@ -1 +1 @@ -Subproject commit 350ebd43f9a8d9e1ca767b0000f95bdfb42a5471 +Subproject commit 027cbcf0de25d681823ea92fb545a2604c3a6a8b ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit e8ee4d5565ec82272ca612034ba6029993e23fd0 ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit d9fba07b664e3c48f011baca1a8a204292ca2722 +Subproject commit 0b6abb3ac433c7d1d5c6f6a5a45b37f7c486e33b ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 87a09e296ea6fc137a0b32edda1bd0f54332642e +Subproject commit 65b0f8f31aac4a306135e27734988327f8eb1e6f ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 +Subproject commit 37c56cf932e429950a199d0b1f39796677b052c5 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 +Subproject commit b87122c1c74b8240e65044a8f600f0427d4dd9c3 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit dfbe62c7d9fc84d2550fc7e7db993dc0aa143ef5 +Subproject commit a5a3865df6ff36358fdc987d3c860d2970993c06 ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 500399a1497dfe1786ba67d6d2bfced4832f3fed +Subproject commit 788ce671cb1cec54c3c9b3ac1c1ba189e8424819 ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit cdb9e13b39079904eed9d75cd332b66ee0cad0c0 +Subproject commit ee0a8f8b9a4bd3fdad23e9ac0db56e7f08ce35cd ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 +Subproject commit 6be36ed54cc035c0f095d24bf3a451638d45513c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f99228ef8a272e1a73a0b2e172c0ec65909492e2...fbc803759e530c15c355387011798f6be84eb54d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f99228ef8a272e1a73a0b2e172c0ec65909492e2...fbc803759e530c15c355387011798f6be84eb54d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu Jan 30 22:40:48 2025 From: gitlab at gitlab.haskell.org (Bodigrim (@Bodigrim)) Date: Thu, 30 Jan 2025 17:40:48 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/ne-cyclic-scc Message-ID: <679bfff0bb6b4_1a8309136868851621@gitlab.mail> Bodigrim pushed new branch wip/ne-cyclic-scc at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ne-cyclic-scc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 09:15:46 2025 From: gitlab at gitlab.haskell.org (Cheng Shao (@TerrorJack)) Date: Fri, 31 Jan 2025 04:15:46 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/bytecode-serialize Message-ID: <679c94c2d553e_2aa6c7ccaa74786be@gitlab.mail> Cheng Shao pushed new branch wip/bytecode-serialize at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bytecode-serialize You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 10:51:01 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Fri, 31 Jan 2025 05:51:01 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/ghc-9.6.7-backports Message-ID: <679cab15a8a0b_2e0d61a366dc782d0@gitlab.mail> Luite Stegeman pushed new branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ghc-9.6.7-backports You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 13:32:48 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 31 Jan 2025 08:32:48 -0500 Subject: [Git][ghc/ghc][wip/T25654] 47 commits: Use checkTyEqRhs to make types concrete Message-ID: <679cd100321b3_33a40cc056c40046@gitlab.mail> Ben Gamari pushed to branch wip/T25654 at Glasgow Haskell Compiler / GHC Commits: 87e82e2e by sheaf at 2025-01-16T14:51:45+01:00 Use checkTyEqRhs to make types concrete This commit refactors makeTypeConcrete to call checkTyEqRhs with the appropriate parameters. This avoids duplicating subtle logic in two places in the compiler. Changes: 1. Refactor of 'TyEqFlags'. Now 'TyEqFlags' stores a 'TEFTask', which is a description of which of the following checks we want to perform in 'checkTyEqRhs': - occurs check - level check - concreteness check In the process, the 'AreUnifying' datatype has been removed, as it is no longer needed. 2. Refactor of 'checkTyVar': a. Make use of the new 'TEFTask' data type to decide which checks to perform. In particular, this ensures that we perform **both** a concreteness check and a level check when both are required; previously we only did a concreteness check (that was a bug!). b. Recursively call 'checkTyVar' on the kind of unfilled metavariables. This deals with a bug in which we failed to uphold the invariant that the kind of a concrete type must itself be concrete. See test cases T23051, T23176. 3. Re-write of 'makeTypeConcrete', which now simply calls 'checkTyEqRhs' with appropriate 'TyEqFlags'/'TEFTask'. This gets rid of code duplication and risk for the two code paths going out-of-sync. Fixes #25616. See also #23883. - - - - - 5a8f35bd by ARATA Mizuki at 2025-01-17T11:17:49-05:00 x86 NCG: Use correct format for MOVD in the implementation of unpackInt64X2# MOVD takes the input format. Fixes #25658 - - - - - 14f8a7ec by Mateusz Goślinowski at 2025-01-17T22:49:09+00:00 Allow multiline strings in JS FFI (#25633) - - - - - 854c2f75 by Simon Peyton Jones at 2025-01-18T02:54:08-05:00 Fix a buglet in tcSplitForAllTyVarsReqTVBindersN The problem was that an equation in `split` had two guards (one about visiblity and one about `n_req`). So it fell thorugh if /either/ was False. But the next equation then assumed an invisible binder. Simple bug, easily fixed. Fixes #25661. - - - - - 264a1186 by sheaf at 2025-01-18T10:05:56+00:00 Generalise GHC diagnostic code infrastructure This commit generalises the infrastructure used for diagnostic codes, allowing it to be used for other namespaces than the GHC namespace. In particular, this enables GHCi to re-use the same infrastructure to emit error messages. - - - - - bf4f5ad3 by Jade at 2025-01-18T10:05:56+00:00 Add structured errors to GHCi (#23338) This patch creates the 'GhciCommandErrorMessage' data type which implents the 'Diagnostic' class and also provides error code for these error conditions. - - - - - b6f54188 by Ben Gamari at 2025-01-18T12:38:46-05:00 Revert "Division by constants optimization" This appears to be responsible for the regression described in #25653. This reverts commit daff1e30219d136977c71f42e82ccc58c9013cfb. - - - - - 0fd90de8 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Introduce div2 test This is a useful test from !8392 which is worth keeping around. - - - - - 32680979 by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Test shift correctness in mul2 test - - - - - 163aa50a by Ben Gamari at 2025-01-18T12:38:46-05:00 testsuite: Add regression test for #25653 - - - - - 44778963 by Matthew Pickering at 2025-01-20T11:23:08+00:00 driver: Store an ExternalModuleGraph in the EPS We now store an ExternalModuleGraph in the EPS. When an new interface is loaded, the module graph is extended with a node for the loaded interface. The result is a partial module graph. If you want to run a transitive closure query on the graph you must first force the transitive closure to be loaded by using `loadExternalGraphBelow`. The primary advantage (for now) is that the transitive dependency calculation does not have to be repeated in getLinkDeps. If your module had many dependencies and many splices, performing this calculation at every splice site took a significant amount of time. We might also want to use this module graph in future for considering questions such as reachability of rules or accessibilty of instance imported by levelled imported. This patch removes another place in the compiler where transitive dependency is calculated in an ad-hoc manner. In general, the transitive dependency calculation should be cached and computed using a ModuleGraph abstraction. The transitive dependency query required by getLinkDeps operates on a graph without hs-boot nodes. If a linkable from a module in a loop is needed, then all modules in the loop are necessary to be available to execute that module. Therefore there is a query in `ModuleGraph` and `ExternalModuleGraph` which allows a transitive closure query to be performed on a graph without loops. Fixes #25634 ------------------------- Metric Decrease: MultiLayerModulesTH_Make MultiLayerModulesTH_OneShot Metric Increase: mhu-perf ------------------------- Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita at gmail.com> - - - - - b3c0acfc by Cheng Shao at 2025-01-20T11:53:10-05:00 hie: fix hie.yaml to use default hie-bios script !13778 accidentally changed hie.yaml to use hie-bios.bat as the default hie-bios script, which completely breaks hie support on non-Windows platforms. This patch reverts that change. - - - - - 595013d4 by Ben Gamari at 2025-01-21T09:57:23-05:00 compiler: Fix CPP guards around ghc_unique_counter64 The `ghc_unique_counter64` symbol was introduced in the RTS in the 64-bit unique refactor (!10568) which has been backported to %9.6.7 and %9.8.4. Update the CPP to reflect this. Fixes #25576. - - - - - 09ee3247 by Ryan Scott at 2025-01-21T09:58:00-05:00 Fix :info pretty-printing of UNPACKed fields This patch: * Ensures that we do not pretty-print a field like `foo :: {-# UNPACK #-} !Int` as `foo :: ! {-# UNPACK -#} Int` (as we were doing before) when running the `:info` command. * Prevents coercions that arise from `UNPACK`ed fields (e.g., such as when one unpacks a newtype) from being printed in `:info` output unless `-dppr-debug` is enabled. Fixes #25651. - - - - - 6b7ea592 by Rodrigo Mesquita at 2025-01-21T16:10:35-05:00 driver: Store the HomePackageTable in a mutable reference This commit refactors the HomePackageTable and HomeUnitGraph: (1) It fixes a quadratic-in-the-number-of-modules space leak in upsweep (#25511) (2) And it reworks these structures into their own modules to simplify the driver. The refactor is driven by the introduction of IO in the HPT interface, but is a bit more aggressive in simplifying the interfaces to enforce correct usage (ie to avoid performance pitfalls). Specifically: - The `HomeUnitGraph` (HUG) is now in `GHC.Unit.Home.Graph` - The `HomePackageTable` (HPT) is now in `GHC.Unit.Home.PackageTable` - The HPT now stores an `IORef` with the table of loaded home package modules. - The interface to the HPT now requires IO - The interface now enforces that the HPT is a datastructure that only grows - This is not enforced in the interface, but, clients of the HPT should never care about there being more or less entries in the HPT when these additional entries are not relevant to their result. - The exception to the invariant that the HPT is monotonically increasing is `restrictHpt`, a function which is called at a "barrier point" (during which there are no other threads inspecting or inserting in the HPT). The invariant can be temporarily broken at this point (currently, after upsweep). This is safe because a single thread holds control over the structure (thus the invariant being broken is never observed). The hug_var and associated structures in the driver, which aimed to improve memory usage in the driver by updating in place a HUG during upsweep, are no longer required as the HPT entries in the HUG are now themselves mutable by construction. This was previously explained in Note [ModuleNameSet, efficiency and space leaks], which is no longer relevant and was deleted. Fixes #25511 Co-authored-by: Matthew Pickering <matthewtpickering at gmail.com> ------------------------- Metric Decrease: MultiComponentModulesRecomp MultiLayerModulesRecomp ------------------------- - - - - - f983a00f by Jens Petersen at 2025-01-21T16:11:12-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 Fix build with gcc-15 which defaults to C23 standard (-std=gnu23) Fixes #25662 ``` utils/hp2ps/Utilities.c:6:14: error: warning: conflicting types for built-in function ‘malloc’; expected ‘void *(long unsigned int)’ [-Wbuiltin-declaration-mismatch] 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c:5:1: error: note: ‘malloc’ is declared in header ‘<stdlib.h>’ 4 | #include "Error.h" +++ |+#include <stdlib.h> 5 | | 5 | | ^ utils/hp2ps/Utilities.c: In function ‘xmalloc’: utils/hp2ps/Utilities.c:80:17: error: error: too many arguments to function ‘malloc’; expected 0, have 1 80 | r = (void*) malloc(n); | ^~~~~~ ~ | 80 | r = (void*) malloc(n); | ^ utils/hp2ps/Utilities.c:6:14: error: note: declared here 6 | extern void* malloc(); | ^~~~~~ | 6 | extern void* malloc(); | ^ utils/hp2ps/Utilities.c: In function ‘xrealloc’: utils/hp2ps/Utilities.c:92:18: error: warning: conflicting types for built-in function ‘realloc’; expected ‘void *(void *, long unsigned int)’ [-Wbuiltin-declaration-mismatch] 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:92:18: error: note: ‘realloc’ is declared in header ‘<stdlib.h>’ | 92 | extern void *realloc(); | ^ utils/hp2ps/Utilities.c:94:9: error: error: too many arguments to function ‘realloc’; expected 0, have 2 94 | r = realloc(p, n); | ^~~~~~~ ~ | 94 | r = realloc(p, n); | ^ utils/hp2ps/Utilities.c:92:18: error: note: declared here 92 | extern void *realloc(); | ^~~~~~~ | 92 | extern void *realloc(); | ^ ``` - - - - - 51e3ec83 by Vladislav Zavialov at 2025-01-22T20:41:32+03:00 Rework built-in and punned names (#25174, #25179, #25180, #25182) This patch rewrites part of the logic for dealing with built-in and punned names, making it more principled and fixing a few bugs. * Kill off filterCTuple. Its purpose was to improve pretty-printing of constraint tuples, and the appropriate place for this is namePun_maybe. * Remove unitTyCon, unboxedUnitTyCon, and soloTyCon from wiredInTyCons. Their inclusion in the list was a workaround for shoddy logic in lookupOrigNameCache. Now we treat tuples of all arities uniformly. * In isBuiltInOcc_maybe, only match on actual built-in syntax, e.g. "FUN" shouldn't be there (#25174). Also take ListTuplePuns into account (#25179). * When matching OccNames, use the ShortByteString directly to avoid potentially costly conversions to ByteString and String. * Introduce isInfiniteFamilyOrigName_maybe, a purpose-built helper for looking up tuples/sums in the OrigNameCache. This clears up the previously convoluted relation between the orig name cache and built-in syntax. * Reuse isKnownOrigName_maybe to eliminate the need for isPunOcc_maybe. * Classify MkSolo and MkSolo# as UserSyntax, thus fixing whole-module reexports (#25182). * Teach valid-hole-fits about tuples, unboxed tuples, and unboxed sums, up to a certain arity (#25180). * Drop the unnecessary special case for unary constraint tuples in the type checker (finish_tuple). It was a workaround for the lack of CSolo. * Update Notes and other comments, add tests. - - - - - 85c60aea by Teo Camarasu at 2025-01-23T18:06:21-05:00 doc: Add documentation for -XDoAndIfThenElse Resolves #18631 Co-authored-by: Richard Eisenberg <rae at cs.brynmawr.edu> - - - - - 4495e48f by Brandon Chinn at 2025-01-24T11:54:24-05:00 Break out GHC.Parser.Lexer.Interface - - - - - 4f8fc11e by Brandon Chinn at 2025-01-24T11:54:24-05:00 Fix lexing comments in multiline strings (#25609) Metric Decrease: MultiLayerModulesRecomp parsing001 - - - - - e7ab778f by Matthew Pickering at 2025-01-24T11:55:01-05:00 testsuite: Pass TEST_HC_OPTS to many more tests This passes `-dno-debug-output` to the test and `-dlint. - - - - - c3593101 by Sylvain Henry at 2025-01-24T23:12:20-05:00 Merge ghc-prim's modules into ghc-internal (#24453) ghc-internal becomes the only wired-in package exposing primitives. There are some minor GHC allocation regressions, but they barely cross the thresholds and only with the wasm backend. They're likely due to longer symbols (ghc-internal vs ghc-prim, GHC.Internal.X vs GHC.X). Metric Increase: T13035 T1969 T4801 T9961 - - - - - 70f7741a by Jens Petersen at 2025-01-24T23:12:58-05:00 hp2ps/Utilities.c: add extern parameter types for malloc and realloc for C23 use portable C types! - - - - - a1d92378 by Brandon Chinn at 2025-01-25T15:11:54-08:00 Fix for alex-3.5.2.0 (#25623) This INLINE pragma for alexScanUser was added in 9.12, but then I ported the change to alex in 3.5.2.0 (https://github.com/haskell/alex/pull/262). I didn't realize that GHC errors on duplicate INLINE pragmas, so this ended up being a breaking change. This change should be backported into 9.12 - - - - - 62760367 by ARATA Mizuki at 2025-01-27T16:23:06-05:00 x86 NCG: Make MOVD's output format explicit The old design led to inference of a wrong format, losing upper bits of a vector register. Fixes #25659 Co-authored-by: sheaf <sam.derbyshire at gmail.com> - - - - - f19ab490 by Simon Hengel at 2025-01-27T16:23:45-05:00 doc: Correct JSON schema for `-fdiagnostics-as-json` (fixes #25393) - - - - - e16eae65 by Cheng Shao at 2025-01-27T21:41:39+00:00 hadrian: fix bootstrap with 9.12.1 This patch bumps hadrian index-state to fix bootstrap with 9.12.1. - - - - - 8071bad8 by Jeffrey Young at 2025-01-28T21:45:32-05:00 base: add SrcLoc changes to changelog, 4.21.0.0 I accidentally dropped this in !13381 - closes #25614 See: - ea4587794b9e3a098f9c02bd6cea2294af2539ce (the 13381 commit) - Issue #25614 - - - - - 9dcc7e28 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Rename `cloneBndrs` and such — now all the monadic ones have an `M` suffix. We now have `cloneBndrs` and `cloneRecIdBndrs` which take a `UniqSupply` argument, and `cloneBndrsM` and `cloneRecIdBndrsM` which rather have a `MonadUnique` constraint. - - - - - 643dd3d8 by Matthew Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in unique generation, and clean up some other partial uni patterns as well. Also drop the losing `instance MonadFail UniqSM`. We redefine `getUniquesM` in terms of `Infinite` rather than `[]`, and define another method `getUniqueListM` for the use sites where we actually want a `[]`. Thus, at many sites, we can avoid the partiality of the empty list case. We also define `withUniques`, `withUniquesM`, and `withUniquesM'`, which traverse an arbitrary `Traversable` structure and introduce a `Unique` for each element. This allows us to redefine various functions to operate on more appropriate types than `[]` and avoid further partiality (in the form of incomplete-uni-patterns). - - - - - dd0acc3c by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Tc.Deriv.Functor`. Make the list of variables to use in generated code `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - 4e9adedf by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Use `Infinite` in `GHC.Runtime.Debugger`. Make the list of available names `Infinite`, to avoid panicking on the (now impossible) empty list case. - - - - - bed812b7 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Cmm.DebugBlock`. We do so by changing the type of `BlockContext` to statically (in GHC) exclude the possibility of Cmm statics, and using `NonEmpty` lists of `BlockContext`s in `cmmDebugGen`. - - - - - 27587df3 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.Types.Literal`. We do so by introducing `mkLitNumberWrap'` whose ultimate codomain is `Integer` rather than `Literal`, and then use that rather than `mkLitNumberWrap` where we just need the number rather than the `Literal`. - - - - - 138de0ff by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Avoid incomplete-uni-patterns in `GHC.CmmToAsm.X86.CodeGen`. - Match the vector element list only once in `shuffleInstructions`. - Define `isSuitableFloatingPointLit_maybe` which returns `Just` the width if the lit is indeed suitable. - - - - - d8cb3d36 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Clean up more incomplete uni patterns. At some sites, we merely panic if the `[]` or `Maybe` is empty when we convert to `NonEmpty` or `Identity`, but at least now we make it explicit. At other sites, we are able to use more precise types and avoid the partiality altogether. To do so, we redefine various functions to operate over `Traversable` arguments, so we can use the appropriate shape where known. - - - - - f251bd22 by M Farkas-Dyck at 2025-01-29T02:27:48-05:00 Outline `expectJustPanic`. - - - - - a963a1a5 by Marc Scholten at 2025-01-29T02:28:35-05:00 base: Introduce Data.Enum.enumerate (CLC #306) https://github.com/haskell/core-libraries-committee/issues/306 - - - - - 944712da by Ben Gamari at 2025-01-29T02:29:13-05:00 base: Update description of locking behavior - - - - - 85abc69c by Ben Gamari at 2025-01-29T02:29:51-05:00 base: Fix @since annotation of Data.Bounded Fixes #25615. - - - - - 2ca41c62 by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Fix overly-broad handling of Addr# literals Previously we assumed that all unlifted types were `Addr#` but this isn't true. As noted in #25638, unlifted nullary data constructor workers can also appear at the top-level and are obviously not of type `Addr#`. Note that there is more work to be done to properly handle unlifted data constructors (especially nullary; see #25636). However, this is a small step in the right direction. Closes #25641. - - - - - ec26c54d by Ben Gamari at 2025-01-29T02:30:29-05:00 StgToByteCode: Assert that PUSH_G'd values are lifted We currently do not support top-level unlifted data constructor applications, therefore this is a safe assertion. Pointed out by @sheaf. - - - - - 8847125f by Ben Gamari at 2025-01-29T02:31:07-05:00 gitlab-ci: Run test-primops testsuite in ~"full-ci" pipeline Closes #25654. - - - - - bf8c7d6e by Matthew Pickering at 2025-01-29T02:31:44-05:00 bytecode: Do not generate `SLIDE x 0` instructions SLIDE x 0 is a no-op as it means to shift x elements of the stack by no spaces. In the interpreter, this results in a loop which copies an array element into the same place. I have instrumented GHCi to count how many of these instructions are interpreted. The workload was `ghc` compiling two simple modules. Total no-op slides: 7793476 Total slides: 11413289 Percentage useless (slides): 68% Percentage uselss of total instructions: 9% - - - - - 7bfc93a7 by Zubin Duggal at 2025-01-29T21:41:17-05:00 hackage-doc-tarball: Allow ghc-boot-th to be uploaded to hackage It can't refer to files outside its source directory, so patch that part out. This is OK because those files are only used while bootstrapping. Also add ghci to the list of packages to be uploaded Fixes #25687 - - - - - 704eeb02 by Roman S at 2025-01-29T21:42:05-05:00 Fix Control.Arrow (***) diagram (fixes #25698) - - - - - 59ef1000 by Ben Gamari at 2025-01-31T08:30:25-05:00 gitlab-ci: Don't use .full-ci to run test-primops test-primops depends upon the existence of validate jobs, yet these do not exist in the context of nightly jobs, which .full-ci includes. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/rel_eng/upload_ghc_libs.py - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Uniques.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/Config.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Sink.hs - compiler/GHC/Cmm/ThreadSanitizer.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/AArch64/CodeGen.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/PPC/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs - compiler/GHC/CmmToAsm/Reg/Liveness.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs - compiler/GHC/CmmToLlvm/CodeGen.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Pipeline.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9dc07fcfc1aa422349693e22d63f5343d9481513...59ef1000634b388cc1f677fb53ba72cb3ac137dc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9dc07fcfc1aa422349693e22d63f5343d9481513...59ef1000634b388cc1f677fb53ba72cb3ac137dc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 13:57:53 2025 From: gitlab at gitlab.haskell.org (Luite Stegeman (@luite)) Date: Fri, 31 Jan 2025 08:57:53 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.6.7-backports] rts: don't export atomic_inc64 Message-ID: <679cd6e18af0d_33a40c34290c47311@gitlab.mail> Luite Stegeman pushed to branch wip/ghc-9.6.7-backports at Glasgow Haskell Compiler / GHC Commits: 6205e04a by Luite Stegeman at 2025-01-31T14:51:48+01:00 rts: don't export atomic_inc64 This makes it easier for packges to use GHC 9.6.7 because the symbols exported by the rts are the same as in 9.6.6. This means that we define the symbol in the ghc library instead, where we have to pessimistically assume a threaded rts. - - - - - 3 changed files: - compiler/cbits/genSym.c - rts/RtsSymbols.c - rts/include/stg/SMP.h Changes: ===================================== compiler/cbits/genSym.c ===================================== @@ -30,8 +30,8 @@ HsInt ghc_unique_inc = 1; // This function has been added to the RTS. Here we pessimistically assume // that a threaded RTS is used. This function is only used for bootstrapping. -#if !MIN_VERSION_GLASGOW_HASKELL(9,6,7,0) -EXTERN_INLINE StgWord64 +#if !MIN_VERSION_GLASGOW_HASKELL(9,7,0,0) +STATIC_INLINE StgWord64 atomic_inc64(StgWord64 volatile* p, StgWord64 incr) { #if defined(HAVE_C11_ATOMICS) ===================================== rts/RtsSymbols.c ===================================== @@ -923,7 +923,6 @@ extern char **environ; SymI_HasProto(stopHeapProfTimer) \ SymI_HasProto(requestHeapCensus) \ SymI_HasProto(atomic_inc) \ - SymI_HasProto(atomic_inc64) \ SymI_HasProto(atomic_dec) \ SymI_HasProto(hs_spt_lookup) \ SymI_HasProto(hs_spt_insert) \ ===================================== rts/include/stg/SMP.h ===================================== @@ -87,15 +87,6 @@ EXTERN_INLINE StgWord cas_seq_cst_relaxed(StgVolatilePtr p, StgWord o, StgWord n EXTERN_INLINE StgWord atomic_inc(StgVolatilePtr p, StgWord n); -/* - * Atomic 64-bit addition of by the provided quantity - * - * atomic_inc64(p, n) { - * return ((*p) += n); - * } - */ -EXTERN_INLINE StgWord64 atomic_inc64(StgWord64 volatile* p, StgWord64 n); - /* * Atomic decrement * @@ -440,16 +431,6 @@ atomic_inc(StgVolatilePtr p, StgWord incr) #endif } -EXTERN_INLINE StgWord64 -atomic_inc64(StgWord64 volatile* p, StgWord64 incr) -{ -#if defined(HAVE_C11_ATOMICS) - return __atomic_add_fetch(p, incr, __ATOMIC_SEQ_CST); -#else - return __sync_add_and_fetch(p, incr); -#endif -} - EXTERN_INLINE StgWord atomic_dec(StgVolatilePtr p) { @@ -678,15 +659,6 @@ atomic_inc(StgVolatilePtr p, StgWord incr) return ((*p) += incr); } - -EXTERN_INLINE StgWord64 atomic_inc64(StgWord64 volatile* p, StgWord64 incr); -EXTERN_INLINE StgWord64 -atomic_inc64(StgWord64 volatile* p, StgWord64 incr) -{ - return ((*p) += incr); -} - - INLINE_HEADER StgWord atomic_dec(StgVolatilePtr p) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6205e04ae920776f282df9a428829d9e90a9c776 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6205e04ae920776f282df9a428829d9e90a9c776 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 14:20:51 2025 From: gitlab at gitlab.haskell.org (Ben Gamari (@bgamari)) Date: Fri, 31 Jan 2025 09:20:51 -0500 Subject: [Git][ghc/ghc][wip/ghc-9.10.2-submodules] 15 commits: gitlab-ci: Bump aarch64-darwin boostrap compiler to 9.6.4 Message-ID: <679cdc43588f_33a40c84928451826@gitlab.mail> Ben Gamari pushed to branch wip/ghc-9.10.2-submodules at Glasgow Haskell Compiler / GHC Commits: 209ba1f7 by Ben Gamari at 2025-01-31T09:20:26-05:00 gitlab-ci: Bump aarch64-darwin boostrap compiler to 9.6.4 Bringing it into alignment with the other platforms. - - - - - c5ca2145 by Ben Gamari at 2025-01-31T09:20:26-05:00 Cabal: Bump to 3.12.1.0 - - - - - 15b69820 by Ben Gamari at 2025-01-31T09:20:26-05:00 bytestring: Bump to 0.12.2.0 - - - - - 5cca5010 by Ben Gamari at 2025-01-31T09:20:26-05:00 binary: Bump to 0.8.9.3 - - - - - 35b0d21d by Ben Gamari at 2025-01-31T09:20:26-05:00 array: Bump to 0.5.8.0 - - - - - 4c6ac1db by Ben Gamari at 2025-01-31T09:20:26-05:00 filepath: Bump to 1.5.4.0 - - - - - 8c168a25 by Ben Gamari at 2025-01-31T09:20:26-05:00 hpc: Bump to 0.7.0.2 - - - - - d5de9bfc by Ben Gamari at 2025-01-31T09:20:26-05:00 parsec: Bump to 3.1.18.0 - - - - - 6eaba44c by Ben Gamari at 2025-01-31T09:20:26-05:00 process: Bump to 1.6.25.0 - - - - - 745ee93f by Ben Gamari at 2025-01-31T09:20:26-05:00 terminfo: Bump to 0.4.1.7 - - - - - 943600a8 by Ben Gamari at 2025-01-31T09:20:26-05:00 text: Bump to 2.1.2 - - - - - a3ec2f52 by Ben Gamari at 2025-01-31T09:20:26-05:00 unix: Bump to 2.8.6.0 - - - - - f9488fa7 by Ben Gamari at 2025-01-31T09:20:26-05:00 exceptions: Bump to 0.10.9 - - - - - 9a87525e by Ben Gamari at 2025-01-31T09:20:26-05:00 Win32: Bump to 2.14.1.0 - - - - - d91e20b1 by Ben Gamari at 2025-01-31T09:20:26-05:00 directory: Bump to 1.3.8.5 - - - - - 18 changed files: - .gitlab/darwin/nix/sources.json - .gitlab/darwin/nix/sources.nix - .gitlab/darwin/toolchain.nix - hadrian/src/Settings/Warnings.hs - libraries/Cabal - libraries/Win32 - libraries/array - libraries/binary - libraries/bytestring - libraries/directory - libraries/exceptions - libraries/filepath - libraries/hpc - libraries/parsec - libraries/process - libraries/terminfo - libraries/text - libraries/unix Changes: ===================================== .gitlab/darwin/nix/sources.json ===================================== @@ -5,10 +5,10 @@ "homepage": "https://github.com/nmattia/niv", "owner": "nmattia", "repo": "niv", - "rev": "e0ca65c81a2d7a4d82a189f1e23a48d59ad42070", - "sha256": "1pq9nh1d8nn3xvbdny8fafzw87mj7gsmp6pxkdl65w2g18rmcmzx", + "rev": "e2f66fe558481d6b569358d27db06f7e972ed71b", + "sha256": "1xn822jajags6bigdr1ssxvfiyd7d3adhnmmrr9x3maphchkr0x0", "type": "tarball", - "url": "https://github.com/nmattia/niv/archive/e0ca65c81a2d7a4d82a189f1e23a48d59ad42070.tar.gz", + "url": "https://github.com/nmattia/niv/archive/e2f66fe558481d6b569358d27db06f7e972ed71b.tar.gz", "url_template": "https://github.com///archive/.tar.gz" }, "nixpkgs": { @@ -17,10 +17,10 @@ "homepage": "", "owner": "nixos", "repo": "nixpkgs", - "rev": "73de017ef2d18a04ac4bfd0c02650007ccb31c2a", - "sha256": "1v9sy2i2dy3qksx4mf81gwzfl0jzpqccfkzq7fjxgq832f9d255i", + "rev": "9d3ae807ebd2981d593cddd0080856873139aa40", + "sha256": "0bjqgsprq9fgl5yh58dk59xmchi4dajq3sf5i447q02dbiasjsil", "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/73de017ef2d18a04ac4bfd0c02650007ccb31c2a.tar.gz", + "url": "https://github.com/nixos/nixpkgs/archive/9d3ae807ebd2981d593cddd0080856873139aa40.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } ===================================== .gitlab/darwin/nix/sources.nix ===================================== @@ -10,29 +10,50 @@ let let name' = sanitizeName name + "-src"; in - if spec.builtin or true then - builtins_fetchurl { inherit (spec) url sha256; name = name'; } - else - pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; + if spec.builtin or true then + builtins_fetchurl { inherit (spec) url sha256; name = name'; } + else + pkgs.fetchurl { inherit (spec) url sha256; name = name'; }; fetch_tarball = pkgs: name: spec: let name' = sanitizeName name + "-src"; in - if spec.builtin or true then - builtins_fetchTarball { name = name'; inherit (spec) url sha256; } - else - pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; + if spec.builtin or true then + builtins_fetchTarball { name = name'; inherit (spec) url sha256; } + else + pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; fetch_git = name: spec: let ref = - if spec ? ref then spec.ref else + spec.ref or ( if spec ? branch then "refs/heads/${spec.branch}" else - if spec ? tag then "refs/tags/${spec.tag}" else - abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"; + if spec ? tag then "refs/tags/${spec.tag}" else + abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!" + ); + submodules = spec.submodules or false; + submoduleArg = + let + nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0; + emptyArgWithWarning = + if submodules + then + builtins.trace + ( + "The niv input \"${name}\" uses submodules " + + "but your nix's (${builtins.nixVersion}) builtins.fetchGit " + + "does not support them" + ) + { } + else { }; + in + if nixSupportsSubmodules + then { inherit submodules; } + else emptyArgWithWarning; in - builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; }; + builtins.fetchGit + ({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg); fetch_local = spec: spec.path; @@ -66,16 +87,16 @@ let hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; hasThisAsNixpkgsPath = == ./.; in - if builtins.hasAttr "nixpkgs" sources - then sourcesNixpkgs - else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then - import {} - else - abort - '' - Please specify either (through -I or NIX_PATH=nixpkgs=...) or - add a package called "nixpkgs" to your sources.json. - ''; + if builtins.hasAttr "nixpkgs" sources + then sourcesNixpkgs + else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then + import { } + else + abort + '' + Please specify either (through -I or NIX_PATH=nixpkgs=...) or + add a package called "nixpkgs" to your sources.json. + ''; # The actual fetching function. fetch = pkgs: name: spec: @@ -95,13 +116,13 @@ let # the path directly as opposed to the fetched source. replace = name: drv: let - saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; + saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name; ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; in - if ersatz == "" then drv else - # this turns the string into an actual Nix path (for both absolute and - # relative paths) - if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; + if ersatz == "" then drv else + # this turns the string into an actual Nix path (for both absolute and + # relative paths) + if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}"; # Ports of functions for older nix versions @@ -112,7 +133,7 @@ let ); # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 - range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1); + range = first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1); # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); @@ -123,43 +144,46 @@ let concatStrings = builtins.concatStringsSep ""; # https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331 - optionalAttrs = cond: as: if cond then as else {}; + optionalAttrs = cond: as: if cond then as else { }; # fetchTarball version that is compatible between all the versions of Nix builtins_fetchTarball = { url, name ? null, sha256 }@attrs: let inherit (builtins) lessThan nixVersion fetchTarball; in - if lessThan nixVersion "1.12" then - fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) - else - fetchTarball attrs; + if lessThan nixVersion "1.12" then + fetchTarball ({ inherit url; } // (optionalAttrs (name != null) { inherit name; })) + else + fetchTarball attrs; # fetchurl version that is compatible between all the versions of Nix builtins_fetchurl = { url, name ? null, sha256 }@attrs: let inherit (builtins) lessThan nixVersion fetchurl; in - if lessThan nixVersion "1.12" then - fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; })) - else - fetchurl attrs; + if lessThan nixVersion "1.12" then + fetchurl ({ inherit url; } // (optionalAttrs (name != null) { inherit name; })) + else + fetchurl attrs; # Create the final "sources" from the config mkSources = config: - mapAttrs ( - name: spec: - if builtins.hasAttr "outPath" spec - then abort - "The values in sources.json should not have an 'outPath' attribute" - else - spec // { outPath = replace name (fetch config.pkgs name spec); } - ) config.sources; + mapAttrs + ( + name: spec: + if builtins.hasAttr "outPath" spec + then + abort + "The values in sources.json should not have an 'outPath' attribute" + else + spec // { outPath = replace name (fetch config.pkgs name spec); } + ) + config.sources; # The "config" used by the fetchers mkConfig = { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null - , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile) + , sources ? if sourcesFile == null then { } else builtins.fromJSON (builtins.readFile sourcesFile) , system ? builtins.currentSystem , pkgs ? mkPkgs sources system }: rec { @@ -171,4 +195,4 @@ let }; in -mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } +mkSources (mkConfig { }) // { __functor = _: settings: mkSources (mkConfig settings); } ===================================== .gitlab/darwin/toolchain.nix ===================================== @@ -26,8 +26,7 @@ let }; ghc = pkgs.stdenv.mkDerivation rec { - # Using 9.6.2 because of #24050 - version = "9.6.2"; + version = "9.6.4"; name = "ghc"; src = ghcBindists.${pkgs.stdenv.hostPlatform.system}; configureFlags = [ ===================================== hadrian/src/Settings/Warnings.hs ===================================== @@ -56,7 +56,7 @@ ghcWarningsArgs = do , package primitive ? pure [ "-Wno-unused-imports" , "-Wno-deprecations" ] , package rts ? pure [ "-Wcpp-undef" ] - , package text ? pure [ "-Wno-deprecations" ] + , package text ? pure [ "-Wno-deprecations", "-Wno-unused-imports" ] , package terminfo ? pure [ "-Wno-unused-imports" ] , package transformers ? pure [ "-Wno-unused-matches" , "-Wno-unused-imports" ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 59fd01457fa662bca17110bc7505ea52bf162135 +Subproject commit 260ecdc3d848782d4df49e629cb0a5dc9e96ca9e ===================================== libraries/Win32 ===================================== @@ -1 +1 @@ -Subproject commit 350ebd43f9a8d9e1ca767b0000f95bdfb42a5471 +Subproject commit 027cbcf0de25d681823ea92fb545a2604c3a6a8b ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit a65f8a5e7c26fe9b8012b90cbbff8866f8d39113 +Subproject commit c9cb2c1e8762aa83b6e77af82c87a55e03e990e4 ===================================== libraries/binary ===================================== @@ -1 +1 @@ -Subproject commit a501955f7ab48da81d732958c8834caaa3e470b6 +Subproject commit a625eee2eb9dfb4019c051b59d6007c9dded88aa ===================================== libraries/bytestring ===================================== @@ -1 +1 @@ -Subproject commit 453c1dc110720a366f90ef84dc2d75a5cd8c28e0 +Subproject commit d984ad00644c0157bad04900434b9d36f23633c5 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 4b7c231d187cf253c5f446c4aed2fea26b81d5f9 +Subproject commit e8ee4d5565ec82272ca612034ba6029993e23fd0 ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit d9fba07b664e3c48f011baca1a8a204292ca2722 +Subproject commit 0b6abb3ac433c7d1d5c6f6a5a45b37f7c486e33b ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 87a09e296ea6fc137a0b32edda1bd0f54332642e +Subproject commit 65b0f8f31aac4a306135e27734988327f8eb1e6f ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit 8bf6f8b08b0d72cb9231775b66ca572acc1d3197 +Subproject commit 37c56cf932e429950a199d0b1f39796677b052c5 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit 9c071b05fbb077afbaf0dd2dfdab21265859ae91 +Subproject commit b87122c1c74b8240e65044a8f600f0427d4dd9c3 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit dfbe62c7d9fc84d2550fc7e7db993dc0aa143ef5 +Subproject commit a5a3865df6ff36358fdc987d3c860d2970993c06 ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 500399a1497dfe1786ba67d6d2bfced4832f3fed +Subproject commit 788ce671cb1cec54c3c9b3ac1c1ba189e8424819 ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit cdb9e13b39079904eed9d75cd332b66ee0cad0c0 +Subproject commit ee0a8f8b9a4bd3fdad23e9ac0db56e7f08ce35cd ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 69552a5267c7dc5c46a8bceec5ec4b40d26b9463 +Subproject commit 6be36ed54cc035c0f095d24bf3a451638d45513c View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fbc803759e530c15c355387011798f6be84eb54d...d91e20b1bcd6095a34fa939cac6c82c2787ba3fa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fbc803759e530c15c355387011798f6be84eb54d...d91e20b1bcd6095a34fa939cac6c82c2787ba3fa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 14:47:09 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 31 Jan 2025 09:47:09 -0500 Subject: [Git][ghc/ghc][wip/generic-length] perf: Replace uses of genericLength with specialised length functions. Message-ID: <679ce26d36e9c_33a40c10688e86107d@gitlab.mail> Matthew Pickering pushed to branch wip/generic-length at Glasgow Haskell Compiler / GHC Commits: f90116dc by Matthew Pickering at 2025-01-31T14:46:15+00:00 perf: Replace uses of genericLength with specialised length functions. genericLength is a recursive function and marked NOINLINE. It is not going to specialise. In profiles, it can be seen that 3% of total compilation time when computing bytecode is spend calling this non-specialised function. In addition, we can simplify `addListToSS` to avoid traversing the input list twice and also allocating an intermediate list (after the call to reverse). Overall these changes reduce the time spend in 'assembleBCOs' from 5.61s to 3.88s. Allocations drop from 8GB to 5.3G. Fixes #25706 - - - - - 4 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/Prelude/Basic.hs - compiler/GHC/StgToByteCode.hs - libraries/ghc-boot/GHC/Data/SizedSeq.hs Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -53,7 +53,6 @@ import Data.Array.Base ( UArray(..) ) import Foreign hiding (shiftL, shiftR) import Data.Char ( ord ) -import Data.List ( genericLength ) import Data.Map.Strict (Map) import Data.Maybe (fromMaybe) import qualified Data.Map.Strict as Map @@ -343,6 +342,7 @@ data InspectState = InspectState , lblEnv :: LabelEnvMap } + inspectAsm :: Platform -> Bool -> Word -> Assembler a -> (Word, LabelEnvMap) inspectAsm platform long_jumps initial_offset = go (InspectState initial_offset 0 0 Map.empty) @@ -350,7 +350,7 @@ inspectAsm platform long_jumps initial_offset go s (NullAsm _) = (instrCount s, lblEnv s) go s (AllocPtr _ k) = go (s { ptrCount = n + 1 }) (k n) where n = ptrCount s - go s (AllocLit ls k) = go (s { litCount = n + genericLength ls }) (k n) + go s (AllocLit ls k) = go (s { litCount = n + strictGenericLength ls }) (k n) where n = litCount s go s (AllocLabel lbl k) = go s' k where s' = s { lblEnv = Map.insert lbl (instrCount s) (lblEnv s) } ===================================== compiler/GHC/Prelude/Basic.hs ===================================== @@ -25,6 +25,8 @@ module GHC.Prelude.Basic , shiftL, shiftR , setBit, clearBit , head, tail + + , strictGenericLength ) where @@ -130,3 +132,18 @@ head = Prelude.head tail :: HasCallStack => [a] -> [a] tail = Prelude.tail {-# INLINE tail #-} + +{- | +The 'genericLength' function defined in base can't be specialised due to the +NOINLINE pragma. + +It is also not strict in the accumulator, and strictGenericLength is not exported. + +See #25706 for why it is important to use a strict, specialised version. + +-} +strictGenericLength :: Num a => [x] -> a +strictGenericLength = foldl' (\n _ -> 1 + n) 0 +{-# INLINABLE strictGenericLength #-} + +{-# SPECIALISE strictGenericLength :: forall x . [x] -> Word #-} ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Types.Name.Env (mkNameEnv) import GHC.Types.Tickish import GHC.Types.SptEntry -import Data.List ( genericReplicate, genericLength, intersperse +import Data.List ( genericReplicate, intersperse , partition, scanl', sortBy, zip4, zip6 ) import Foreign hiding (shiftL, shiftR) import Control.Monad @@ -393,7 +393,7 @@ schemeR_wrk fvs nm original_body (args, body) -- make the arg bitmap bits = argBits platform (reverse (map (idArgRep platform) all_args)) - bitmap_size = genericLength bits + bitmap_size = strictGenericLength bits bitmap = mkBitmap platform bits body_code <- schemeER_wrk sum_szsb_args p_init body @@ -607,7 +607,7 @@ schemeE d s p (StgLet _ext binds body) = do platform <- targetPlatform <$> getDynFlags let (xs,rhss) = case binds of StgNonRec x rhs -> ([x],[rhs]) StgRec xs_n_rhss -> unzip xs_n_rhss - n_binds = genericLength xs + n_binds = strictGenericLength xs fvss = map (fvsToEnv p') rhss @@ -616,7 +616,7 @@ schemeE d s p (StgLet _ext binds body) = do sizes = map (\rhs_fvs -> sum (map size_w rhs_fvs)) fvss -- the arity of each rhs - arities = map (genericLength . fst . collect) rhss + arities = map (strictGenericLength . fst . collect) rhss -- This p', d' defn is safe because all the items being pushed -- are ptrs, so all have size 1 word. d' and p' reflect the stack @@ -1857,7 +1857,7 @@ implement_tagToId implement_tagToId d s p arg names = assert (notNull names) $ do (push_arg, arg_bytes) <- pushAtom d p (StgVarArg arg) - labels <- getLabelsBc (genericLength names) + labels <- getLabelsBc (strictGenericLength names) label_fail <- getLabelBc label_exit <- getLabelBc dflags <- getDynFlags ===================================== libraries/ghc-boot/GHC/Data/SizedSeq.hs ===================================== @@ -11,7 +11,6 @@ module GHC.Data.SizedSeq import Prelude -- See note [Why do we import Prelude here?] import Control.DeepSeq import Data.Binary -import Data.List (genericLength) import GHC.Generics data SizedSeq a = SizedSeq {-# UNPACK #-} !Word [a] @@ -37,9 +36,9 @@ emptySS = SizedSeq 0 [] addToSS :: SizedSeq a -> a -> SizedSeq a addToSS (SizedSeq n r_xs) x = SizedSeq (n+1) (x:r_xs) +-- NB, important this is eta-expand so that foldl' is inlined. addListToSS :: SizedSeq a -> [a] -> SizedSeq a -addListToSS (SizedSeq n r_xs) xs - = SizedSeq (n + genericLength xs) (reverse xs ++ r_xs) +addListToSS s xs = foldl' addToSS s xs ssElts :: SizedSeq a -> [a] ssElts (SizedSeq _ r_xs) = reverse r_xs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f90116dc7c489195f816eba9cf1e220fbd6e533a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f90116dc7c489195f816eba9cf1e220fbd6e533a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 14:49:49 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 31 Jan 2025 09:49:49 -0500 Subject: [Git][ghc/ghc][wip/generic-length] perf: Replace uses of genericLength with strictGenericLength Message-ID: <679ce30d5ce7b_33a40c1265d3064486@gitlab.mail> Matthew Pickering pushed to branch wip/generic-length at Glasgow Haskell Compiler / GHC Commits: a75c70e4 by Matthew Pickering at 2025-01-31T14:49:26+00:00 perf: Replace uses of genericLength with strictGenericLength genericLength is a recursive function and marked NOINLINE. It is not going to specialise. In profiles, it can be seen that 3% of total compilation time when computing bytecode is spend calling this non-specialised function. In addition, we can simplify `addListToSS` to avoid traversing the input list twice and also allocating an intermediate list (after the call to reverse). Overall these changes reduce the time spend in 'assembleBCOs' from 5.61s to 3.88s. Allocations drop from 8GB to 5.3G. Fixes #25706 - - - - - 4 changed files: - compiler/GHC/ByteCode/Asm.hs - compiler/GHC/Prelude/Basic.hs - compiler/GHC/StgToByteCode.hs - libraries/ghc-boot/GHC/Data/SizedSeq.hs Changes: ===================================== compiler/GHC/ByteCode/Asm.hs ===================================== @@ -53,7 +53,6 @@ import Data.Array.Base ( UArray(..) ) import Foreign hiding (shiftL, shiftR) import Data.Char ( ord ) -import Data.List ( genericLength ) import Data.Map.Strict (Map) import Data.Maybe (fromMaybe) import qualified Data.Map.Strict as Map @@ -343,6 +342,7 @@ data InspectState = InspectState , lblEnv :: LabelEnvMap } + inspectAsm :: Platform -> Bool -> Word -> Assembler a -> (Word, LabelEnvMap) inspectAsm platform long_jumps initial_offset = go (InspectState initial_offset 0 0 Map.empty) @@ -350,7 +350,7 @@ inspectAsm platform long_jumps initial_offset go s (NullAsm _) = (instrCount s, lblEnv s) go s (AllocPtr _ k) = go (s { ptrCount = n + 1 }) (k n) where n = ptrCount s - go s (AllocLit ls k) = go (s { litCount = n + genericLength ls }) (k n) + go s (AllocLit ls k) = go (s { litCount = n + strictGenericLength ls }) (k n) where n = litCount s go s (AllocLabel lbl k) = go s' k where s' = s { lblEnv = Map.insert lbl (instrCount s) (lblEnv s) } ===================================== compiler/GHC/Prelude/Basic.hs ===================================== @@ -25,6 +25,8 @@ module GHC.Prelude.Basic , shiftL, shiftR , setBit, clearBit , head, tail + + , strictGenericLength ) where @@ -130,3 +132,18 @@ head = Prelude.head tail :: HasCallStack => [a] -> [a] tail = Prelude.tail {-# INLINE tail #-} + +{- | +The 'genericLength' function defined in base can't be specialised due to the +NOINLINE pragma. + +It is also not strict in the accumulator, and strictGenericLength is not exported. + +See #25706 for why it is important to use a strict, specialised version. + +-} +strictGenericLength :: Num a => [x] -> a +strictGenericLength = foldl' (\n _ -> 1 + n) 0 +{-# INLINABLE strictGenericLength #-} + +{-# SPECIALISE strictGenericLength :: forall x . [x] -> Word #-} ===================================== compiler/GHC/StgToByteCode.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Types.Name.Env (mkNameEnv) import GHC.Types.Tickish import GHC.Types.SptEntry -import Data.List ( genericReplicate, genericLength, intersperse +import Data.List ( genericReplicate, intersperse , partition, scanl', sortBy, zip4, zip6 ) import Foreign hiding (shiftL, shiftR) import Control.Monad @@ -393,7 +393,7 @@ schemeR_wrk fvs nm original_body (args, body) -- make the arg bitmap bits = argBits platform (reverse (map (idArgRep platform) all_args)) - bitmap_size = genericLength bits + bitmap_size = strictGenericLength bits bitmap = mkBitmap platform bits body_code <- schemeER_wrk sum_szsb_args p_init body @@ -607,7 +607,7 @@ schemeE d s p (StgLet _ext binds body) = do platform <- targetPlatform <$> getDynFlags let (xs,rhss) = case binds of StgNonRec x rhs -> ([x],[rhs]) StgRec xs_n_rhss -> unzip xs_n_rhss - n_binds = genericLength xs + n_binds = strictGenericLength xs fvss = map (fvsToEnv p') rhss @@ -616,7 +616,7 @@ schemeE d s p (StgLet _ext binds body) = do sizes = map (\rhs_fvs -> sum (map size_w rhs_fvs)) fvss -- the arity of each rhs - arities = map (genericLength . fst . collect) rhss + arities = map (strictGenericLength . fst . collect) rhss -- This p', d' defn is safe because all the items being pushed -- are ptrs, so all have size 1 word. d' and p' reflect the stack @@ -1857,7 +1857,7 @@ implement_tagToId implement_tagToId d s p arg names = assert (notNull names) $ do (push_arg, arg_bytes) <- pushAtom d p (StgVarArg arg) - labels <- getLabelsBc (genericLength names) + labels <- getLabelsBc (strictGenericLength names) label_fail <- getLabelBc label_exit <- getLabelBc dflags <- getDynFlags ===================================== libraries/ghc-boot/GHC/Data/SizedSeq.hs ===================================== @@ -11,7 +11,6 @@ module GHC.Data.SizedSeq import Prelude -- See note [Why do we import Prelude here?] import Control.DeepSeq import Data.Binary -import Data.List (genericLength) import GHC.Generics data SizedSeq a = SizedSeq {-# UNPACK #-} !Word [a] @@ -37,9 +36,9 @@ emptySS = SizedSeq 0 [] addToSS :: SizedSeq a -> a -> SizedSeq a addToSS (SizedSeq n r_xs) x = SizedSeq (n+1) (x:r_xs) +-- NB, important this is eta-expand so that foldl' is inlined. addListToSS :: SizedSeq a -> [a] -> SizedSeq a -addListToSS (SizedSeq n r_xs) xs - = SizedSeq (n + genericLength xs) (reverse xs ++ r_xs) +addListToSS s xs = foldl' addToSS s xs ssElts :: SizedSeq a -> [a] ssElts (SizedSeq _ r_xs) = reverse r_xs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a75c70e400751f54d76e4c6dd304cc5a76d1e0c2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a75c70e400751f54d76e4c6dd304cc5a76d1e0c2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 15:34:27 2025 From: gitlab at gitlab.haskell.org (Peter Trommler (@trommler)) Date: Fri, 31 Jan 2025 10:34:27 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/T25700 Message-ID: <679ced83899bb_36b39141bdec50823@gitlab.mail> Peter Trommler pushed new branch wip/T25700 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T25700 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 15:36:56 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 31 Jan 2025 10:36:56 -0500 Subject: [Git][ghc/ghc] Pushed new branch wip/specialise-assembler Message-ID: <679cee188d36c_36b39141bd745102e@gitlab.mail> Matthew Pickering pushed new branch wip/specialise-assembler at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/specialise-assembler You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 15:49:08 2025 From: gitlab at gitlab.haskell.org (sheaf (@sheaf)) Date: Fri, 31 Jan 2025 10:49:08 -0500 Subject: [Git][ghc/ghc][wip/T24359] WIP: another approach to 'fully solving' for tcSpecPrag Message-ID: <679cf0f498524_36b3916be37458327@gitlab.mail> sheaf pushed to branch wip/T24359 at Glasgow Haskell Compiler / GHC Commits: 8d333bcc by sheaf at 2025-01-31T16:48:59+01:00 WIP: another approach to 'fully solving' for tcSpecPrag - - - - - 2 changed files: - compiler/GHC/Tc/Gen/Sig.hs - testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs Changes: ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -39,7 +39,7 @@ import GHC.Tc.Gen.HsType import GHC.Tc.Solver( reportUnsolvedEqualities, pushLevelAndSolveEqualitiesX , emitResidualConstraints ) import GHC.Tc.Solver.Solve( solveWanteds ) -import GHC.Tc.Solver.Monad( runTcS, runTcSSpecPragWithEvBinds ) +import GHC.Tc.Solver.Monad( runTcS, runTcSWithEvBinds ) import GHC.Tc.Validity ( checkValidType ) import GHC.Tc.Utils.Monad @@ -57,6 +57,7 @@ import GHC.Tc.Zonk.TcType import GHC.Tc.Zonk.Type import GHC.Core( hasSomeUnfolding ) +import GHC.Core.FVs (exprSomeFreeVarsList) import GHC.Core.Type import GHC.Core.Multiplicity import GHC.Core.Predicate @@ -80,12 +81,15 @@ import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Data.Bag -import GHC.Data.Maybe( orElse, whenIsJust ) +import GHC.Data.Maybe( orElse, whenIsJust, expectJust ) import Control.Monad( unless ) import Data.Foldable ( toList ) +import qualified Data.Graph as Graph +import Data.List ((\\), nub) import qualified Data.List.NonEmpty as NE import Data.Maybe( mapMaybe ) +import qualified Data.Semigroup as S {- ------------------------------------------------------------- @@ -976,27 +980,67 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) let skol_info_anon = SpecESkol nm ; traceTc "tcSpecPrag SpecSigE 1" (ppr nm $$ ppr spec_e) ; skol_info <- mkSkolemInfo skol_info_anon - ; (rhs_tclvl, wanted, (rule_bndrs', (tc_spec_e, _rho))) + ; (rhs_tclvl, spec_e_wanted, (rule_bndrs', (tc_spec_e, _rho))) <- tcRuleBndrs skol_info rule_bndrs $ tcInferRho spec_e - -- (2) Simplify the constraints, in special TcSSpecPrag mode + -- (2) Solve the Wanteds that arose from typechecking spec_e, but + -- in a special way: every original Wanted should be either fully solved + -- or left untouched. + -- + -- We achieve this by: + -- + -- 2.1. Clone the wanteds that arose from typechecking spec_e. + -- + -- 2.2 Try to solve them, and look through the evidence to see which + -- ones we could fully solve. + -- + -- 2.3 Separate the original Wanteds into two groups, those that + -- we could fully solve and those that we couldn't + -- + -- The fully soluble ones get solved again (a bit wasteful). + -- The other ones either get quantified or emitted as residuals, + -- depending on whether they can be quantified (see 'getRuleQuantCts'.) + ; ev_binds_var_clone <- newTcEvBinds + ; spec_e_wanted_clone <- cloneWC spec_e_wanted + ; simpl_spec_e_wanted_clone <- setTcLevel rhs_tclvl $ + runTcSWithEvBinds ev_binds_var_clone $ + solveWanteds spec_e_wanted_clone + ; not_fully_solved <- + notFullySolvedWanteds ev_binds_var_clone simpl_spec_e_wanted_clone + + ; spec_e_wanted <- liftZonkM $ zonkWC spec_e_wanted + + ; let (fully_soluble1, other1) = + partitionWC + (\ ev_id -> not (ev_id `elemVarSet` not_fully_solved)) + spec_e_wanted + ; ev_binds_var <- newTcEvBinds - ; wanted <- setTcLevel rhs_tclvl $ - runTcSSpecPragWithEvBinds ev_binds_var $ - solveWanteds wanted + ; simpl_fully_soluble1 <- setTcLevel rhs_tclvl $ + runTcSWithEvBinds ev_binds_var $ + solveWanteds fully_soluble1 + ; massertPpr (isSolvedWC simpl_fully_soluble1) $ + vcat [ text "tcSpecPrag: fully soluble Wanteds couldn't be fully solved?" + , text "spec_e_wanted:" <+> ppr spec_e_wanted + , text "spec_e_wanted_clone:" <+> ppr spec_e_wanted_clone + , text "simpl_spec_e_wanted_clone:" <+> ppr simpl_spec_e_wanted_clone + , text "not_fully_solved:" <+> ppr not_fully_solved + , text "fully_soluble1:" <+> ppr fully_soluble1 + , text "other1:" <+> ppr other1 + , text "simpl_fully_soluble1:" <+> ppr simpl_fully_soluble1 + ] -- (3) Quantify over the constraints - ; qevs <- mapM newEvVar $ - ctsPreds $ - approximateWC False wanted + ; (quant_cts, residual) <- getRuleQuantCts other1 + ; let qevs = map ctEvId $ bagToList quant_cts -- (4) Emit the residual (non-quantified) constraints, -- and wrap the expression in the evidence let bindings ; let tv_bndrs = filter isTyVar rule_bndrs' ; emitResidualConstraints rhs_tclvl skol_info_anon ev_binds_var emptyVarSet tv_bndrs qevs - wanted + residual ; let lhs_call = mkLHsWrap (WpLet (TcEvBinds ev_binds_var)) tc_spec_e ; traceTc "tcSpecPrag:SpecSigE" $ @@ -1004,7 +1048,19 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) , text "rule_bndrs':" <+> ppr rule_bndrs' , text "qevs:" <+> ppr qevs , text "spec_e:" <+> ppr tc_spec_e - , text "inl:" <+> ppr inl ] + , text "inl:" <+> ppr inl + , text (replicate 40 '=') + , text "spec_e_wanted:" <+> ppr spec_e_wanted + , text "spec_e_wanted_clone:" <+> ppr spec_e_wanted_clone + , text "simpl_spec_e_wanted_clone:" <+> ppr simpl_spec_e_wanted_clone + , text "not_fully_solved:" <+> ppr not_fully_solved + , text "fully_soluble1:" <+> ppr fully_soluble1 + , text "other1:" <+> ppr other1 + , text "simpl_fully_soluble1:" <+> ppr simpl_fully_soluble1 + , text (replicate 40 '-') + , text "quant_cts:" <+> ppr quant_cts + , text "residual:" <+> ppr residual + ] ; return [SpecPragE { spe_fn_nm = nm , spe_fn_id = poly_id @@ -1015,6 +1071,67 @@ tcSpecPrag poly_id (SpecSigE nm rule_bndrs spec_e inl) tcSpecPrag _ prag = pprPanic "tcSpecPrag" (ppr prag) +-- | Figure out the 'EvId's of all the Wanted constraints that +-- are not fully solved, by inspecting their evidence terms. +notFullySolvedWanteds :: EvBindsVar -> WantedConstraints -> TcM VarSet +notFullySolvedWanteds ev_binds_var wc + = do { (unsolved_ids, ev_deps_edges) <- ev_binds_edges ev_binds_var wc + ; let (ev_graph, node_from_vertex, vertex_from_key) = Graph.graphFromEdges ev_deps_edges + evid_from_vertex v = case node_from_vertex v of ( ev_id, _, _ ) -> ev_id + reachable = mkVarSet + $ concatMap (map evid_from_vertex . toList) + $ Graph.dfs + (Graph.transposeG ev_graph) + (map (expectJust "tcSpecPrag (computing fully solved)" . vertex_from_key) unsolved_ids) + ; return reachable + } + +ev_binds_edges :: EvBindsVar -> WantedConstraints -> TcM ([EvId], [(EvId, EvId, [EvId])]) +ev_binds_edges ev_binds_var0 ( WC { wc_simple = cts, wc_impl = implics } ) + = do { ev_binds <- getTcEvBindsMap ev_binds_var0 + ; edges1 <- foldMapM ev_bind_edges (evBindMapBinds ev_binds) + ; let edges2 = foldMap (\ ct -> let i = ctEvId ct in ([i], [(i,i,[])])) cts + ; (insols3, edges3) <- foldMapM go_implic implics + ; return $ + edges2 S.<> ( insols3, edges1 S.<> edges3 ) + } + where + ev_bind_edges :: EvBind -> TcM [(EvId, EvId, [EvId])] + ev_bind_edges (EvBind { eb_lhs = ev_id, eb_rhs = body }) = do + ev_deps <- evVarsOfTermList body + return [(ev_id, ev_id, ev_deps)] + go_implic :: Implication -> TcM ([EvId], [(EvId, EvId, [EvId])]) + go_implic ( Implic { ic_binds = ev_binds_var, ic_wanted = wc }) = + ev_binds_edges ev_binds_var wc + +evVarsOfTermList :: EvTerm -> TcM [EvId] +evVarsOfTermList (EvExpr e) = return $ exprSomeFreeVarsList isEvVar e +evVarsOfTermList (EvTypeable _ ev) = + case ev of + EvTypeableTyCon _ e -> concatMapM evVarsOfTermList e + EvTypeableTyApp e1 e2 -> concatMapM evVarsOfTermList [e1,e2] + EvTypeableTrFun e1 e2 e3 -> concatMapM evVarsOfTermList [e1,e2,e3] + EvTypeableTyLit e -> evVarsOfTermList e +evVarsOfTermList (EvFun { et_given = givens, et_binds = tcev_binds, et_body = body_id }) = do + ev_binds <- + case tcev_binds of + TcEvBinds var -> evBindMapBinds <$> getTcEvBindsMap var + EvBinds binds -> return binds + return $ + nub $ + ( body_id : map evBindVar ( bagToList ev_binds ) ) \\ givens + +partitionWC :: (EvId -> Bool) -> WantedConstraints -> (WantedConstraints, WantedConstraints) +partitionWC f wc@(WC { wc_simple = cts, wc_impl = implics }) = + let (yes_cts, no_cts) = partitionBag (f . ctEvId) cts + (yes_impls, no_impls) = unzipBag $ mapBag f_impl implics + in ( wc { wc_simple = yes_cts, wc_impl = yes_impls } + , wc { wc_simple = no_cts, wc_impl = no_impls } ) + where + f_impl i@(Implic { ic_wanted = wc' }) = + let (yes, no) = partitionWC f wc' + in (i { ic_wanted = yes }, i { ic_wanted = no }) + -------------- tcSpecWrapper :: UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper -- A simpler variant of tcSubType, used for SPECIALISE pragmas ===================================== testsuite/tests/simplCore/should_compile/DsSpecPragmas.hs ===================================== @@ -78,6 +78,6 @@ f6 z = z == z -- Quantify over this same quantified constraint, but discharge the -- other dictionary constraints. -{-# SPECIALISE f6 :: ( forall x. ( Eq x, Eq ( T x ) ) => Eq ( f x ) ) => f Int -> Bool #-} +{-# SPECIALISE f6 :: ( forall y. ( Eq y, Eq ( T y ) ) => Eq ( g y ) ) => g Int -> Bool #-} -------------------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d333bcc657ec63845ab5098f882f8af3fc1964a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d333bcc657ec63845ab5098f882f8af3fc1964a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri Jan 31 15:51:41 2025 From: gitlab at gitlab.haskell.org (Matthew Pickering (@mpickering)) Date: Fri, 31 Jan 2025 10:51:41 -0500 Subject: [Git][ghc/ghc][wip/ghci-force-background] ghci: Force bytecode to be evaluated after loading Message-ID: <679cf18d1eb7b_36b391842d1c592f@gitlab.mail> Matthew Pickering pushed to branch wip/ghci-force-background at Glasgow Haskell Compiler / GHC Commits: e787cccf by Matthew Pickering at 2025-01-31T15:51:24+00:00 ghci: Force bytecode to be evaluated after loading Behaviour before: Bytecode is forced when you need it to evaluate an expression in the interpreter. Behaviour after: Bytecode is forced in parallel, in the background, after the initial load is completed. The goal is to increase percieved responsiveness of the interpreter after a reload. If you do a reload and at a later point perform evaluation, now the evaluation will start immediately, rather than waiting first for all the byte code to be compiled. Since the bytecode is evaluated in the background, the prompt can still be used like normal to evaluate expressions or perform other queries. The thunks are evaluated in parallel by creating a spark for each thunk, thus if another reload is perfomed then the sparks will be discarded as the thunks in question will no longer be evaluated. - - - - - 2 changed files: - compiler/GHC/Unit/Home/PackageTable.hs - ghc/GHCi/UI.hs Changes: ===================================== compiler/GHC/Unit/Home/PackageTable.hs ===================================== @@ -47,6 +47,7 @@ module GHC.Unit.Home.PackageTable -- ** More Traversal-based queries , hptCollectDependencies , hptCollectObjects + , hptCollectByteCode , hptCollectModules -- ** Memory dangerous queries @@ -248,6 +249,12 @@ hptCollectObjects HPT{table} = do return $ foldr ((:) . expectJust "collectObjects" . homeModInfoObject) [] hpt +hptCollectByteCode :: HomePackageTable -> IO [Linkable] +hptCollectByteCode HPT{table} = do + hpt <- readIORef table + return $ + catMaybes $ foldr ((:) . homeModInfoByteCode) [] hpt + -- | Collect all module ifaces in the HPT -- -- $O(n)$ in the number of modules in the HPT. ===================================== ghc/GHCi/UI.hs ===================================== @@ -94,6 +94,8 @@ import GHC.Unit.Finder as Finder import GHC.Unit.Module.Graph (filterToposortToModules) import GHC.Unit.Module.ModSummary +import GHC.Linker.Types + import GHC.Data.StringBuffer import GHC.Utils.Outputable import GHC.Utils.Logger @@ -176,6 +178,8 @@ import GHC.TopHandler ( topHandler ) import qualified GHC.Unit.Module.Graph as GHC +import GHC.Conc.Sync ( par, pseq, forkIO ) + ----------------------------------------------------------------------------- data GhciSettings = GhciSettings { @@ -2170,6 +2174,38 @@ afterLoad ok load_type = do modulesLoadedMsg ok loaded_mods load_type graph <- GHC.getModuleGraph setContextAfterLoad (isReload load_type) (Just graph) + forceByteCode + +-- | Force any compiled bytecode in the background +-- +-- During compilation the compiler leaves thunks when producing bytecode, so that +-- the result is not forced before it is needed. (Especially important when doing recompilation +-- checking) +-- +-- However, after the reload is complete, the interpreter will otherwise be idle, so +-- force those thunks in parallel so that when the user comes to write in the prompt +-- the response is faster. +-- +-- If a reload happens, then the thunks which have been sparked will no longer +-- be reachable. Therefore they will be gced so we do not need to explicitly terminate +-- the parallel work if a reload happens before we are finished. +forceByteCode :: GhciMonad m => m () +forceByteCode = do + hsc_env <- GHC.getSession + -- Spawn a new thread, so the thunks are forced completely in the background of the main thread + -- and we can get to the prompt as fast as possible. + void $ liftIO $ forkIO $ do + all_linkables <- (concat <$> traverse (hptCollectByteCode . homeUnitEnv_hpt) (hsc_HUG hsc_env)) + evaluate $ foldr (\x u -> force x `pseq` u) () all_linkables + + where + + force :: Linkable -> () + force (Linkable _ _ ps) = foldr (\a u -> force_part a `pseq` u) () ps + + force_part (LazyBCOs x _) = x `par` () + force_part _ = () + setContextAfterLoad :: GhciMonad m => Bool -> Maybe GHC.ModuleGraph -> m () setContextAfterLoad keep_ctxt Nothing = do View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e787cccf3461f7a6708b0cdd2540d1a36fd64845 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e787cccf3461f7a6708b0cdd2540d1a36fd64845 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: