[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: ghc-toolchain: detect PowerPC 64 bit ABI
by Marge Bot (@marge-bot) 01 Nov '25
by Marge Bot (@marge-bot) 01 Nov '25
01 Nov '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
f75ab223 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: detect PowerPC 64 bit ABI
Check preprocessor macro defined for ABI v2 and assume v1 otherwise.
Fixes #26521
- - - - -
d086c474 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: refactor, move lastLine to Utils
- - - - -
995dfe0d by Vladislav Zavialov at 2025-10-31T18:43:54-04:00
Tests for -Wduplicate-exports, -Wdodgy-exports
Add test cases for the previously untested diagnostics:
[GHC-51876] TcRnDupeModuleExport
[GHC-64649] TcRnNullExportedModule
This also revealed a typo (incorrect capitalization of "module") in the
warning text for TcRnDupeModuleExport, which is now fixed.
- - - - -
f6961b02 by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: reformat dyld source code
This commit reformats dyld source code with prettier, to avoid
introducing unnecessary diffs in subsequent patches when they're
formatted before committing.
- - - - -
0c9032a0 by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: simplify _initialize logic in dyld
This commit simplifies how we _initialize a wasm shared library in
dyld and removes special treatment for libc.so, see added comment for
detailed explanation.
- - - - -
ec1b40bd by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: support running dyld fully client side in the browser
This commit refactors the wasm dyld script so that it can be used to
load and run wasm shared libraries fully client-side in the browser
without needing a wasm32-wasi-ghci backend:
- A new `DyLDBrowserHost` class is exported, which runs in the browser
and uses the in-memory vfs without any RPC calls. This meant to be
used to create a `rpc` object for the fully client side use cases.
- The exported `main` function now can be used to load user-specified
shared libraries, and the user can use the returned `DyLD` instance
to run their own exported Haskell functions.
- The in-browser wasi implementation is switched to
https://github.com/haskell-wasm/browser_wasi_shim for bugfixes and
major performance improvements not landed upstream yet.
- When being run by deno, it now correctly switches to non-nodejs code
paths, so it's more convenient to test dyld logic with deno.
See added comments for details, as well as the added `playground001`
test case for an example of using it to build an in-browser Haskell
playground.
- - - - -
8f3e481f by Cheng Shao at 2025-11-01T00:08:01+01:00
testsuite: add playground001 to test haskell playground
This commit adds the playground001 test case to test the haskell
playground in browser, see comments for details.
- - - - -
af40606a by Cheng Shao at 2025-11-01T00:08:04+01:00
Revert "testsuite: add T26431 test case"
This reverts commit 695036686f8c6d78611edf3ed627608d94def6b7. T26431
is now retired, wasm ghc internal-interpreter logic is tested by
playground001.
- - - - -
21d446c5 by Vladislav Zavialov at 2025-11-01T01:23:22-04:00
Supplant TcRnExportHiddenComponents with TcRnDodgyExports (#26534)
Remove a bogus special case in lookup_ie_kids_all,
making TcRnExportHiddenComponents obsolete.
- - - - -
29 changed files:
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Types/Error/Codes.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- + testsuite/tests/ghc-api-browser/README.md
- + testsuite/tests/ghc-api-browser/all.T
- + testsuite/tests/ghc-api-browser/index.html
- + testsuite/tests/ghc-api-browser/playground001.hs
- + testsuite/tests/ghc-api-browser/playground001.js
- + testsuite/tests/ghc-api-browser/playground001.sh
- testsuite/tests/ghci-wasm/T26431.stdout → testsuite/tests/ghc-api-browser/playground001.stdout
- − testsuite/tests/ghci-wasm/T26431.hs
- testsuite/tests/ghci-wasm/all.T
- + testsuite/tests/warnings/should_compile/DodgyExports02.hs
- + testsuite/tests/warnings/should_compile/DodgyExports02.stderr
- + testsuite/tests/warnings/should_compile/DodgyExports03.hs
- + testsuite/tests/warnings/should_compile/DodgyExports03.stderr
- + testsuite/tests/warnings/should_compile/DuplicateModExport.hs
- + testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
- + testsuite/tests/warnings/should_compile/EmptyModExport.hs
- + testsuite/tests/warnings/should_compile/EmptyModExport.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/ghc-toolchain/ghc-toolchain.cabal
- utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
- + utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
- utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
- utils/jsffi/dyld.mjs
Changes:
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -619,7 +619,7 @@ instance Diagnostic TcRnMessage where
TcRnDupeModuleExport mod
-> mkSimpleDecorated $
hsep [ text "Duplicate"
- , quotes (text "Module" <+> ppr mod)
+ , quotes (text "module" <+> ppr mod)
, text "in export list" ]
TcRnExportedModNotImported mod
-> mkSimpleDecorated
@@ -636,11 +636,6 @@ instance Diagnostic TcRnMessage where
$ formatExportItemError
(text "module" <+> ppr mod)
"is missing an export list"
- TcRnExportHiddenComponents export_item
- -> mkSimpleDecorated
- $ formatExportItemError
- (ppr export_item)
- "attempts to export constructors or class methods that are not visible here"
TcRnExportHiddenDefault export_item
-> mkSimpleDecorated
$ formatExportItemError
@@ -2231,8 +2226,6 @@ instance Diagnostic TcRnMessage where
-> WarningWithFlag Opt_WarnDodgyExports
TcRnMissingExportList{}
-> WarningWithFlag Opt_WarnMissingExportList
- TcRnExportHiddenComponents{}
- -> ErrorWithoutFlag
TcRnExportHiddenDefault{}
-> ErrorWithoutFlag
TcRnDuplicateExport{}
@@ -2904,8 +2897,6 @@ instance Diagnostic TcRnMessage where
-> noHints
TcRnMissingExportList{}
-> noHints
- TcRnExportHiddenComponents{}
- -> noHints
TcRnExportHiddenDefault{}
-> noHints
TcRnDuplicateExport{}
=====================================
compiler/GHC/Tc/Errors/Types.hs
=====================================
@@ -1567,10 +1567,11 @@ data TcRnMessage where
occurs when a module appears more than once in an export list.
Example(s):
- module Foo (module Bar, module Bar)
- import Bar
+ module Foo (module Bar, module Bar) where
+ import Bar
- Text cases: None
+ Text cases:
+ DuplicateModExport
-}
TcRnDupeModuleExport :: ModuleName -> TcRnMessage
@@ -1590,10 +1591,11 @@ data TcRnMessage where
when an export list contains a module that has no exports.
Example(s):
- module Foo (module Bar) where
- import Bar ()
+ module Foo (module Bar) where
+ import Bar ()
- Test cases: None
+ Test cases:
+ EmptyModExport
-}
TcRnNullExportedModule :: ModuleName -> TcRnMessage
@@ -1606,15 +1608,6 @@ data TcRnMessage where
-}
TcRnMissingExportList :: ModuleName -> TcRnMessage
- {-| TcRnExportHiddenComponents is an error that occurs when an export contains
- constructor or class methods that are not visible.
-
- Example(s): None
-
- Test cases: None
- -}
- TcRnExportHiddenComponents :: IE GhcPs -> TcRnMessage
-
{-| TcRnExportHiddenDefault is an error that occurs when an export contains
a class default (with language extension NamedDefaults) that is not visible.
=====================================
compiler/GHC/Tc/Gen/Export.hs
=====================================
@@ -526,7 +526,7 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
} (L loc ie@(IEThingAll (warn_txt_ps, ann) l doc))
= do mb_gre <- lookupGreAvailRn (ieLWrappedNameWhatLooking l) $ lieWrappedName l
for mb_gre $ \ par -> do
- all_kids <- lookup_ie_kids_all ie l par
+ all_kids <- lookup_ie_kids_all l par
let name = greName par
all_gres = par : all_kids
all_names = map greName all_gres
@@ -562,7 +562,7 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
wc_kids <-
case wc of
NoIEWildcard -> return []
- IEWildcard _ -> lookup_ie_kids_all ie l par
+ IEWildcard _ -> lookup_ie_kids_all l par
let name = greName par
all_kids = with_kids ++ wc_kids
@@ -595,20 +595,15 @@ exports_from_avail (Just (L _ rdr_items)) rdr_env imports this_mod
; kids <- lookupChildrenExport gre child_gres sub_rdrs
; return (unzip kids) }
- lookup_ie_kids_all :: IE GhcPs -> LIEWrappedName GhcPs -> GlobalRdrElt
+ lookup_ie_kids_all :: LIEWrappedName GhcPs -> GlobalRdrElt
-> RnM [GlobalRdrElt]
- lookup_ie_kids_all ie (L _loc rdr) gre =
+ lookup_ie_kids_all (L _loc rdr) gre =
do { let name = greName gre
gres = findChildren kids_env name
-- We only choose level 0 exports when filling in part of an export list implicitly.
; let kids_0 = mapMaybe pickLevelZeroGRE gres
; addUsedKids (ieWrappedName rdr) kids_0
- ; when (null kids_0) $
- if isTyConName name
- then addTcRnDiagnostic (TcRnDodgyExports gre)
- else -- This occurs when you export T(..), but
- -- only import T abstractly, or T is a synonym.
- addErr (TcRnExportHiddenComponents ie)
+ ; when (null kids_0) $ addTcRnDiagnostic (TcRnDodgyExports gre)
; return kids_0 }
-------------
=====================================
compiler/GHC/Types/Error/Codes.hs
=====================================
@@ -505,7 +505,7 @@ type family GhcDiagnosticCode c = n | n -> c where
GhcDiagnosticCode "TcRnExportedModNotImported" = 90973
GhcDiagnosticCode "TcRnNullExportedModule" = 64649
GhcDiagnosticCode "TcRnMissingExportList" = 85401
- GhcDiagnosticCode "TcRnExportHiddenComponents" = 94558
+ GhcDiagnosticCode "TcRnExportHiddenComponents" = Outdated 94558
GhcDiagnosticCode "TcRnExportHiddenDefault" = 74775
GhcDiagnosticCode "TcRnDuplicateExport" = 47854
GhcDiagnosticCode "TcRnDuplicateNamedDefaultExport" = 31584
=====================================
testsuite/tests/diagnostic-codes/codes.stdout
=====================================
@@ -50,9 +50,6 @@
[GHC-17268] is untested (constructor = TcRnCharLiteralOutOfRange)
[GHC-36495] is untested (constructor = TcRnTagToEnumMissingValArg)
[GHC-55868] is untested (constructor = TcRnArrowIfThenElsePredDependsOnResultTy)
-[GHC-51876] is untested (constructor = TcRnDupeModuleExport)
-[GHC-64649] is untested (constructor = TcRnNullExportedModule)
-[GHC-94558] is untested (constructor = TcRnExportHiddenComponents)
[GHC-63055] is untested (constructor = TcRnFieldUpdateInvalidType)
[GHC-26133] is untested (constructor = TcRnForeignImportPrimSafeAnn)
[GHC-03355] is untested (constructor = TcRnIllegalForeignDeclBackend)
=====================================
testsuite/tests/ghc-api-browser/README.md
=====================================
@@ -0,0 +1,124 @@
+# The Haskell playground browser test
+
+This directory contains the `playground001` test, which builds a fully
+client side Haskell playground in the browser, then runs a
+puppeteer-based test to actually interpret a Haskell program in a
+headless browser.
+
+## Headless testing
+
+`playground001` is tested in GHC CI. To test it locally, first ensure
+you've set up the latest
+[`ghc-wasm-meta`](https://gitlab.haskell.org/haskell-wasm/ghc-wasm-meta)
+toolchain and sourced the `~/.ghc-wasm/env` script, so the right
+`node` with the right pre-installed libraries are used. Additionally,
+you need to install latest Firefox and:
+
+```sh
+export FIREFOX_LAUNCH_OPTS='{"browser":"firefox","executablePath":"/usr/bin/firefox"}'`
+```
+
+Or on macOS:
+
+```sh
+export FIREFOX_LAUNCH_OPTS='{"browser":"firefox","executablePath":"/Applications/Firefox.app/Contents/MacOS/firefox"}'
+```
+
+Without `FIREFOX_LAUNCH_OPTS`, `playground001` is skipped.
+
+It's possible to test against Chrome as well, the
+[`playground001.js`](./playground001.js) test driver doesn't assume
+anything Firefox-specific, it just takes the
+[`puppeteer.launch`](https://pptr.dev/api/puppeteer.puppeteernode.launch)
+options as JSON passed via command line.
+
+`playground001` works on latest versions of Firefox/Chrome/Safari.
+
+## Manual testing
+
+The simplest way to build the playground manually and run it in a
+browser tab is to test it once with `--only=playground001
+--keep-test-files` passed to Hadrian, then you can find the temporary
+directory containing [`index.html`](./index.html), `rootfs.tar.zst`
+etc, then fire up a dev web server and load it.
+
+Additionally, you can build the playground in tree without invoking
+the GHC testsuite. Just build GHC with the wasm target first, then
+copy `utils/jsffi/*.mjs` here and run
+[`./playground001.sh`](./playground001.sh) script. You need to set
+`TEST_CC` to the path of `wasm32-wasi-clang` and `TEST_HC` to the path
+of `wasm32-wasi-ghc`, that's it.
+
+## Customized Haskell playground
+
+You may want to build a customized Haskell playground that uses GHC
+API to interpret Haskell code with custom packages, here are some tips
+to get started:
+
+- Read the code in this directory and figure out how `playground001`
+ itself works.
+- [`./playground001.sh`](./playground001.sh) can be used as a basis to
+ write your own build/test script.
+
+You don't need to read the full `dyld.mjs` script. The user-facing
+things that are relevant to the playground use case are:
+
+- `export class DyLDBrowserHost`: it is the `rpc` object required when
+ calling `main`. You need to pass `stdout`/`stderr` callbacks to
+ write each line of stdout/stderr, as well as a `rootfs` object that
+ represents an in-memory vfs containing the shared libraries to load.
+- `export async function main`: it eventually returns a `DyLD` object
+ that can be used like `await
+ dyld.exportFuncs.myExportedHaskellFunc(js_foo, js_bar)` to invoke
+ your exported Haskell function.
+
+Check the source code of [`index.html`](./index.html) and cross
+reference [`playground001.hs`](./playground001.hs) for the example of
+how they are used.
+
+The `rootfs` object is a
+[`PreopenDirectory`](https://github.com/haskell-wasm/browser_wasi_shim/blob/master/src/fs_mem.ts)
+object in the
+[`browser_wasi_shim`](https://github.com/haskell-wasm/browser_wasi_shim)
+library. The Haskell playground needs a complex vfs containing many
+files (shared libraries, interface files, package databases, etc), so
+to speed things up, the whole vfs is compressed into a
+`rootfs.tar.zst` archive, then that archive is extracted using
+[`bsdtar-wasm`](https://github.com/haskell-wasm/bsdtar-wasm).
+
+You don't need to read the source code of `browser_wasi_shim`; you can
+simply paste and adapt the relevant code snippet in
+[`index.html`](./index.html) to create the right `rootfs` object from
+a tarball.
+
+The main concern is what do you need to pack into `rootfs.tar.zst`.
+For `playground001`, it contains:
+
+- `/tmp/clib`: the C/C++ shared libraries
+- `/tmp/hslib/lib`: the GHC libdir
+- `/tmp/libplayground001.so`: the main shared library to start loading
+ that exports `myMain`
+
+You can read [`./playground001.sh`](./playground001.sh) to figure out
+the details of how I prepare `rootfs.tar.zst` and trim unneeded files
+to minimize the tarball size.
+
+There are multiple possible ways to install third-party packages in
+the playground:
+
+- Start from a `wasm32-wasi-ghc` installation, use `wasm32-wasi-cabal
+ v1-install --global` to install everything to the global package
+ database. In theory this is the simplest way, though I haven't tried
+ it myself and it's unclear to what extent do `v1` commands work
+ these days.
+- Use default nix-style installation, then package the cabal store and
+ `dist-newstyle` directories into `rootfs.tar.zst`, and pass the
+ right package database flags when calling GHC API.
+
+Note that cabal built packages are not relocatable! So things will
+break if you build them at a host location and then package into a
+different absolute path into the rootfs, keep this in mind.
+
+If you have any difficulties, you're welcome to the [Haskell
+Wasm](https://matrix.to/#/#haskell.wasm:matrix.org) matrix room for
+community support.
=====================================
testsuite/tests/ghc-api-browser/all.T
=====================================
@@ -0,0 +1,52 @@
+# makefile_test/run_command is skipped when config.target_wrapper is
+# not None, see test_common_work in testsuite/driver/testlib.py. for
+# now just use this workaround to run custom test script here; ideally
+# we'd fix test failures elsewhere and enable
+# makefile_test/run_command for cross targets some day.
+async def stub_run_command(name, way, cmd):
+ return await run_command(name, way, cmd)
+
+
+# config.target_wrapper is prepended when running any command when
+# testing a cross target, see simple_run in
+# testsuite/driver/testlib.py. this is problematic when running a host
+# test script. for now do this override; ideally we'd have clear
+# host/target distinction for command invocations in the testsuite
+# driver instead of just a command string.
+def override_target_wrapper(name, opts):
+ opts.target_wrapper = ""
+
+
+setTestOpts(
+ [
+ unless(arch("wasm32"), skip),
+ override_target_wrapper,
+ high_memory_usage,
+ ignore_stderr,
+ only_ways(["dyn"]),
+ extra_ways(["dyn"]),
+ ]
+)
+
+
+test(
+ "playground001",
+ [
+ # pretty heavyweight, just test one browser for now.
+ unless("FIREFOX_LAUNCH_OPTS" in ghc_env, skip),
+ extra_files(
+ [
+ "../../../.gitlab/hello.hs",
+ "../../../utils/jsffi/dyld.mjs",
+ "../../../utils/jsffi/post-link.mjs",
+ "../../../utils/jsffi/prelude.mjs",
+ "index.html",
+ "playground001.hs",
+ "playground001.js",
+ "playground001.sh",
+ ]
+ ),
+ ],
+ stub_run_command,
+ ['./playground001.sh "$FIREFOX_LAUNCH_OPTS"'],
+)
=====================================
testsuite/tests/ghc-api-browser/index.html
=====================================
@@ -0,0 +1,234 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <title>ghc-in-browser</title>
+ <link
+ rel="stylesheet"
+ href="https://cdn.jsdelivr.net/npm/modern-normalize/modern-normalize.min.css"
+ />
+ <style>
+ html,
+ body {
+ height: 100%;
+ }
+ body {
+ margin: 0;
+ font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
+ background: #0f172a;
+ color: #e5e7eb;
+ }
+ .app {
+ height: 100vh;
+ display: grid;
+ gap: 0.5rem;
+ padding: 0.5rem;
+ }
+ @media (min-width: 800px) {
+ .app {
+ grid-template-columns: 1fr 1fr;
+ }
+ }
+ @media (max-width: 799.98px) {
+ .app {
+ grid-template-rows: 1fr 1fr;
+ }
+ }
+ .pane {
+ background: #111827;
+ border: 1px solid #1f2937;
+ border-radius: 12px;
+ display: flex;
+ flex-direction: column;
+ min-height: 0;
+ }
+ header {
+ padding: 0.5rem 0.75rem;
+ border-bottom: 1px solid #1f2937;
+ font-weight: 600;
+ }
+ #editor {
+ flex: 1;
+ min-height: 0;
+ }
+ .right {
+ padding: 0.6rem;
+ gap: 0.6rem;
+ }
+ .controls {
+ display: flex;
+ gap: 0.5rem;
+ flex-wrap: wrap;
+ margin-bottom: 0.4rem;
+ }
+ .controls input[type="text"] {
+ flex: 1;
+ min-width: 200px;
+ background: #0b1020;
+ color: #e5e7eb;
+ border: 1px solid #223;
+ border-radius: 8px;
+ padding: 0.55rem;
+ }
+ .controls button {
+ background: #22c55e;
+ border: none;
+ border-radius: 8px;
+ padding: 0.55rem 0.85rem;
+ font-weight: 600;
+ cursor: pointer;
+ }
+ .outputs {
+ display: block;
+ }
+ .outputs .label {
+ font-size: 0.85rem;
+ opacity: 0.8;
+ margin: 0.35rem 0;
+ }
+ .outputs textarea {
+ display: block;
+ width: 100%;
+ min-height: 30vh;
+ background: #0b1020;
+ color: #d1fae5;
+ border: 1px solid #223;
+ border-radius: 8px;
+ padding: 0.6rem;
+ resize: vertical;
+ }
+ .stderr {
+ color: #fee2e2;
+ }
+ </style>
+
+ <script async type="module">
+ import * as monaco from "https://cdn.jsdelivr.net/npm/monaco-editor/+esm";
+ import {
+ ConsoleStdout,
+ File,
+ OpenFile,
+ PreopenDirectory,
+ WASI,
+ } from "https://esm.sh/gh/haskell-wasm/browser_wasi_shim";
+ import { DyLDBrowserHost, main } from "./dyld.mjs";
+
+ const rootfs = new PreopenDirectory("/", []);
+
+ const bsdtar_wasi = new WASI(
+ ["bsdtar.wasm", "-x"],
+ [],
+ [
+ new OpenFile(new File(new Uint8Array(), { readonly: true })),
+ ConsoleStdout.lineBuffered((msg) => console.info(msg)),
+ ConsoleStdout.lineBuffered((msg) => console.warn(msg)),
+ rootfs,
+ ],
+ { debug: false }
+ );
+
+ const [{ instance }, rootfs_bytes] = await Promise.all([
+ WebAssembly.instantiateStreaming(
+ fetch("https://haskell-wasm.github.io/bsdtar-wasm/bsdtar.wasm"),
+ { wasi_snapshot_preview1: bsdtar_wasi.wasiImport }
+ ),
+ fetch("./rootfs.tar.zst").then((r) => r.bytes()),
+ ]);
+
+ bsdtar_wasi.fds[0] = new OpenFile(
+ new File(rootfs_bytes, { readonly: true })
+ );
+ bsdtar_wasi.start(instance);
+
+ if (document.readyState === "loading") {
+ await new Promise((res) =>
+ document.addEventListener("DOMContentLoaded", res, { once: true })
+ );
+ }
+
+ window.editor = monaco.editor.create(document.getElementById("editor"), {
+ value: 'main :: IO ()\nmain = putStrLn "Hello, Haskell!"\n',
+ language: "haskell",
+ automaticLayout: true,
+ minimap: { enabled: false },
+ theme: "vs-dark",
+ fontSize: 14,
+ });
+
+ const dyld = await main({
+ rpc: new DyLDBrowserHost({
+ rootfs,
+ stdout: (msg) => {
+ document.getElementById("stdout").value += `${msg}\n`;
+ },
+ stderr: (msg) => {
+ document.getElementById("stderr").value += `${msg}\n`;
+ },
+ }),
+ searchDirs: [
+ "/tmp/clib",
+ "/tmp/hslib/lib/wasm32-wasi-ghc-9.15.20251024",
+ ],
+ mainSoPath: "/tmp/libplayground001.so",
+ args: ["libplayground001.so", "+RTS", "-c", "-RTS"],
+ isIserv: false,
+ });
+ const main_func = await dyld.exportFuncs.myMain("/tmp/hslib/lib");
+
+ document.getElementById("runBtn").addEventListener("click", async () => {
+ document.getElementById("runBtn").disabled = true;
+
+ try {
+ document.getElementById("stdout").value = "";
+ document.getElementById("stderr").value = "";
+
+ await main_func(
+ document.getElementById("ghcArgs").value,
+ editor.getValue()
+ );
+ } finally {
+ document.getElementById("runBtn").disabled = false;
+ }
+ });
+
+ document.getElementById("runBtn").disabled = false;
+ </script>
+ </head>
+ <body>
+ <div class="app">
+ <section class="pane">
+ <header>Haskell Source</header>
+ <div id="editor"></div>
+ </section>
+
+ <section class="pane right">
+ <header>Controls / Output</header>
+ <div class="controls">
+ <input
+ id="ghcArgs"
+ type="text"
+ placeholder="GHC args"
+ style="font-family: ui-monospace, Menlo, Consolas, monospace"
+ />
+ <button id="runBtn" disabled="true">Run</button>
+ </div>
+ <div class="outputs">
+ <div class="label">stdout</div>
+ <textarea
+ id="stdout"
+ readonly
+ style="font-family: ui-monospace, Menlo, Consolas, monospace"
+ ></textarea>
+ <div class="label">stderr</div>
+ <textarea
+ id="stderr"
+ class="stderr"
+ readonly
+ style="font-family: ui-monospace, Menlo, Consolas, monospace"
+ ></textarea>
+ </div>
+ </section>
+ </div>
+ </body>
+</html>
=====================================
testsuite/tests/ghc-api-browser/playground001.hs
=====================================
@@ -0,0 +1,95 @@
+module Playground
+ ( myMain,
+ )
+where
+
+import Control.Monad
+import Data.Coerce
+import Data.IORef
+import GHC
+import GHC.Driver.Config.Diagnostic
+import GHC.Driver.Errors
+import GHC.Driver.Errors.Types
+import GHC.Driver.Monad
+import GHC.Plugins
+import GHC.Runtime.Interpreter
+import GHC.Utils.Exception
+import GHC.Wasm.Prim
+
+newtype JSFunction t = JSFunction JSVal
+
+type ExportedMainFunction = JSString -> JSString -> IO ()
+
+-- main entry point of playground001, returns a js async function that
+-- takes ghc args and Main.hs content, interprets Main.hs and runs
+-- Main.main.
+myMain :: JSString -> IO (JSFunction ExportedMainFunction)
+myMain js_libdir =
+ defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
+ libdir <- evaluate $ fromJSString js_libdir
+ freeJSVal $ coerce js_libdir
+ -- we don't use runGhc since we want to share a session to be
+ -- reused.
+ session <- Session <$> newIORef undefined
+ -- save a fresh default dflags, otherwise user input ghc args are
+ -- not properly reset.
+ dflags0 <- flip reflectGhc session $ do
+ initGhcMonad (Just libdir)
+ dflags0 <- getSessionDynFlags
+ setSessionDynFlags $
+ dflags0
+ { ghcMode = CompManager,
+ backend = bytecodeBackend,
+ ghcLink = LinkInMemory,
+ verbosity = 1
+ }
+ getSessionDynFlags
+ -- this is always run in a forked thread. which is fine as long as
+ -- the sesssion is not reused concurrently, but it's up to the
+ -- caller in js to ensure that. we simply disable the run button
+ -- until each run completes in the playground ui logic.
+ toMainFunc $ \js_args js_src ->
+ defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
+ args <- evaluate $ words $ fromJSString js_args
+ freeJSVal $ coerce js_args
+ writeFile f $ fromJSString js_src
+ freeJSVal $ coerce js_src
+ -- it's fine to call withCleanupSession since it just cleans up
+ -- tmpfs for now. in the future if it does more cleanup that
+ -- makes the session state invalid for reuse, just remove it;
+ -- everything will be cleaned up anyway when the browser tab is
+ -- closed
+ flip reflectGhc session $ withCleanupSession $ do
+ setSessionDynFlags dflags0
+ logger0 <- getLogger
+ (dflags1, _, dynamicFlagWarnings) <-
+ parseDynamicFlags logger0 dflags0 $ map noLoc args
+ setSessionDynFlags dflags1
+ logger1 <- getLogger
+ liftIO
+ $ printOrThrowDiagnostics
+ logger1
+ (initPrintConfig dflags1)
+ (initDiagOpts dflags1)
+ $ GhcDriverMessage
+ <$> dynamicFlagWarnings
+ setTargets =<< (: []) <$> guessTarget f Nothing Nothing
+ r <- load LoadAllTargets
+ when (failed r) $ fail "load returned Failed"
+ setContext [IIDecl $ simpleImportDecl $ mkModuleName "Main"]
+ fhv <- compileExprRemote "Main.main"
+ hsc_env <- getSession
+ liftIO $ evalIO (hscInterp hsc_env) fhv
+ where
+ f = "/tmp/Main.hs"
+
+foreign import javascript "wrapper"
+ toMainFunc ::
+ ExportedMainFunction ->
+ IO (JSFunction ExportedMainFunction)
+
+foreign export javascript "myMain"
+ myMain ::
+ JSString ->
+ IO
+ (JSFunction ExportedMainFunction)
=====================================
testsuite/tests/ghc-api-browser/playground001.js
=====================================
@@ -0,0 +1,91 @@
+#!/usr/bin/env -S node
+
+const puppeteer = require("puppeteer-core");
+const fs = require("node:fs");
+const path = require("node:path");
+
+class Playground {
+ static #token = Symbol("Playground");
+ #browser;
+ #page;
+
+ static async create({ launchOpts, artifactDir }) {
+ const playground = new Playground(Playground.#token);
+ playground.#browser = await puppeteer.launch(launchOpts);
+
+ playground.#page = await playground.#browser.newPage();
+ await playground.#page.setRequestInterception(true);
+ playground.#page.on("request", async (req) => {
+ if (!req.url().startsWith("http://localhost")) {
+ return req.continue();
+ }
+
+ try {
+ const f = req.url().replace("http://localhost", artifactDir);
+ return req.respond({
+ status: 200,
+ contentType:
+ {
+ ".html": "text/html",
+ ".mjs": "application/javascript",
+ }[path.extname(f)] || "application/octet-stream",
+ body: await fs.promises.readFile(f),
+ });
+ } catch {
+ return req.abort();
+ }
+ });
+
+ await playground.#page.goto("http://localhost/index.html");
+ await playground.#page.locator("#runBtn:enabled").wait();
+ return playground;
+ }
+
+ async close() {
+ await this.#browser.close();
+ }
+
+ async runMain({ mainSrc, ghcArgs }) {
+ await Promise.all([
+ this.#page.evaluate((mainSrc) => editor.setValue(mainSrc), mainSrc),
+ this.#page.locator("#ghcArgs").fill(ghcArgs),
+ ]);
+ await this.#page.locator("#runBtn:enabled").click();
+ await this.#page.locator("#runBtn:enabled").wait();
+
+ const [stdout, stderr] = await Promise.all(
+ ["#stdout", "#stderr"].map((el) =>
+ this.#page
+ .locator(el)
+ .map((t) => t.value)
+ .wait()
+ )
+ );
+
+ return { stdout, stderr };
+ }
+
+ constructor(token) {
+ if (token !== Playground.#token) {
+ throw new Error("new Playground() is forbidden, use Playground.create()");
+ }
+ }
+}
+
+(async () => {
+ const playground = await Playground.create({
+ launchOpts: JSON.parse(process.argv[2]),
+ artifactDir: process.cwd(),
+ });
+
+ try {
+ const { stdout, stderr } = await playground.runMain({
+ mainSrc: await fs.promises.readFile("./hello.hs", { encoding: "utf-8" }),
+ ghcArgs: "-package ghc -v0",
+ });
+ process.stdout.write(stdout);
+ process.stderr.write(stderr);
+ } finally {
+ await playground.close();
+ }
+})();
=====================================
testsuite/tests/ghc-api-browser/playground001.sh
=====================================
@@ -0,0 +1,76 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+# also set this when building wasm32-wasi-ghc for production
+# deployment of haskell playground, so all the .so files are
+# optimized.
+export WASM_SO_OPT="--debuginfo --low-memory-unused --strip-dwarf -Oz"
+
+# we'll build a rootfs tarball that contains everything in tmp and
+# extracts to /tmp, mapped from here
+mkdir ./tmp
+
+$TEST_HC \
+ -v0 \
+ -package ghc \
+ -shared -dynamic \
+ -no-keep-hi-files -no-keep-o-files \
+ -O2 \
+ playground001.hs -o ./tmp/libplayground001.so
+rm -f ./*_stub.h ./playground001.hs
+
+# /tmp/clib contains libc/libc++ .so files
+cp -r "$(dirname "$TEST_CC")/../share/wasi-sysroot/lib/wasm32-wasi" ./tmp/clib
+# trim unneeded stuff in c libdir
+find ./tmp/clib -type f ! -name "*.so" -delete
+rm -f \
+ ./tmp/clib/libsetjmp.so \
+ ./tmp/clib/libwasi-emulated-*.so
+
+# /tmp/hslib/lib is the ghc libdir
+mkdir ./tmp/hslib
+cp -r "$($TEST_HC --print-libdir)" ./tmp/hslib/lib
+# unregister Cabal/Cabal-syntax, too big
+$GHC_PKG --no-user-package-db --global-package-db=./tmp/hslib/lib/package.conf.d unregister Cabal Cabal-syntax
+$GHC_PKG --no-user-package-db --global-package-db=./tmp/hslib/lib/package.conf.d recache
+# we only need non-profiling .dyn_hi/.so, trim as much as we can
+find ./tmp/hslib/lib "(" \
+ -name "*.hi" \
+ -o -name "*.a" \
+ -o -name "*.p_hi" \
+ -o -name "libHS*_p.a" \
+ -o -name "*.p_dyn_hi" \
+ -o -name "libHS*_p*.so" \
+ -o -name "libHSrts*_debug*.so" \
+ ")" -delete
+rm -rf \
+ ./tmp/hslib/lib/doc \
+ ./tmp/hslib/lib/html \
+ ./tmp/hslib/lib/latex \
+ ./tmp/hslib/lib/*.mjs \
+ ./tmp/hslib/lib/*.js \
+ ./tmp/hslib/lib/*.txt
+# HS_SEARCHDIR is something like
+# /tmp/hslib/lib/wasm32-wasi-ghc-9.15.20251024 which is the
+# dynamic-library-dirs that contains all libHS*.so in one place, and
+# also static libraries in per-unit directories
+HS_SEARCHDIR=$(find ./tmp/hslib/lib -type f -name "*.so" -print0 | xargs -0 -n1 dirname | sort -u | sed "s|^\./|/|")
+# hunt down the remaining bits of Cabal/Cabal-syntax. too bad there's
+# no ghc-pkg uninstall.
+rm -rf ."$HS_SEARCHDIR"/*Cabal*
+
+# fix the hard coded search dir in index.html
+SED_IS_GNU=$(sed --version &> /dev/null && echo 1 || echo 0)
+if [[ $SED_IS_GNU == "1" ]]; then
+ sed -i "s|/tmp/hslib/lib/wasm32-wasi-ghc-9.15.20251024|$HS_SEARCHDIR|" ./index.html
+else
+ sed -i "" "s|/tmp/hslib/lib/wasm32-wasi-ghc-9.15.20251024|$HS_SEARCHDIR|" ./index.html
+fi
+
+# also set ZSTD_NBTHREADS/ZSTD_CLEVEL when building for production
+tar -cf ./rootfs.tar.zst --zstd tmp
+rm -rf ./tmp
+
+# pass puppeteer.launch() opts as json
+exec ./playground001.js "$1"
=====================================
testsuite/tests/ghci-wasm/T26431.stdout → testsuite/tests/ghc-api-browser/playground001.stdout
=====================================
=====================================
testsuite/tests/ghci-wasm/T26431.hs deleted
=====================================
@@ -1,35 +0,0 @@
-import Control.Exception
-import Control.Monad.IO.Class
-import Data.Maybe
-import GHC
-import GHC.Plugins
-import GHC.Runtime.Interpreter
-import System.Environment.Blank
-
-main :: IO ()
-main = do
- [libdir] <- getArgs
- defaultErrorHandler defaultFatalMessager defaultFlushOut $
- runGhc (Just libdir) $
- do
- dflags0 <- getSessionDynFlags
- let dflags1 =
- dflags0
- { ghcMode = CompManager,
- backend = bytecodeBackend,
- ghcLink = LinkInMemory
- }
- logger <- getLogger
- (dflags2, _, _) <-
- parseDynamicFlags logger dflags1 $
- map noLoc ["-package", "ghc"]
- _ <- setSessionDynFlags dflags2
- addTarget =<< guessTarget "hello.hs" Nothing Nothing
- _ <- load LoadAllTargets
- setContext
- [ IIDecl $ simpleImportDecl $ mkModuleName "Prelude",
- IIDecl $ simpleImportDecl $ mkModuleName "Main"
- ]
- hsc_env <- getSession
- fhv <- compileExprRemote "main"
- liftIO $ evalIO (fromJust $ hsc_interp hsc_env) fhv
=====================================
testsuite/tests/ghci-wasm/all.T
=====================================
@@ -10,11 +10,3 @@ test('T26430', [
extra_hc_opts('-L. -lT26430B')]
, compile_and_run, ['']
)
-
-test('T26431', [
- extra_files(['../../../.gitlab/hello.hs']),
- extra_hc_opts('-package ghc'),
- extra_run_opts(f'"{config.libdir}"'),
- ignore_stderr]
-, compile_and_run, ['']
-)
=====================================
testsuite/tests/warnings/should_compile/DodgyExports02.hs
=====================================
@@ -0,0 +1,7 @@
+module DodgyExports02
+ ( Identity(..) -- type constructor has out-of-scope children
+ , Void(..) -- type constructor has no children
+ ) where
+
+import Data.Void (Void)
+import Data.Functor.Identity (Identity)
=====================================
testsuite/tests/warnings/should_compile/DodgyExports02.stderr
=====================================
@@ -0,0 +1,10 @@
+DodgyExports02.hs:2:5: warning: [GHC-75356] [-Wdodgy-exports (in -Wextra)]
+ The export item ‘Identity(..)’ suggests that
+ ‘Identity’ has (in-scope) constructors or record fields,
+ but it has none
+
+DodgyExports02.hs:3:5: warning: [GHC-75356] [-Wdodgy-exports (in -Wextra)]
+ The export item ‘Void(..)’ suggests that
+ ‘Void’ has (in-scope) constructors or record fields,
+ but it has none
+
=====================================
testsuite/tests/warnings/should_compile/DodgyExports03.hs
=====================================
@@ -0,0 +1,7 @@
+{-# LANGUAGE ExplicitNamespaces #-}
+
+module DodgyExports03
+ ( data MkR(..) -- data constructors never have children ('fld' belongs to 'R')
+ ) where
+
+data R = MkR { fld :: Int }
=====================================
testsuite/tests/warnings/should_compile/DodgyExports03.stderr
=====================================
@@ -0,0 +1,4 @@
+DodgyExports03.hs:4:5: warning: [GHC-75356] [-Wdodgy-exports (in -Wextra)]
+ The export item ‘MkR(..)’ suggests that
+ ‘MkR’ has children, but it is not a type constructor or a class
+
=====================================
testsuite/tests/warnings/should_compile/DuplicateModExport.hs
=====================================
@@ -0,0 +1,3 @@
+module DuplicateModExport (module L, module L) where
+
+import Data.List as L
=====================================
testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
=====================================
@@ -0,0 +1,3 @@
+DuplicateModExport.hs:1:38: warning: [GHC-51876] [-Wduplicate-exports (in -Wdefault)]
+ Duplicate ‘module L’ in export list
+
=====================================
testsuite/tests/warnings/should_compile/EmptyModExport.hs
=====================================
@@ -0,0 +1,3 @@
+module EmptyModExport (module L) where
+
+import Data.List as L ()
=====================================
testsuite/tests/warnings/should_compile/EmptyModExport.stderr
=====================================
@@ -0,0 +1,3 @@
+EmptyModExport.hs:1:24: warning: [GHC-64649] [-Wdodgy-exports (in -Wextra)]
+ The export item ‘module L’ exports nothing
+
=====================================
testsuite/tests/warnings/should_compile/all.T
=====================================
@@ -54,6 +54,8 @@ test('T19564d', normal, compile, [''])
# Also, suppress uniques as one of the warnings is unstable in CI, otherwise.
test('T19296', normal, compile, ['-fdiagnostics-show-caret -Wredundant-constraints -dsuppress-uniques'])
test('DodgyExports01', normal, compile, ['-Wdodgy-exports'])
+test('DodgyExports02', normal, compile, ['-Wdodgy-exports'])
+test('DodgyExports03', normal, compile, ['-Wdodgy-exports'])
test('DerivingTypeable', normal, compile, ['-Wderiving-typeable'])
test('T18862a', normal, compile, [''])
test('T18862b', normal, compile, [''])
@@ -72,3 +74,5 @@ test('T23465', normal, compile, ['-ddump-parsed'])
test('WarnNoncanonical', normal, compile, [''])
test('T24396', [extra_files(["T24396a.hs", "T24396b.hs"])], multimod_compile, ['T24396b', ''])
test('SpecMultipleTys', normal, compile, ['']) # compile_fail from GHC 9.18
+test('DuplicateModExport', normal, compile, ['-Wduplicate-exports'])
+test('EmptyModExport', normal, compile, ['-Wdodgy-exports'])
=====================================
utils/ghc-toolchain/ghc-toolchain.cabal
=====================================
@@ -21,6 +21,7 @@ library
GHC.Toolchain.NormaliseTriple,
GHC.Toolchain.CheckArm,
GHC.Toolchain.Target,
+ GHC.Toolchain.CheckPower
GHC.Toolchain.Tools.Ar,
GHC.Toolchain.Tools.Cc,
GHC.Toolchain.Tools.Cxx,
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
=====================================
@@ -8,6 +8,7 @@ import System.Process
import GHC.Platform.ArchOS
import GHC.Toolchain.Prelude
+import GHC.Toolchain.Utils (lastLine)
import GHC.Toolchain.Tools.Cc
-- | Awkwardly, ARM triples sometimes contain insufficient information about
@@ -75,10 +76,6 @@ findArmIsa cc = do
"False" -> return False
_ -> throwE $ "unexpected output from test program: " ++ out
-lastLine :: String -> String
-lastLine "" = ""
-lastLine s = last $ lines s
-
-- | Raspbian unfortunately makes some extremely questionable packaging
-- decisions, configuring gcc to compile for ARMv6 despite the fact that the
-- Raspberry Pi 4 is ARMv8. As ARMv8 doesn't support all instructions supported
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
=====================================
@@ -0,0 +1,29 @@
+module GHC.Toolchain.CheckPower ( checkPowerAbi ) where
+
+import GHC.Platform.ArchOS
+
+import GHC.Toolchain.Prelude
+import GHC.Toolchain.Utils (lastLine)
+import GHC.Toolchain.Tools.Cc
+
+-- 64-Bit ELF V2 ABI Specification, Power Architecture, Revision 1.5 says:
+-- A C preprocessor that conforms to this ABI shall predefine the macro
+-- _CALL_ELF to have a value of 2 (Section 5.1.4 Predifined Macros).
+-- The 64-bit PowerPC ELF Application Binary Interface Supplement 1.9
+-- does not define any macro to identify the ABI.
+-- So we check for ABI version 2 and default to ABI version 1.
+
+checkPowerAbi :: Cc -> M Arch
+checkPowerAbi cc = do
+ checking "POWER ELF ABI" $ do
+ out <- fmap lastLine $ preprocess cc $ unlines
+ [ "#if defined(_CALL_ELF) && _CALL_ELF == 2"
+ , "ELFv2"
+ , "#else"
+ , "ELFv1"
+ , "#endif"
+ ]
+ case out of
+ "ELFv1" -> pure $ ArchPPC_64 ELF_V1
+ "ELFv2" -> pure $ ArchPPC_64 ELF_V2
+ _ -> throwE $ "unexpected output from test program: " ++ out
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
=====================================
@@ -6,6 +6,7 @@ import GHC.Platform.ArchOS
import GHC.Toolchain.Prelude
import GHC.Toolchain.CheckArm
+import GHC.Toolchain.CheckPower
import GHC.Toolchain.Tools.Cc
-- | Parse a triple `arch-vendor-os` into an 'ArchOS' and a vendor name 'String'
@@ -40,7 +41,7 @@ parseArch cc arch =
"x86_64" -> pure ArchX86_64
"amd64" -> pure ArchX86_64
"powerpc" -> pure ArchPPC
- "powerpc64" -> pure (ArchPPC_64 ELF_V1)
+ "powerpc64" -> checkPowerAbi cc
"powerpc64le" -> pure (ArchPPC_64 ELF_V2)
"s390x" -> pure ArchS390X
"arm" -> findArmIsa cc
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
=====================================
@@ -8,6 +8,7 @@ module GHC.Toolchain.Utils
, oneOf
, oneOf'
, isSuccess
+ , lastLine
) where
import Control.Exception
@@ -65,3 +66,6 @@ isSuccess = \case
ExitSuccess -> True
ExitFailure _ -> False
+lastLine :: String -> String
+lastLine "" = ""
+lastLine s = last $ lines s
=====================================
utils/jsffi/dyld.mjs
=====================================
@@ -285,7 +285,7 @@ function originFromServerAddress({ address, family, port }) {
}
// Browser/node portable code stays above this watermark.
-const isNode = Boolean(globalThis?.process?.versions?.node);
+const isNode = Boolean(globalThis?.process?.versions?.node && !globalThis.Deno);
// Too cumbersome to only import at use sites. Too troublesome to
// factor out browser-only/node-only logic into different modules. For
@@ -307,27 +307,27 @@ if (isNode) {
ws = require("ws");
} catch {}
} else {
- wasi = await import(
- "https://cdn.jsdelivr.net/npm/@bjorn3/browser_wasi_shim@0.4.2/dist/index.js"
- );
+ wasi = await import("https://esm.sh/gh/haskell-wasm/browser_wasi_shim");
}
// A subset of dyld logic that can only be run in the host node
// process and has full access to local filesystem
-class DyLDHost {
+export class DyLDHost {
// Deduped absolute paths of directories where we lookup .so files
#rpaths = new Set();
- constructor() {
- // Inherited pipe file descriptors from GHC
- const out_fd = Number.parseInt(process.argv[4]),
- in_fd = Number.parseInt(process.argv[5]);
-
+ constructor({ outFd, inFd }) {
+ // When running a non-iserv shared library with node, the DyLDHost
+ // instance is created without a pair of fds, so skip creation of
+ // readStream/writeStream, they won't be used anyway
+ if (!(typeof outFd === "number" && typeof inFd === "number")) {
+ return;
+ }
this.readStream = stream.Readable.toWeb(
- fs.createReadStream(undefined, { fd: in_fd })
+ fs.createReadStream(undefined, { fd: inFd })
);
this.writeStream = stream.Writable.toWeb(
- fs.createWriteStream(undefined, { fd: out_fd })
+ fs.createWriteStream(undefined, { fd: outFd })
);
}
@@ -377,6 +377,72 @@ class DyLDHost {
}
}
+// Runs in the browser and uses the in-memory vfs, doesn't do any RPC
+// calls
+export class DyLDBrowserHost {
+ // Deduped absolute paths of directories where we lookup .so files
+ #rpaths = new Set();
+ // The PreopenDirectory object of the root filesystem
+ rootfs;
+ // Continuations to output a single line to stdout/stderr
+ stdout;
+ stderr;
+
+ // Given canonicalized absolute file path, returns the File object,
+ // or null if absent
+ #readFile(p) {
+ const { ret, entry } = this.rootfs.dir.get_entry_for_path({
+ parts: p.split("/").filter((tok) => tok !== ""),
+ is_dir: false,
+ });
+ return ret === 0 ? entry : null;
+ }
+
+ constructor({ rootfs, stdout, stderr }) {
+ this.rootfs = rootfs
+ ? rootfs
+ : new wasi.PreopenDirectory("/", [["tmp", new wasi.Directory([])]]);
+ this.stdout = stdout ? stdout : (msg) => console.info(msg);
+ this.stderr = stderr ? stderr : (msg) => console.warn(msg);
+ }
+
+ // p must be canonicalized absolute path
+ async addLibrarySearchPath(p) {
+ this.#rpaths.add(p);
+ return null;
+ }
+
+ async findSystemLibrary(f) {
+ if (f.startsWith("/")) {
+ if (this.#readFile(f)) {
+ return f;
+ }
+ throw new Error(`findSystemLibrary(${f}): not found in /`);
+ }
+
+ for (const rpath of this.#rpaths) {
+ const r = `${rpath}/${f}`;
+ if (this.#readFile(r)) {
+ return r;
+ }
+ }
+
+ throw new Error(
+ `findSystemLibrary(${f}): not found in ${[...this.#rpaths]}`
+ );
+ }
+
+ async fetchWasm(p) {
+ const entry = this.#readFile(p);
+ const r = new Response(entry.data, {
+ headers: { "Content-Type": "application/wasm" },
+ });
+ // It's only fetched once, take the chance to prune it in vfs to save memory
+ entry.data = new Uint8Array();
+ return r;
+ }
+}
+
// Fulfill the same functionality as DyLDHost by doing fetch() calls
// to respective RPC endpoints of a host http server. Also manages
// WebSocket connections back to host.
@@ -494,7 +560,7 @@ export class DyLDRPC {
// Actual implementation of endpoints used by DyLDRPC
class DyLDRPCServer {
- #dyldHost = new DyLDHost();
+ #dyldHost;
#server;
#wss;
@@ -502,11 +568,15 @@ class DyLDRPCServer {
host,
port,
dyldPath,
- libdir,
- ghciSoPath,
+ searchDirs,
+ mainSoPath,
+ outFd,
+ inFd,
args,
redirectWasiConsole,
}) {
+ this.#dyldHost = new DyLDHost({ outFd, inFd });
+
this.#server = http.createServer(async (req, res) => {
const origin = originFromServerAddress(await this.listening);
@@ -540,7 +610,7 @@ class DyLDRPCServer {
res.end(
`
import { DyLDRPC, main } from "./fs${dyldPath}";
-const args = ${JSON.stringify({ libdir, ghciSoPath, args })};
+const args = ${JSON.stringify({ searchDirs, mainSoPath, args, isIserv: true })};
args.rpc = new DyLDRPC({origin: "${origin}", redirectWasiConsole: ${redirectWasiConsole}});
args.rpc.opened.then(() => main(args));
`
@@ -829,11 +899,37 @@ class DyLD {
),
wasi.ConsoleStdout.lineBuffered((msg) => this.#rpc.stdout(msg)),
wasi.ConsoleStdout.lineBuffered((msg) => this.#rpc.stderr(msg)),
+ // for ghci browser mode, default to an empty rootfs with
+ // /tmp
+ this.#rpc instanceof DyLDBrowserHost
+ ? this.#rpc.rootfs
+ : new wasi.PreopenDirectory("/", [["tmp", new wasi.Directory([])]]),
],
{ debug: false }
);
}
+ // Both wasi implementations we use provide
+ // wasi.initialize(instance) to initialize a wasip1 reactor
+ // module. However, instance does not really need to be a
+ // WebAssembly.Instance object; the wasi implementations only need
+ // to access instance.exports.memory for the wasi syscalls to
+ // work.
+ //
+ // Given we'll reuse the same wasi object across different
+ // WebAssembly.Instance objects anyway and
+ // wasi.initialize(instance) can't be called more than once, we
+ // use this simple trick and pass a fake instance object that
+ // contains just enough info for the wasi implementation to
+ // initialize its internal state. Later when we load each wasm
+ // shared library, we can just manually invoke their
+ // initialization functions.
+ this.#wasi.initialize({
+ exports: {
+ memory: this.#memory,
+ },
+ });
+
// Keep this in sync with rts/wasm/Wasm.S!
for (let i = 1; i <= 10; ++i) {
this.#regs[`__R${i}`] = new WebAssembly.Global({
@@ -930,10 +1026,15 @@ class DyLD {
async loadDLLs(packed) {
// Normalize input to an array of strings. When called from Haskell
// we pass a single JSString containing NUL-separated paths.
- const paths = (typeof packed === "string"
- ? (packed.length === 0 ? [] : packed.split("\0"))
- : [packed] // tolerate an accidental single path object
- ).filter((s) => s.length > 0).reverse();
+ const paths = (
+ typeof packed === "string"
+ ? packed.length === 0
+ ? []
+ : packed.split("\0")
+ : [packed]
+ ) // tolerate an accidental single path object
+ .filter((s) => s.length > 0)
+ .reverse();
// Compute a single downsweep plan for the whole batch.
// Note: #downsweep mutates #loadedSos to break cycles and dedup.
@@ -1154,22 +1255,6 @@ class DyLD {
throw new Error(`cannot handle export ${k} ${v}`);
}
- // We call wasi.initialize when loading libc.so, then reuse the
- // wasi instance globally. When loading later .so files, just
- // manually invoke _initialize().
- if (soname === "libc.so") {
- instance.exports.__wasm_apply_data_relocs();
- // wasm-ld forbits --export-memory with --shared, I don't know
- // why but this is sufficient to make things work
- this.#wasi.initialize({
- exports: {
- memory: this.#memory,
- _initialize: instance.exports._initialize,
- },
- });
- continue;
- }
-
// See
// https://gitlab.haskell.org/haskell-wasm/llvm-project/-/blob/release/21.x/ll…,
// __wasm_apply_data_relocs is now optional so only call it if
@@ -1180,7 +1265,7 @@ class DyLD {
// been called upon instantiation, see
// Writer::createStartFunction().
if (instance.exports.__wasm_apply_data_relocs) {
- instance.exports.__wasm_apply_data_relocs();
+ instance.exports.__wasm_apply_data_relocs();
}
instance.exports._initialize();
@@ -1208,15 +1293,38 @@ class DyLD {
}
}
-export async function main({ rpc, libdir, ghciSoPath, args }) {
+// The main entry point of dyld that may be run on node/browser, and
+// may run either iserv defaultMain from the ghci library or an
+// alternative entry point from another shared library
+export async function main({
+ rpc, // Handle the side effects of DyLD
+ searchDirs, // Initial library search directories
+ mainSoPath, // Could also be another shared library that's actually not ghci
+ args, // WASI argv starting with the executable name. +RTS etc will be respected
+ isIserv, // set to true when running iserv defaultServer
+}) {
try {
const dyld = new DyLD({
- args: ["dyld.so", ...args],
+ args,
rpc,
});
- await dyld.addLibrarySearchPath(libdir);
- await dyld.loadDLLs(ghciSoPath);
+ for (const libdir of searchDirs) {
+ await dyld.addLibrarySearchPath(libdir);
+ }
+ await dyld.loadDLLs(mainSoPath);
+
+ // At this point, rts/ghc-internal are loaded, perform wasm shared
+ // library specific RTS startup logic, see Note [JSFFI initialization]
+ dyld.exportFuncs.__ghc_wasm_jsffi_init();
+
+ // We're not running iserv, just return the dyld instance so user
+ // could use it to invoke their exported functions, and don't
+ // perform cleanup (see finally block)
+ if (!isIserv) {
+ return dyld;
+ }
+ // iserv-specific logic follows
const reader = rpc.readStream.getReader();
const writer = rpc.writeStream.getWriter();
@@ -1235,31 +1343,25 @@ export async function main({ rpc, libdir, ghciSoPath, args }) {
writer.write(new Uint8Array(buf));
};
- dyld.exportFuncs.__ghc_wasm_jsffi_init();
- await dyld.exportFuncs.defaultServer(cb_sig, cb_recv, cb_send);
+ return await dyld.exportFuncs.defaultServer(cb_sig, cb_recv, cb_send);
} finally {
- rpc.close();
+ if (isIserv) {
+ rpc.close();
+ }
}
}
-(async () => {
- if (!isNode) {
- return;
- }
-
- const libdir = process.argv[2];
- const ghciSoPath = process.argv[3];
- const args = process.argv.slice(6);
-
+// node-specific iserv-specific logic
+async function nodeMain({ searchDirs, mainSoPath, outFd, inFd, args }) {
if (!process.env.GHCI_BROWSER) {
- const rpc = new DyLDHost();
- await main({
+ const rpc = new DyLDHost({ outFd, inFd });
+ return await main({
rpc,
- libdir,
- ghciSoPath,
+ searchDirs,
+ mainSoPath,
args,
+ isIserv: true,
});
- return;
}
if (!ws) {
@@ -1272,8 +1374,10 @@ export async function main({ rpc, libdir, ghciSoPath, args }) {
host: process.env.GHCI_BROWSER_HOST || "127.0.0.1",
port: process.env.GHCI_BROWSER_PORT || 0,
dyldPath: import.meta.filename,
- libdir,
- ghciSoPath,
+ searchDirs,
+ mainSoPath,
+ outFd,
+ inFd,
args,
redirectWasiConsole:
process.env.GHCI_BROWSER_PUPPETEER_LAUNCH_OPTS ||
@@ -1362,6 +1466,20 @@ export async function main({ rpc, libdir, ghciSoPath, args }) {
}
console.log(
- `Open ${origin}/main.html or import ${origin}/main.js to boot ghci`
+ `Open ${origin}/main.html or import("${origin}/main.js") to boot ghci`
);
-})();
+}
+
+const isNodeMain = isNode && import.meta.filename === process.argv[1];
+
+// node iserv as invoked by
+// GHC.Runtime.Interpreter.Wasm.spawnWasmInterp
+if (isNodeMain) {
+ const clibdir = process.argv[2];
+ const mainSoPath = process.argv[3];
+ const outFd = Number.parseInt(process.argv[4]),
+ inFd = Number.parseInt(process.argv[5]);
+ const args = ["dyld.so", ...process.argv.slice(6)];
+
+ await nodeMain({ searchDirs: [clibdir], mainSoPath, outFd, inFd, args });
+}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/da43e8776c3537fb8f6d45d2d58e61…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/da43e8776c3537fb8f6d45d2d58e61…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/int-index/imp-exp-whole-namespace] 9 commits: rts: remove unneccesary cabal flags
by Vladislav Zavialov (@int-index) 31 Oct '25
by Vladislav Zavialov (@int-index) 31 Oct '25
31 Oct '25
Vladislav Zavialov pushed to branch wip/int-index/imp-exp-whole-namespace at Glasgow Haskell Compiler / GHC
Commits:
643ce801 by Julian Ospald at 2025-10-28T18:18:55-04:00
rts: remove unneccesary cabal flags
We perform those checks via proper autoconf macros
instead that do the right thing and then add those
libs to the rts buildinfo.
- - - - -
d69ea8fe by Vladislav Zavialov at 2025-10-28T18:19:37-04:00
Test case for #17705
Starting with GHC 9.12 (the first release to include 5745dbd3),
all examples in this ticket are handled as expected.
- - - - -
4038a28b by Andreas Klebinger at 2025-10-30T12:38:52-04:00
Add a perf test for #26425
- - - - -
f997618e by Andreas Klebinger at 2025-10-30T12:38:52-04:00
OccAnal: Be stricter for better compiler perf.
In particular we are now stricter:
* When combining usageDetails.
* When computing binder info.
In combineUsageDetails when combining the underlying adds we compute a
new `LocalOcc` for each entry by combining the two existing ones.
Rather than wait for those entries to be forced down the road we now
force them immediately. Speeding up T26425 by about 10% with little
effect on the common case.
We also force binders we put into the Core AST everywhere now.
Failure to do so risks leaking the occ env used to set the binders
OccInfo.
For T26425 compiler residency went down by a factor of ~10x.
Compile time also improved by a factor of ~1.6.
-------------------------
Metric Decrease:
T18698a
T26425
T9233
-------------------------
- - - - -
5618645b by Vladislav Zavialov at 2025-10-30T12:39:33-04:00
Fix namespace specifiers in subordinate exports (#12488)
This patch fixes an oversight in the `lookupChildrenExport` function that
caused explicit namespace specifiers of subordinate export items to be
ignored:
module M (T (type A)) where -- should be rejected
data T = A
Based on the `IEWrappedName` data type, there are 5 cases to consider:
1. Unadorned name: P(X)
2. Named default: P(default X)
3. Pattern synonym: P(pattern X)
4. Type name: P(type X)
5. Data name: P(data X)
Case 1 is already handled correctly; cases 2 and 3 are parse errors; and
it is cases 4 and 5 that we are concerned with in this patch.
Following the precedent established in `LookupExactName`, we introduce
a boolean flag in `LookupChildren` to control whether to look up in all
namespaces or in a specific one. If an export item is accompanied by an
explicit namespace specifier `type` or `data`, we restrict the lookup in
`lookupGRE` to a specific namespace.
The newly introduced diagnostic `TcRnExportedSubordinateNotFound`
provides error messages and suggestions more tailored to this context
than the previously used `reportUnboundName`.
- - - - -
f75ab223 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: detect PowerPC 64 bit ABI
Check preprocessor macro defined for ABI v2 and assume v1 otherwise.
Fixes #26521
- - - - -
d086c474 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: refactor, move lastLine to Utils
- - - - -
995dfe0d by Vladislav Zavialov at 2025-10-31T18:43:54-04:00
Tests for -Wduplicate-exports, -Wdodgy-exports
Add test cases for the previously untested diagnostics:
[GHC-51876] TcRnDupeModuleExport
[GHC-64649] TcRnNullExportedModule
This also revealed a typo (incorrect capitalization of "module") in the
warning text for TcRnDupeModuleExport, which is now fixed.
- - - - -
862e9949 by Vladislav Zavialov at 2025-11-01T02:53:11+03:00
Namespace-specified wildcards in import/export lists
This change adds support for top-level namespace-specified wildcards
`type ..` and `data ..` to import and export lists.
Examples:
import M (type ..) -- imports all type and class constructors from M
import M (data ..) -- imports all data constructors and terms from M
module M (type .., f) where
-- exports all type and class constructors defined in M,
-- plus the function 'f'
The primary intended usage of this feature is in combination with module
aliases, allowing namespace disambiguation:
import Data.Proxy as T (type ..) -- T.Proxy is unambiguously the type constructor
import Data.Proxy as D (data ..) -- D.Proxy is unambiguously the data constructor
The patch accounts for the interactions of wildcards with:
* Imports with `hiding` clauses
* Import warnings -Wunused-imports, -Wdodgy-imports
* Export warnings -Wduplicate-exports, -Wdodgy-exports
Summary of the changes:
1. Move the NamespaceSpecifier type from GHC.Hs.Binds to GHC.Hs.Basic,
making it possible to use it in more places in the AST.
2. Extend the AST (type: IE) with a representation of `..`, `type ..`,
and `data ..` (constructor: IEWholeNamespace). Per the proposal, the
plain `..` is always rejected with a dedicated error message.
3. Extend the grammar in Parser.y with productions for `..`, `type ..`,
and `data ..` in both import and export lists.
4. Implement wildcard imports by updating the `filterImports` function
in GHC.Rename.Names; the logic for IEWholeNamespace is roughly
modeled after the Nothing (no explicit import list) case.
5. Implement wildcard exports by updating the `exports_from_avail`
function in GHC.Tc.Gen.Export; the logic for IEWholeNamespace is
closely modeled after the IEModuleContents case.
6. Refactor and extend diagnostics to report the new warnings and
errors. See PsErrPlainWildcardImport, DodgyImportsWildcard,
PsErrPlainWildcardExport, DodgyExportsWildcard,
TcRnDupeWildcardExport.
Note that this patch is specifically about top-level import/export
items. Subordinate import/export items are left unchanged.
- - - - -
111 changed files:
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Hs/Basic.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Var/Env.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/ImpExp.hs
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/exts/explicit_namespaces.rst
- m4/fp_check_pthreads.m4
- rts/configure.ac
- + rts/rts.buildinfo.in
- rts/rts.cabal
- testsuite/tests/diagnostic-codes/codes.stdout
- + testsuite/tests/module/T25901_exp_plain_wc.hs
- + testsuite/tests/module/T25901_exp_plain_wc.stderr
- + testsuite/tests/module/T25901_imp_plain_wc.hs
- + testsuite/tests/module/T25901_imp_plain_wc.stderr
- testsuite/tests/module/all.T
- testsuite/tests/module/mod4.stderr
- + testsuite/tests/parser/should_fail/T12488c.hs
- + testsuite/tests/parser/should_fail/T12488c.stderr
- + testsuite/tests/parser/should_fail/T12488d.hs
- + testsuite/tests/parser/should_fail/T12488d.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/perf/compiler/T26425.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/rename/should_compile/T12488b.hs
- + testsuite/tests/rename/should_compile/T12488f.hs
- + testsuite/tests/rename/should_compile/T25901_exp_1.hs
- + testsuite/tests/rename/should_compile/T25901_exp_1_helper.hs
- + testsuite/tests/rename/should_compile/T25901_exp_2.hs
- + testsuite/tests/rename/should_compile/T25901_exp_2_helper.hs
- + testsuite/tests/rename/should_compile/T25901_imp_hq.hs
- + testsuite/tests/rename/should_compile/T25901_imp_hu.hs
- + testsuite/tests/rename/should_compile/T25901_imp_sq.hs
- + testsuite/tests/rename/should_compile/T25901_imp_su.hs
- testsuite/tests/rename/should_compile/all.T
- + testsuite/tests/rename/should_fail/T12488a.hs
- + testsuite/tests/rename/should_fail/T12488a.stderr
- + testsuite/tests/rename/should_fail/T12488a_foo.hs
- + testsuite/tests/rename/should_fail/T12488a_foo.stderr
- + testsuite/tests/rename/should_fail/T12488e.hs
- + testsuite/tests/rename/should_fail/T12488e.stderr
- + testsuite/tests/rename/should_fail/T12488g.hs
- + testsuite/tests/rename/should_fail/T12488g.stderr
- testsuite/tests/rename/should_fail/T25899e2.stderr
- + testsuite/tests/rename/should_fail/T25901_exp_fail_1.hs
- + testsuite/tests/rename/should_fail/T25901_exp_fail_1.stderr
- + testsuite/tests/rename/should_fail/T25901_exp_fail_1_helper.hs
- + testsuite/tests/rename/should_fail/T25901_exp_fail_2.hs
- + testsuite/tests/rename/should_fail/T25901_exp_fail_2.stderr
- + testsuite/tests/rename/should_fail/T25901_exp_fail_2_helper.hs
- + testsuite/tests/rename/should_fail/T25901_imp_hq_fail_5.hs
- + testsuite/tests/rename/should_fail/T25901_imp_hq_fail_5.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_hq_fail_6.hs
- + testsuite/tests/rename/should_fail/T25901_imp_hq_fail_6.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_hu_fail_4.hs
- + testsuite/tests/rename/should_fail/T25901_imp_hu_fail_4.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_sq_fail_2.hs
- + testsuite/tests/rename/should_fail/T25901_imp_sq_fail_2.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_sq_fail_3.hs
- + testsuite/tests/rename/should_fail/T25901_imp_sq_fail_3.stderr
- + testsuite/tests/rename/should_fail/T25901_imp_su_fail_1.hs
- + testsuite/tests/rename/should_fail/T25901_imp_su_fail_1.stderr
- testsuite/tests/rename/should_fail/all.T
- + testsuite/tests/typecheck/should_compile/T17705.hs
- testsuite/tests/typecheck/should_compile/all.T
- + testsuite/tests/warnings/should_compile/DuplicateModExport.hs
- + testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
- + testsuite/tests/warnings/should_compile/EmptyModExport.hs
- + testsuite/tests/warnings/should_compile/EmptyModExport.stderr
- + testsuite/tests/warnings/should_compile/T25901_dodgy_helper_1.hs
- + testsuite/tests/warnings/should_compile/T25901_dodgy_helper_2.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dodgy.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dodgy.stderr
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_1.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_1.stderr
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_2.hs
- + testsuite/tests/warnings/should_compile/T25901_exp_dup_wc_2.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_dodgy_1.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_dodgy_1.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_dodgy_2.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_dodgy_2.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_1.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_1.stderr
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_2.hs
- + testsuite/tests/warnings/should_compile/T25901_imp_unused_2.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/ghc-toolchain/ghc-toolchain.cabal
- utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
- + utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
- utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6aabe75818dbcd05758e01e7f80626…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6aabe75818dbcd05758e01e7f80626…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/int-index/remove-outdated-note] Comments only in GHC.Parser.PostProcess.Haddock
by Vladislav Zavialov (@int-index) 31 Oct '25
by Vladislav Zavialov (@int-index) 31 Oct '25
31 Oct '25
Vladislav Zavialov pushed to branch wip/int-index/remove-outdated-note at Glasgow Haskell Compiler / GHC
Commits:
f1def4bd by Vladislav Zavialov at 2025-11-01T02:44:39+03:00
Comments only in GHC.Parser.PostProcess.Haddock
Remove outdated Note [Register keyword location], as the issue it describes
was addressed by commit 05eb50dff2fcc78d025e77b9418ddb369db49b9f.
- - - - -
3 changed files:
- compiler/GHC/Parser/PostProcess/Haddock.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
Changes:
=====================================
compiler/GHC/Parser/PostProcess/Haddock.hs
=====================================
@@ -1115,7 +1115,6 @@ runHdkA (HdkA _ m) = unHdkM m mempty
-- To take it into account, we must register its location using registerLocHdkA
-- or registerHdkA.
--
--- See Note [Register keyword location].
-- See Note [Adding Haddock comments to the syntax tree].
registerLocHdkA :: SrcSpan -> HdkA ()
registerLocHdkA l = HdkA (getBufSpan l) (pure ())
@@ -1544,18 +1543,3 @@ that GHC could parse successfully:
This declaration was accepted by ghc but rejected by ghc -haddock.
-}
-
-{- Note [Register keyword location]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-At the moment, 'addHaddock' erroneously associates some comments with
-constructs that are separated by a keyword. For example:
-
- data Foo -- | Comment for MkFoo
- where MkFoo :: Foo
-
-We could use EPA (exactprint annotations) to fix this, but not without
-modification. For example, EpaLocation contains RealSrcSpan but not BufSpan.
-Also, the fix would be more straightforward after #19623.
-
-For examples, see tests/haddock/should_compile_flag_haddock/T17544_kw.hs
--}
=====================================
testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.hs
=====================================
@@ -2,8 +2,6 @@
{-# OPTIONS -haddock -ddump-parsed-ast #-}
-- Haddock comments in this test case are all rejected.
---
--- See Note [Register keyword location] in GHC.Parser.PostProcess.Haddock
module
-- | Bad comment for the module
=====================================
testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
=====================================
@@ -10,15 +10,15 @@
(AnnsModule
(NoEpTok)
(EpTok
- (EpaSpan { T17544_kw.hs:8:1-6 }))
+ (EpaSpan { T17544_kw.hs:6:1-6 }))
(EpTok
- (EpaSpan { T17544_kw.hs:13:12-16 }))
+ (EpaSpan { T17544_kw.hs:11:12-16 }))
[]
[]
(Just
((,)
- { T17544_kw.hs:25:1 }
- { T17544_kw.hs:24:18 })))
+ { T17544_kw.hs:23:1 }
+ { T17544_kw.hs:22:18 })))
(EpaCommentsBalanced
[]
[]))
@@ -29,7 +29,7 @@
(Just
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:10:3-11 })
+ (EpaSpan { T17544_kw.hs:8:3-11 })
(AnnListItem
[])
(EpaComments
@@ -38,14 +38,14 @@
(Just
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:(10,13)-(13,10) })
+ (EpaSpan { T17544_kw.hs:(8,13)-(11,10) })
(AnnList
(Nothing)
(ListParens
(EpTok
- (EpaSpan { T17544_kw.hs:10:13 }))
+ (EpaSpan { T17544_kw.hs:8:13 }))
(EpTok
- (EpaSpan { T17544_kw.hs:13:10 })))
+ (EpaSpan { T17544_kw.hs:11:10 })))
[]
((,)
(NoEpTok)
@@ -55,26 +55,24 @@
[]))
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:11:3-9 })
+ (EpaSpan { T17544_kw.hs:9:3-9 })
(AnnListItem
[(AddCommaAnn
(EpTok
- (EpaSpan { T17544_kw.hs:11:10 })))])
+ (EpaSpan { T17544_kw.hs:9:10 })))])
(EpaComments
[]))
- (IEThingAll
+ (IEThingWith
((,)
(Nothing)
- ((,,)
- (EpTok
- (EpaSpan { T17544_kw.hs:11:6 }))
+ ((,)
(EpTok
- (EpaSpan { T17544_kw.hs:11:7-8 }))
+ (EpaSpan { T17544_kw.hs:9:6 }))
(EpTok
- (EpaSpan { T17544_kw.hs:11:9 }))))
+ (EpaSpan { T17544_kw.hs:9:9 }))))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:11:3-5 })
+ (EpaSpan { T17544_kw.hs:9:3-5 })
(AnnListItem
[])
(EpaComments
@@ -83,36 +81,45 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:11:3-5 })
+ (EpaSpan { T17544_kw.hs:9:3-5 })
(NameAnnTrailing
[])
(EpaComments
[]))
(Unqual
{OccName: Foo}))))
+ [(L
+ (EpAnn
+ (EpaSpan { T17544_kw.hs:9:7-8 })
+ (AnnListItem
+ [])
+ (EpaComments
+ []))
+ (IEWildcard
+ (EpTok
+ (EpaSpan { T17544_kw.hs:9:7-8 }))))]
+ []
(Nothing)))
,(L
(EpAnn
- (EpaSpan { T17544_kw.hs:12:3-9 })
+ (EpaSpan { T17544_kw.hs:10:3-9 })
(AnnListItem
[(AddCommaAnn
(EpTok
- (EpaSpan { T17544_kw.hs:12:10 })))])
+ (EpaSpan { T17544_kw.hs:10:10 })))])
(EpaComments
[]))
- (IEThingAll
+ (IEThingWith
((,)
(Nothing)
- ((,,)
+ ((,)
(EpTok
- (EpaSpan { T17544_kw.hs:12:6 }))
+ (EpaSpan { T17544_kw.hs:10:6 }))
(EpTok
- (EpaSpan { T17544_kw.hs:12:7-8 }))
- (EpTok
- (EpaSpan { T17544_kw.hs:12:9 }))))
+ (EpaSpan { T17544_kw.hs:10:9 }))))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:12:3-5 })
+ (EpaSpan { T17544_kw.hs:10:3-5 })
(AnnListItem
[])
(EpaComments
@@ -121,34 +128,43 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:12:3-5 })
+ (EpaSpan { T17544_kw.hs:10:3-5 })
(NameAnnTrailing
[])
(EpaComments
[]))
(Unqual
{OccName: Bar}))))
+ [(L
+ (EpAnn
+ (EpaSpan { T17544_kw.hs:10:7-8 })
+ (AnnListItem
+ [])
+ (EpaComments
+ []))
+ (IEWildcard
+ (EpTok
+ (EpaSpan { T17544_kw.hs:10:7-8 }))))]
+ []
(Nothing)))
,(L
(EpAnn
- (EpaSpan { T17544_kw.hs:13:3-9 })
+ (EpaSpan { T17544_kw.hs:11:3-9 })
(AnnListItem
[])
(EpaComments
[]))
- (IEThingAll
+ (IEThingWith
((,)
(Nothing)
- ((,,)
+ ((,)
(EpTok
- (EpaSpan { T17544_kw.hs:13:6 }))
- (EpTok
- (EpaSpan { T17544_kw.hs:13:7-8 }))
+ (EpaSpan { T17544_kw.hs:11:6 }))
(EpTok
- (EpaSpan { T17544_kw.hs:13:9 }))))
+ (EpaSpan { T17544_kw.hs:11:9 }))))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:13:3-5 })
+ (EpaSpan { T17544_kw.hs:11:3-5 })
(AnnListItem
[])
(EpaComments
@@ -157,18 +173,29 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:13:3-5 })
+ (EpaSpan { T17544_kw.hs:11:3-5 })
(NameAnnTrailing
[])
(EpaComments
[]))
(Unqual
{OccName: Cls}))))
+ [(L
+ (EpAnn
+ (EpaSpan { T17544_kw.hs:11:7-8 })
+ (AnnListItem
+ [])
+ (EpaComments
+ []))
+ (IEWildcard
+ (EpTok
+ (EpaSpan { T17544_kw.hs:11:7-8 }))))]
+ []
(Nothing)))]))
[]
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:(15,1)-(16,20) })
+ (EpaSpan { T17544_kw.hs:(13,1)-(14,20) })
(AnnListItem
[])
(EpaComments
@@ -179,7 +206,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:15:6-8 })
+ (EpaSpan { T17544_kw.hs:13:6-8 })
(NameAnnTrailing
[])
(EpaComments
@@ -197,11 +224,11 @@
(NoEpTok)
(NoEpTok)
(EpTok
- (EpaSpan { T17544_kw.hs:15:1-4 }))
+ (EpaSpan { T17544_kw.hs:13:1-4 }))
(NoEpTok)
(NoEpUniTok)
(EpTok
- (EpaSpan { T17544_kw.hs:16:3-7 }))
+ (EpaSpan { T17544_kw.hs:14:3-7 }))
(NoEpTok)
(NoEpTok)
(NoEpTok))
@@ -212,7 +239,7 @@
(False)
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:9-20 })
+ (EpaSpan { T17544_kw.hs:14:9-20 })
(AnnListItem
[])
(EpaComments
@@ -222,12 +249,12 @@
[]
[]
(EpUniTok
- (EpaSpan { T17544_kw.hs:16:15-16 })
+ (EpaSpan { T17544_kw.hs:14:15-16 })
(NormalSyntax)))
(:|
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:9-13 })
+ (EpaSpan { T17544_kw.hs:14:9-13 })
(NameAnnTrailing
[])
(EpaComments
@@ -237,7 +264,7 @@
[])
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:18-20 })
+ (EpaSpan { T17544_kw.hs:14:18-20 })
(AnnListItem
[])
(EpaComments
@@ -251,7 +278,7 @@
[])
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:18-20 })
+ (EpaSpan { T17544_kw.hs:14:18-20 })
(AnnListItem
[])
(EpaComments
@@ -261,7 +288,7 @@
(NotPromoted)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:16:18-20 })
+ (EpaSpan { T17544_kw.hs:14:18-20 })
(NameAnnTrailing
[])
(EpaComments
@@ -272,7 +299,7 @@
[]))))
,(L
(EpAnn
- (EpaSpan { T17544_kw.hs:(18,1)-(19,26) })
+ (EpaSpan { T17544_kw.hs:(16,1)-(17,26) })
(AnnListItem
[])
(EpaComments
@@ -283,7 +310,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:18:9-11 })
+ (EpaSpan { T17544_kw.hs:16:9-11 })
(NameAnnTrailing
[])
(EpaComments
@@ -300,12 +327,12 @@
[]
(NoEpTok)
(EpTok
- (EpaSpan { T17544_kw.hs:18:1-7 }))
+ (EpaSpan { T17544_kw.hs:16:1-7 }))
(NoEpTok)
(NoEpTok)
(NoEpUniTok)
(EpTok
- (EpaSpan { T17544_kw.hs:19:3-7 }))
+ (EpaSpan { T17544_kw.hs:17:3-7 }))
(NoEpTok)
(NoEpTok)
(NoEpTok))
@@ -315,7 +342,7 @@
(NewTypeCon
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:9-26 })
+ (EpaSpan { T17544_kw.hs:17:9-26 })
(AnnListItem
[])
(EpaComments
@@ -325,12 +352,12 @@
[]
[]
(EpUniTok
- (EpaSpan { T17544_kw.hs:19:15-16 })
+ (EpaSpan { T17544_kw.hs:17:15-16 })
(NormalSyntax)))
(:|
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:9-13 })
+ (EpaSpan { T17544_kw.hs:17:9-13 })
(NameAnnTrailing
[])
(EpaComments
@@ -340,7 +367,7 @@
[])
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:18-26 })
+ (EpaSpan { T17544_kw.hs:17:18-26 })
(AnnListItem
[])
(EpaComments
@@ -363,11 +390,11 @@
(HsUnannotated
(EpArrow
(EpUniTok
- (EpaSpan { T17544_kw.hs:19:21-22 })
+ (EpaSpan { T17544_kw.hs:17:21-22 })
(NormalSyntax))))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:18-19 })
+ (EpaSpan { T17544_kw.hs:17:18-19 })
(AnnListItem
[])
(EpaComments
@@ -375,15 +402,15 @@
(HsTupleTy
(AnnParens
(EpTok
- (EpaSpan { T17544_kw.hs:19:18 }))
+ (EpaSpan { T17544_kw.hs:17:18 }))
(EpTok
- (EpaSpan { T17544_kw.hs:19:19 })))
+ (EpaSpan { T17544_kw.hs:17:19 })))
(HsBoxedOrConstraintTuple)
[]))
(Nothing))])
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:24-26 })
+ (EpaSpan { T17544_kw.hs:17:24-26 })
(AnnListItem
[])
(EpaComments
@@ -393,7 +420,7 @@
(NotPromoted)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:19:24-26 })
+ (EpaSpan { T17544_kw.hs:17:24-26 })
(NameAnnTrailing
[])
(EpaComments
@@ -404,7 +431,7 @@
[]))))
,(L
(EpAnn
- (EpaSpan { T17544_kw.hs:(21,1)-(24,18) })
+ (EpaSpan { T17544_kw.hs:(19,1)-(22,18) })
(AnnListItem
[])
(EpaComments
@@ -415,12 +442,12 @@
((,,)
(AnnClassDecl
(EpTok
- (EpaSpan { T17544_kw.hs:21:1-5 }))
+ (EpaSpan { T17544_kw.hs:19:1-5 }))
[]
[]
(NoEpTok)
(EpTok
- (EpaSpan { T17544_kw.hs:23:3-7 }))
+ (EpaSpan { T17544_kw.hs:21:3-7 }))
(NoEpTok)
(NoEpTok)
[])
@@ -430,7 +457,7 @@
(Nothing)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:21:7-9 })
+ (EpaSpan { T17544_kw.hs:19:7-9 })
(NameAnnTrailing
[])
(EpaComments
@@ -441,7 +468,7 @@
(NoExtField)
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:21:11 })
+ (EpaSpan { T17544_kw.hs:19:11 })
(AnnListItem
[])
(EpaComments
@@ -458,7 +485,7 @@
(NoExtField)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:21:11 })
+ (EpaSpan { T17544_kw.hs:19:11 })
(NameAnnTrailing
[])
(EpaComments
@@ -471,7 +498,7 @@
[]
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:5-18 })
+ (EpaSpan { T17544_kw.hs:22:5-18 })
(AnnListItem
[])
(EpaComments
@@ -479,14 +506,14 @@
(ClassOpSig
(AnnSig
(EpUniTok
- (EpaSpan { T17544_kw.hs:24:15-16 })
+ (EpaSpan { T17544_kw.hs:22:15-16 })
(NormalSyntax))
(Nothing)
(Nothing))
(False)
[(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:5-13 })
+ (EpaSpan { T17544_kw.hs:22:5-13 })
(NameAnnTrailing
[])
(EpaComments
@@ -495,7 +522,7 @@
{OccName: clsmethod}))]
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:18 })
+ (EpaSpan { T17544_kw.hs:22:18 })
(AnnListItem
[])
(EpaComments
@@ -506,7 +533,7 @@
(NoExtField))
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:18 })
+ (EpaSpan { T17544_kw.hs:22:18 })
(AnnListItem
[])
(EpaComments
@@ -516,7 +543,7 @@
(NotPromoted)
(L
(EpAnn
- (EpaSpan { T17544_kw.hs:24:18 })
+ (EpaSpan { T17544_kw.hs:22:18 })
(NameAnnTrailing
[])
(EpaComments
@@ -529,15 +556,15 @@
[])))]))
-T17544_kw.hs:9:3: warning: [GHC-94458] [-Winvalid-haddock]
+T17544_kw.hs:7:3: warning: [GHC-94458] [-Winvalid-haddock]
A Haddock comment cannot appear in this position and will be ignored.
-T17544_kw.hs:15:10: warning: [GHC-94458] [-Winvalid-haddock]
+T17544_kw.hs:13:10: warning: [GHC-94458] [-Winvalid-haddock]
A Haddock comment cannot appear in this position and will be ignored.
-T17544_kw.hs:18:13: warning: [GHC-94458] [-Winvalid-haddock]
+T17544_kw.hs:16:13: warning: [GHC-94458] [-Winvalid-haddock]
A Haddock comment cannot appear in this position and will be ignored.
-T17544_kw.hs:22:5: warning: [GHC-94458] [-Winvalid-haddock]
+T17544_kw.hs:20:5: warning: [GHC-94458] [-Winvalid-haddock]
A Haddock comment cannot appear in this position and will be ignored.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f1def4bd9105333aa64d73f2afd9239…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f1def4bd9105333aa64d73f2afd9239…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/int-index/dodgy-hidden-components] 9 commits: rts: remove unneccesary cabal flags
by Vladislav Zavialov (@int-index) 31 Oct '25
by Vladislav Zavialov (@int-index) 31 Oct '25
31 Oct '25
Vladislav Zavialov pushed to branch wip/int-index/dodgy-hidden-components at Glasgow Haskell Compiler / GHC
Commits:
643ce801 by Julian Ospald at 2025-10-28T18:18:55-04:00
rts: remove unneccesary cabal flags
We perform those checks via proper autoconf macros
instead that do the right thing and then add those
libs to the rts buildinfo.
- - - - -
d69ea8fe by Vladislav Zavialov at 2025-10-28T18:19:37-04:00
Test case for #17705
Starting with GHC 9.12 (the first release to include 5745dbd3),
all examples in this ticket are handled as expected.
- - - - -
4038a28b by Andreas Klebinger at 2025-10-30T12:38:52-04:00
Add a perf test for #26425
- - - - -
f997618e by Andreas Klebinger at 2025-10-30T12:38:52-04:00
OccAnal: Be stricter for better compiler perf.
In particular we are now stricter:
* When combining usageDetails.
* When computing binder info.
In combineUsageDetails when combining the underlying adds we compute a
new `LocalOcc` for each entry by combining the two existing ones.
Rather than wait for those entries to be forced down the road we now
force them immediately. Speeding up T26425 by about 10% with little
effect on the common case.
We also force binders we put into the Core AST everywhere now.
Failure to do so risks leaking the occ env used to set the binders
OccInfo.
For T26425 compiler residency went down by a factor of ~10x.
Compile time also improved by a factor of ~1.6.
-------------------------
Metric Decrease:
T18698a
T26425
T9233
-------------------------
- - - - -
5618645b by Vladislav Zavialov at 2025-10-30T12:39:33-04:00
Fix namespace specifiers in subordinate exports (#12488)
This patch fixes an oversight in the `lookupChildrenExport` function that
caused explicit namespace specifiers of subordinate export items to be
ignored:
module M (T (type A)) where -- should be rejected
data T = A
Based on the `IEWrappedName` data type, there are 5 cases to consider:
1. Unadorned name: P(X)
2. Named default: P(default X)
3. Pattern synonym: P(pattern X)
4. Type name: P(type X)
5. Data name: P(data X)
Case 1 is already handled correctly; cases 2 and 3 are parse errors; and
it is cases 4 and 5 that we are concerned with in this patch.
Following the precedent established in `LookupExactName`, we introduce
a boolean flag in `LookupChildren` to control whether to look up in all
namespaces or in a specific one. If an export item is accompanied by an
explicit namespace specifier `type` or `data`, we restrict the lookup in
`lookupGRE` to a specific namespace.
The newly introduced diagnostic `TcRnExportedSubordinateNotFound`
provides error messages and suggestions more tailored to this context
than the previously used `reportUnboundName`.
- - - - -
f75ab223 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: detect PowerPC 64 bit ABI
Check preprocessor macro defined for ABI v2 and assume v1 otherwise.
Fixes #26521
- - - - -
d086c474 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: refactor, move lastLine to Utils
- - - - -
995dfe0d by Vladislav Zavialov at 2025-10-31T18:43:54-04:00
Tests for -Wduplicate-exports, -Wdodgy-exports
Add test cases for the previously untested diagnostics:
[GHC-51876] TcRnDupeModuleExport
[GHC-64649] TcRnNullExportedModule
This also revealed a typo (incorrect capitalization of "module") in the
warning text for TcRnDupeModuleExport, which is now fixed.
- - - - -
36828821 by Vladislav Zavialov at 2025-11-01T02:26:19+03:00
Supplant TcRnExportHiddenComponents with TcRnDodgyExports (#26534)
Remove a bogus special case in lookup_ie_kids_all,
making TcRnExportHiddenComponents obsolete.
- - - - -
54 changed files:
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Var/Env.hs
- m4/fp_check_pthreads.m4
- rts/configure.ac
- + rts/rts.buildinfo.in
- rts/rts.cabal
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/module/mod4.stderr
- + testsuite/tests/parser/should_fail/T12488c.hs
- + testsuite/tests/parser/should_fail/T12488c.stderr
- + testsuite/tests/parser/should_fail/T12488d.hs
- + testsuite/tests/parser/should_fail/T12488d.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/perf/compiler/T26425.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/rename/should_compile/T12488b.hs
- + testsuite/tests/rename/should_compile/T12488f.hs
- testsuite/tests/rename/should_compile/all.T
- + testsuite/tests/rename/should_fail/T12488a.hs
- + testsuite/tests/rename/should_fail/T12488a.stderr
- + testsuite/tests/rename/should_fail/T12488a_foo.hs
- + testsuite/tests/rename/should_fail/T12488a_foo.stderr
- + testsuite/tests/rename/should_fail/T12488e.hs
- + testsuite/tests/rename/should_fail/T12488e.stderr
- + testsuite/tests/rename/should_fail/T12488g.hs
- + testsuite/tests/rename/should_fail/T12488g.stderr
- testsuite/tests/rename/should_fail/T25899e2.stderr
- testsuite/tests/rename/should_fail/all.T
- + testsuite/tests/typecheck/should_compile/T17705.hs
- testsuite/tests/typecheck/should_compile/all.T
- + testsuite/tests/warnings/should_compile/DodgyExports02.hs
- + testsuite/tests/warnings/should_compile/DodgyExports02.stderr
- + testsuite/tests/warnings/should_compile/DodgyExports03.hs
- + testsuite/tests/warnings/should_compile/DodgyExports03.stderr
- + testsuite/tests/warnings/should_compile/DuplicateModExport.hs
- + testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
- + testsuite/tests/warnings/should_compile/EmptyModExport.hs
- + testsuite/tests/warnings/should_compile/EmptyModExport.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/ghc-toolchain/ghc-toolchain.cabal
- utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
- + utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
- utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a425efaf3d622a8c776cac7813cb5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a425efaf3d622a8c776cac7813cb5…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/wasm-dyld-pie] 21 commits: Fix stack decoding when using profiled runtime
by Cheng Shao (@TerrorJack) 31 Oct '25
by Cheng Shao (@TerrorJack) 31 Oct '25
31 Oct '25
Cheng Shao pushed to branch wip/wasm-dyld-pie at Glasgow Haskell Compiler / GHC
Commits:
38d65187 by Matthew Pickering at 2025-10-21T13:12:20+01:00
Fix stack decoding when using profiled runtime
There are three fixes in this commit.
* We need to replicate the `InfoTable` and `InfoTableProf`
approach for the other stack constants (see the new Stack.ConstantsProf
file).
* Then we need to appropiately import the profiled or non-profiled
versions.
* Finally, there was an incorrect addition in `stackFrameSize`. We need
to cast after performing addition on words.
Fixes #26507
- - - - -
17231bfb by fendor at 2025-10-21T13:12:20+01:00
Add regression test for #26507
- - - - -
4f5bf93b by Simon Peyton Jones at 2025-10-25T04:05:34-04:00
Postscript to fix for #26255
This MR has comments only
- - - - -
6ef22fa0 by IC Rainbow at 2025-10-26T18:23:01-04:00
Add SIMD primops for bitwise logical operations
This adds 128-bit wide and/or/xor instructions for X86 NCG,
with both SSE and AVX encodings.
```
andFloatX4# :: FloatX4# -> FloatX4# -> FloatX4# -- andps / vandps
andDoubleX2# :: DoubleX2# -> DoubleX2# -> DoubleX2# -- andpd / vandpd
andInt8X16# :: Int8X16# -> Int8X16# -> Int8X16# -- pand / vpand
```
The new primops are available on ARM when using LLVM backend.
Tests added:
- simd015 (floats and doubles)
- simd016 (integers)
- simd017 (words)
Fixes #26417
- - - - -
fbdc623a by sheaf at 2025-10-26T18:23:52-04:00
Add hints for unsolved HasField constraints
This commit adds hints and explanations for unsolved 'HasField'
constraints.
GHC will now provide additional explanations for an unsolved constraint
of the form 'HasField fld_name rec_ty fld_ty'; the details are laid out in
Note [Error messages for unsolved HasField constraints], but briefly:
1. Provide similar name suggestions (e.g. mis-spelled field name)
and import suggestions (record field not in scope).
These result in actionable 'GhcHints', which is helpful to provide
code actions in HLS.
2. Explain why GHC did not solve the constraint, e.g.:
- 'fld_name' is not a string literal (e.g. a type variable)
- 'rec_ty' is a TyCon without any fields, e.g. 'Int' or 'Bool'.
- 'fld_ty' contains existentials variables or foralls.
- The record field is a pattern synonym field (GHC does not generate
HasField instances for those).
- 'HasField' is a custom 'TyCon', not actually the built-in
'HasField' typeclass from 'GHC.Records'.
On the way, we slightly refactor the mechanisms for import suggestions
in GHC.Rename.Unbound. This is to account for the fact that, for
'HasField', we don't care whether the field is imported qualified or
unqualified. 'importSuggestions' was refactored, we now have
'sameQualImportSuggestions' and 'anyQualImportSuggestions'.
Fixes #18776 #22382 #26480
- - - - -
99d5707f by sheaf at 2025-10-26T18:23:52-04:00
Rename PatSyn MatchContext to PatSynCtx to avoid punning
- - - - -
5dc2e9ea by Julian Ospald at 2025-10-27T18:17:23-04:00
Skip uniques test if sources are not available
- - - - -
544b9ec9 by Vladislav Zavialov at 2025-10-27T18:18:06-04:00
Re-export GHC.Hs.Basic from GHC.Hs
Clean up some import sections in GHC by re-exporting GHC.Hs.Basic
from GHC.Hs.
- - - - -
643ce801 by Julian Ospald at 2025-10-28T18:18:55-04:00
rts: remove unneccesary cabal flags
We perform those checks via proper autoconf macros
instead that do the right thing and then add those
libs to the rts buildinfo.
- - - - -
d69ea8fe by Vladislav Zavialov at 2025-10-28T18:19:37-04:00
Test case for #17705
Starting with GHC 9.12 (the first release to include 5745dbd3),
all examples in this ticket are handled as expected.
- - - - -
4038a28b by Andreas Klebinger at 2025-10-30T12:38:52-04:00
Add a perf test for #26425
- - - - -
f997618e by Andreas Klebinger at 2025-10-30T12:38:52-04:00
OccAnal: Be stricter for better compiler perf.
In particular we are now stricter:
* When combining usageDetails.
* When computing binder info.
In combineUsageDetails when combining the underlying adds we compute a
new `LocalOcc` for each entry by combining the two existing ones.
Rather than wait for those entries to be forced down the road we now
force them immediately. Speeding up T26425 by about 10% with little
effect on the common case.
We also force binders we put into the Core AST everywhere now.
Failure to do so risks leaking the occ env used to set the binders
OccInfo.
For T26425 compiler residency went down by a factor of ~10x.
Compile time also improved by a factor of ~1.6.
-------------------------
Metric Decrease:
T18698a
T26425
T9233
-------------------------
- - - - -
5618645b by Vladislav Zavialov at 2025-10-30T12:39:33-04:00
Fix namespace specifiers in subordinate exports (#12488)
This patch fixes an oversight in the `lookupChildrenExport` function that
caused explicit namespace specifiers of subordinate export items to be
ignored:
module M (T (type A)) where -- should be rejected
data T = A
Based on the `IEWrappedName` data type, there are 5 cases to consider:
1. Unadorned name: P(X)
2. Named default: P(default X)
3. Pattern synonym: P(pattern X)
4. Type name: P(type X)
5. Data name: P(data X)
Case 1 is already handled correctly; cases 2 and 3 are parse errors; and
it is cases 4 and 5 that we are concerned with in this patch.
Following the precedent established in `LookupExactName`, we introduce
a boolean flag in `LookupChildren` to control whether to look up in all
namespaces or in a specific one. If an export item is accompanied by an
explicit namespace specifier `type` or `data`, we restrict the lookup in
`lookupGRE` to a specific namespace.
The newly introduced diagnostic `TcRnExportedSubordinateNotFound`
provides error messages and suggestions more tailored to this context
than the previously used `reportUnboundName`.
- - - - -
f75ab223 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: detect PowerPC 64 bit ABI
Check preprocessor macro defined for ABI v2 and assume v1 otherwise.
Fixes #26521
- - - - -
d086c474 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: refactor, move lastLine to Utils
- - - - -
995dfe0d by Vladislav Zavialov at 2025-10-31T18:43:54-04:00
Tests for -Wduplicate-exports, -Wdodgy-exports
Add test cases for the previously untested diagnostics:
[GHC-51876] TcRnDupeModuleExport
[GHC-64649] TcRnNullExportedModule
This also revealed a typo (incorrect capitalization of "module") in the
warning text for TcRnDupeModuleExport, which is now fixed.
- - - - -
f6961b02 by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: reformat dyld source code
This commit reformats dyld source code with prettier, to avoid
introducing unnecessary diffs in subsequent patches when they're
formatted before committing.
- - - - -
0c9032a0 by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: simplify _initialize logic in dyld
This commit simplifies how we _initialize a wasm shared library in
dyld and removes special treatment for libc.so, see added comment for
detailed explanation.
- - - - -
ec1b40bd by Cheng Shao at 2025-11-01T00:08:01+01:00
wasm: support running dyld fully client side in the browser
This commit refactors the wasm dyld script so that it can be used to
load and run wasm shared libraries fully client-side in the browser
without needing a wasm32-wasi-ghci backend:
- A new `DyLDBrowserHost` class is exported, which runs in the browser
and uses the in-memory vfs without any RPC calls. This meant to be
used to create a `rpc` object for the fully client side use cases.
- The exported `main` function now can be used to load user-specified
shared libraries, and the user can use the returned `DyLD` instance
to run their own exported Haskell functions.
- The in-browser wasi implementation is switched to
https://github.com/haskell-wasm/browser_wasi_shim for bugfixes and
major performance improvements not landed upstream yet.
- When being run by deno, it now correctly switches to non-nodejs code
paths, so it's more convenient to test dyld logic with deno.
See added comments for details, as well as the added `playground001`
test case for an example of using it to build an in-browser Haskell
playground.
- - - - -
8f3e481f by Cheng Shao at 2025-11-01T00:08:01+01:00
testsuite: add playground001 to test haskell playground
This commit adds the playground001 test case to test the haskell
playground in browser, see comments for details.
- - - - -
af40606a by Cheng Shao at 2025-11-01T00:08:04+01:00
Revert "testsuite: add T26431 test case"
This reverts commit 695036686f8c6d78611edf3ed627608d94def6b7. T26431
is now retired, wasm ghc internal-interpreter logic is tested by
playground001.
- - - - -
143 changed files:
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToAsm/X86/Ppr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/Core/ConLike.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/HsToCore/Foreign/Wasm.hs
- compiler/GHC/HsToCore/Pmc/Utils.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Utils.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Unbound.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/Prim.hs
- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Var/Env.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- docs/users_guide/9.16.1-notes.rst
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Exts.hs
- libraries/ghc-experimental/CHANGELOG.md
- libraries/ghc-internal/cbits/Stack_c.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/src/GHC/Internal/Stack/ConstantsProf.hsc
- libraries/ghc-internal/src/GHC/Internal/Stack/Decode.hs
- + libraries/ghc-internal/tests/backtraces/T26507.hs
- + libraries/ghc-internal/tests/backtraces/T26507.stderr
- libraries/ghc-internal/tests/backtraces/all.T
- libraries/ghc-internal/tests/stack-annotation/all.T
- libraries/ghc-prim/changelog.md
- m4/fp_check_pthreads.m4
- rts/configure.ac
- + rts/rts.buildinfo.in
- rts/rts.cabal
- testsuite/tests/diagnostic-codes/codes.stdout
- + testsuite/tests/ghc-api-browser/README.md
- + testsuite/tests/ghc-api-browser/all.T
- + testsuite/tests/ghc-api-browser/index.html
- + testsuite/tests/ghc-api-browser/playground001.hs
- + testsuite/tests/ghc-api-browser/playground001.js
- + testsuite/tests/ghc-api-browser/playground001.sh
- testsuite/tests/ghci-wasm/T26431.stdout → testsuite/tests/ghc-api-browser/playground001.stdout
- − testsuite/tests/ghci-wasm/T26431.hs
- testsuite/tests/ghci-wasm/all.T
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/linters/all.T
- testsuite/tests/module/mod4.stderr
- + testsuite/tests/overloadedrecflds/should_fail/T26480.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26480.stderr
- + testsuite/tests/overloadedrecflds/should_fail/T26480_aux1.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26480_aux2.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26480b.hs
- + testsuite/tests/overloadedrecflds/should_fail/T26480b.stderr
- testsuite/tests/overloadedrecflds/should_fail/all.T
- testsuite/tests/overloadedrecflds/should_fail/hasfieldfail01.stderr
- testsuite/tests/overloadedrecflds/should_fail/hasfieldfail02.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail11.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.hs
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail8.stderr
- + testsuite/tests/parser/should_fail/T12488c.hs
- + testsuite/tests/parser/should_fail/T12488c.stderr
- + testsuite/tests/parser/should_fail/T12488d.hs
- + testsuite/tests/parser/should_fail/T12488d.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/perf/compiler/T26425.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/rename/should_compile/T12488b.hs
- + testsuite/tests/rename/should_compile/T12488f.hs
- testsuite/tests/rename/should_compile/all.T
- + testsuite/tests/rename/should_fail/T12488a.hs
- + testsuite/tests/rename/should_fail/T12488a.stderr
- + testsuite/tests/rename/should_fail/T12488a_foo.hs
- + testsuite/tests/rename/should_fail/T12488a_foo.stderr
- + testsuite/tests/rename/should_fail/T12488e.hs
- + testsuite/tests/rename/should_fail/T12488e.stderr
- + testsuite/tests/rename/should_fail/T12488g.hs
- + testsuite/tests/rename/should_fail/T12488g.stderr
- testsuite/tests/rename/should_fail/T19843h.stderr
- testsuite/tests/rename/should_fail/T25899e2.stderr
- testsuite/tests/rename/should_fail/all.T
- testsuite/tests/simd/should_run/all.T
- + testsuite/tests/simd/should_run/simd015.hs
- + testsuite/tests/simd/should_run/simd015.stdout
- + testsuite/tests/simd/should_run/simd016.hs
- + testsuite/tests/simd/should_run/simd016.stdout
- + testsuite/tests/simd/should_run/simd017.hs
- + testsuite/tests/simd/should_run/simd017.stdout
- + testsuite/tests/typecheck/should_compile/T17705.hs
- testsuite/tests/typecheck/should_compile/all.T
- + testsuite/tests/warnings/should_compile/DuplicateModExport.hs
- + testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
- + testsuite/tests/warnings/should_compile/EmptyModExport.hs
- + testsuite/tests/warnings/should_compile/EmptyModExport.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/ghc-toolchain/ghc-toolchain.cabal
- utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
- + utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
- utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3d7985e376935e3583370f85a83bbc…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3d7985e376935e3583370f85a83bbc…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Tests for -Wduplicate-exports, -Wdodgy-exports
by Marge Bot (@marge-bot) 31 Oct '25
by Marge Bot (@marge-bot) 31 Oct '25
31 Oct '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
995dfe0d by Vladislav Zavialov at 2025-10-31T18:43:54-04:00
Tests for -Wduplicate-exports, -Wdodgy-exports
Add test cases for the previously untested diagnostics:
[GHC-51876] TcRnDupeModuleExport
[GHC-64649] TcRnNullExportedModule
This also revealed a typo (incorrect capitalization of "module") in the
warning text for TcRnDupeModuleExport, which is now fixed.
- - - - -
8 changed files:
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- + testsuite/tests/warnings/should_compile/DuplicateModExport.hs
- + testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
- + testsuite/tests/warnings/should_compile/EmptyModExport.hs
- + testsuite/tests/warnings/should_compile/EmptyModExport.stderr
- testsuite/tests/warnings/should_compile/all.T
Changes:
=====================================
compiler/GHC/Tc/Errors/Ppr.hs
=====================================
@@ -619,7 +619,7 @@ instance Diagnostic TcRnMessage where
TcRnDupeModuleExport mod
-> mkSimpleDecorated $
hsep [ text "Duplicate"
- , quotes (text "Module" <+> ppr mod)
+ , quotes (text "module" <+> ppr mod)
, text "in export list" ]
TcRnExportedModNotImported mod
-> mkSimpleDecorated
=====================================
compiler/GHC/Tc/Errors/Types.hs
=====================================
@@ -1567,10 +1567,11 @@ data TcRnMessage where
occurs when a module appears more than once in an export list.
Example(s):
- module Foo (module Bar, module Bar)
- import Bar
+ module Foo (module Bar, module Bar) where
+ import Bar
- Text cases: None
+ Text cases:
+ DuplicateModExport
-}
TcRnDupeModuleExport :: ModuleName -> TcRnMessage
@@ -1590,10 +1591,11 @@ data TcRnMessage where
when an export list contains a module that has no exports.
Example(s):
- module Foo (module Bar) where
- import Bar ()
+ module Foo (module Bar) where
+ import Bar ()
- Test cases: None
+ Test cases:
+ EmptyModExport
-}
TcRnNullExportedModule :: ModuleName -> TcRnMessage
=====================================
testsuite/tests/diagnostic-codes/codes.stdout
=====================================
@@ -50,8 +50,6 @@
[GHC-17268] is untested (constructor = TcRnCharLiteralOutOfRange)
[GHC-36495] is untested (constructor = TcRnTagToEnumMissingValArg)
[GHC-55868] is untested (constructor = TcRnArrowIfThenElsePredDependsOnResultTy)
-[GHC-51876] is untested (constructor = TcRnDupeModuleExport)
-[GHC-64649] is untested (constructor = TcRnNullExportedModule)
[GHC-94558] is untested (constructor = TcRnExportHiddenComponents)
[GHC-63055] is untested (constructor = TcRnFieldUpdateInvalidType)
[GHC-26133] is untested (constructor = TcRnForeignImportPrimSafeAnn)
=====================================
testsuite/tests/warnings/should_compile/DuplicateModExport.hs
=====================================
@@ -0,0 +1,3 @@
+module DuplicateModExport (module L, module L) where
+
+import Data.List as L
=====================================
testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
=====================================
@@ -0,0 +1,3 @@
+DuplicateModExport.hs:1:38: warning: [GHC-51876] [-Wduplicate-exports (in -Wdefault)]
+ Duplicate ‘module L’ in export list
+
=====================================
testsuite/tests/warnings/should_compile/EmptyModExport.hs
=====================================
@@ -0,0 +1,3 @@
+module EmptyModExport (module L) where
+
+import Data.List as L ()
=====================================
testsuite/tests/warnings/should_compile/EmptyModExport.stderr
=====================================
@@ -0,0 +1,3 @@
+EmptyModExport.hs:1:24: warning: [GHC-64649] [-Wdodgy-exports (in -Wextra)]
+ The export item ‘module L’ exports nothing
+
=====================================
testsuite/tests/warnings/should_compile/all.T
=====================================
@@ -72,3 +72,5 @@ test('T23465', normal, compile, ['-ddump-parsed'])
test('WarnNoncanonical', normal, compile, [''])
test('T24396', [extra_files(["T24396a.hs", "T24396b.hs"])], multimod_compile, ['T24396b', ''])
test('SpecMultipleTys', normal, compile, ['']) # compile_fail from GHC 9.18
+test('DuplicateModExport', normal, compile, ['-Wduplicate-exports'])
+test('EmptyModExport', normal, compile, ['-Wdodgy-exports'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/995dfe0d6012c2798bafe42cabbc04b…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/995dfe0d6012c2798bafe42cabbc04b…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: ghc-toolchain: detect PowerPC 64 bit ABI
by Marge Bot (@marge-bot) 31 Oct '25
by Marge Bot (@marge-bot) 31 Oct '25
31 Oct '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
f75ab223 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: detect PowerPC 64 bit ABI
Check preprocessor macro defined for ABI v2 and assume v1 otherwise.
Fixes #26521
- - - - -
d086c474 by Peter Trommler at 2025-10-31T18:43:13-04:00
ghc-toolchain: refactor, move lastLine to Utils
- - - - -
5 changed files:
- utils/ghc-toolchain/ghc-toolchain.cabal
- utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
- + utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
- utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
Changes:
=====================================
utils/ghc-toolchain/ghc-toolchain.cabal
=====================================
@@ -21,6 +21,7 @@ library
GHC.Toolchain.NormaliseTriple,
GHC.Toolchain.CheckArm,
GHC.Toolchain.Target,
+ GHC.Toolchain.CheckPower
GHC.Toolchain.Tools.Ar,
GHC.Toolchain.Tools.Cc,
GHC.Toolchain.Tools.Cxx,
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
=====================================
@@ -8,6 +8,7 @@ import System.Process
import GHC.Platform.ArchOS
import GHC.Toolchain.Prelude
+import GHC.Toolchain.Utils (lastLine)
import GHC.Toolchain.Tools.Cc
-- | Awkwardly, ARM triples sometimes contain insufficient information about
@@ -75,10 +76,6 @@ findArmIsa cc = do
"False" -> return False
_ -> throwE $ "unexpected output from test program: " ++ out
-lastLine :: String -> String
-lastLine "" = ""
-lastLine s = last $ lines s
-
-- | Raspbian unfortunately makes some extremely questionable packaging
-- decisions, configuring gcc to compile for ARMv6 despite the fact that the
-- Raspberry Pi 4 is ARMv8. As ARMv8 doesn't support all instructions supported
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
=====================================
@@ -0,0 +1,29 @@
+module GHC.Toolchain.CheckPower ( checkPowerAbi ) where
+
+import GHC.Platform.ArchOS
+
+import GHC.Toolchain.Prelude
+import GHC.Toolchain.Utils (lastLine)
+import GHC.Toolchain.Tools.Cc
+
+-- 64-Bit ELF V2 ABI Specification, Power Architecture, Revision 1.5 says:
+-- A C preprocessor that conforms to this ABI shall predefine the macro
+-- _CALL_ELF to have a value of 2 (Section 5.1.4 Predifined Macros).
+-- The 64-bit PowerPC ELF Application Binary Interface Supplement 1.9
+-- does not define any macro to identify the ABI.
+-- So we check for ABI version 2 and default to ABI version 1.
+
+checkPowerAbi :: Cc -> M Arch
+checkPowerAbi cc = do
+ checking "POWER ELF ABI" $ do
+ out <- fmap lastLine $ preprocess cc $ unlines
+ [ "#if defined(_CALL_ELF) && _CALL_ELF == 2"
+ , "ELFv2"
+ , "#else"
+ , "ELFv1"
+ , "#endif"
+ ]
+ case out of
+ "ELFv1" -> pure $ ArchPPC_64 ELF_V1
+ "ELFv2" -> pure $ ArchPPC_64 ELF_V2
+ _ -> throwE $ "unexpected output from test program: " ++ out
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
=====================================
@@ -6,6 +6,7 @@ import GHC.Platform.ArchOS
import GHC.Toolchain.Prelude
import GHC.Toolchain.CheckArm
+import GHC.Toolchain.CheckPower
import GHC.Toolchain.Tools.Cc
-- | Parse a triple `arch-vendor-os` into an 'ArchOS' and a vendor name 'String'
@@ -40,7 +41,7 @@ parseArch cc arch =
"x86_64" -> pure ArchX86_64
"amd64" -> pure ArchX86_64
"powerpc" -> pure ArchPPC
- "powerpc64" -> pure (ArchPPC_64 ELF_V1)
+ "powerpc64" -> checkPowerAbi cc
"powerpc64le" -> pure (ArchPPC_64 ELF_V2)
"s390x" -> pure ArchS390X
"arm" -> findArmIsa cc
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
=====================================
@@ -8,6 +8,7 @@ module GHC.Toolchain.Utils
, oneOf
, oneOf'
, isSuccess
+ , lastLine
) where
import Control.Exception
@@ -65,3 +66,6 @@ isSuccess = \case
ExitSuccess -> True
ExitFailure _ -> False
+lastLine :: String -> String
+lastLine "" = ""
+lastLine s = last $ lines s
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5618645b5860bf65546108e578a7eb…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5618645b5860bf65546108e578a7eb…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/int-index/remove-outdated-note
by Vladislav Zavialov (@int-index) 31 Oct '25
by Vladislav Zavialov (@int-index) 31 Oct '25
31 Oct '25
Vladislav Zavialov pushed new branch wip/int-index/remove-outdated-note at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/int-index/remove-outdated-note
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26425] 2 commits: Undo the "suppress unfoldings of big join points"
by Simon Peyton Jones (@simonpj) 31 Oct '25
by Simon Peyton Jones (@simonpj) 31 Oct '25
31 Oct '25
Simon Peyton Jones pushed to branch wip/T26425 at Glasgow Haskell Compiler / GHC
Commits:
4e7dd636 by Simon Peyton Jones at 2025-10-31T17:36:56+00:00
Undo the "suppress unfoldings of big join points"
- - - - -
3916cdd3 by Simon Peyton Jones at 2025-10-31T17:37:28+00:00
Tidying up on the main point of this MR
..needs better docs!
- - - - -
2 changed files:
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
Changes:
=====================================
compiler/GHC/Core/Opt/OccurAnal.hs
=====================================
@@ -759,62 +759,62 @@ rest of 'OccInfo' until it goes on the binder.
Note [Join arity prediction based on joinRhsArity]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-In general, the join arity from tail occurrences of a join point (O) may be
-higher or lower than the manifest join arity of the join body (M). E.g.,
+In general, the join arity from tail occurrences of a join point (OAr) may be
+higher or lower than the manifest join arity of the join body (MAr). E.g.,
- -- M > O:
- let f x y = x + y -- M = 2
- in if b then f 1 else f 2 -- O = 1
+ -- MAr > Oar:
+ let f x y = x + y -- MAr = 2
+ in if b then f 1 else f 2 -- OAr = 1
==> { Contify for join arity 1 }
join f x = \y -> x + y
in if b then jump f 1 else jump f 2
- -- M < O
- let f = id -- M = 0
- in if ... then f 12 else f 13 -- O = 1
+ -- MAr < Oar
+ let f = id -- MAr = 0
+ in if ... then f 12 else f 13 -- OAr = 1
==> { Contify for join arity 1, eta-expand f }
join f x = id x
in if b then jump f 12 else jump f 13
-But for *recursive* let, it is crucial that both arities match up, consider
+But for *recursive* let, it is crucial MAr=OAr. Consider:
letrec f x y = if ... then f x else True
in f 42
-Here, M=2 but O=1. If we settled for a joinrec arity of 1, the recursive jump
+Here, MAr=2 but OAr=1. If we settled for a joinrec arity of 1, the recursive jump
would not happen in a tail context! Contification is invalid here.
-So indeed it is crucial to demand that M=O.
+So indeed it is crucial to demand that MAr=OAr.
-(Side note: Actually, we could be more specific: Let O1 be the join arity of
-occurrences from the letrec RHS and O2 the join arity from the let body. Then
-we need M=O1 and M<=O2 and could simply eta-expand the RHS to match O2 later.
-M=O is the specific case where we don't want to eta-expand. Neither the join
+(Side note: Actually, we could be more specific: Let OAr1 be the join arity of
+occurrences from the letrec RHS and OAr2 the join arity from the let body. Then
+we need MAr=OAr1 and MAr<=OAr2 and could simply eta-expand the RHS to match OAr2 later.
+MAr=OAr is the specific case where we don't want to eta-expand. Neither the join
points paper nor GHC does this at the moment.)
We can capitalise on this observation and conclude that *if* f could become a
-joinrec (without eta-expansion), it will have join arity M.
-Now, M is just the result of 'joinRhsArity', a rather simple, local analysis.
+joinrec (without eta-expansion), it will have join arity MAr.
+Now, MAr is just the result of 'joinRhsArity', a rather simple, local analysis.
It is also the join arity inside the 'TailUsageDetails' returned by
'occAnalLamTail', so we can predict join arity without doing any fixed-point
iteration or really doing any deep traversal of let body or RHS at all.
-We check for M in the 'adjustTailUsage' call inside 'tagRecBinders'.
+We check for MAr in the 'adjustTailUsage' call inside 'tagRecBinders'.
All this is quite apparent if you look at the contification transformation in
Fig. 5 of "Compiling without Continuations" (which does not account for
eta-expansion at all, mind you). The letrec case looks like this
-
+n
letrec f = /\as.\xs. L[us] in L'[es]
... and a bunch of conditions establishing that f only occurs
in app heads of join arity (len as + len xs) inside us and es ...
-The syntactic form `/\as.\xs. L[us]` forces M=O iff `f` occurs in `us`. However,
+The syntactic form `/\as.\xs. L[us]` forces MAr=OAr iff `f` occurs in `us`. However,
for non-recursive functions, this is the definition of contification from the
paper:
let f = /\as.\xs.u in L[es] ... conditions ...
-Note that u could be a lambda itself, as we have seen. No relationship between M
-and O to exploit here.
+Note that u could be a lambda itself, as we have seen. No relationship between MAr
+and OAr to exploit here.
Note [Join points and unfoldings/rules]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -998,7 +998,8 @@ occAnalBind !env lvl ire (NonRec bndr rhs) thing_inside combine
-- Now analyse the body, adding the join point
-- into the environment with addJoinPoint
- !(WUD body_uds (occ, body)) = occAnalNonRecBody env bndr' $ \env ->
+ env_body = addLocalLet env lvl bndr
+ !(WUD body_uds (occ, body)) = occAnalNonRecBody env_body bndr' $ \env ->
thing_inside (addJoinPoint env bndr' rhs_uds)
in
if isDeadOcc occ -- Drop dead code; see Note [Dead code]
@@ -1012,8 +1013,8 @@ occAnalBind !env lvl ire (NonRec bndr rhs) thing_inside combine
-- The normal case, including newly-discovered join points
-- Analyse the body and /then/ the RHS
- | WUD body_uds (occ,body) <- occAnalNonRecBody (addLocalLet env lvl bndr)
- bndr thing_inside
+ | let env_body = addLocalLet env lvl bndr
+ , WUD body_uds (occ,body) <- occAnalNonRecBody env_body bndr thing_inside
= if isDeadOcc occ -- Drop dead code; see Note [Dead code]
then WUD body_uds body
else let
@@ -1059,7 +1060,7 @@ occAnalNonRecRhs !env lvl imp_rule_edges mb_join bndr rhs
rhs_ctxt = mkNonRecRhsCtxt lvl bndr unf
-- See Note [Join arity prediction based on joinRhsArity]
- -- Match join arity O from mb_join_arity with manifest join arity M as
+ -- Match join arity OAr from mb_join_arity with manifest join arity MAr as
-- returned by of occAnalLamTail. It's totally OK for them to mismatch;
-- hence adjust the UDs from the RHS
@@ -1769,7 +1770,7 @@ makeNode !env imp_rule_edges bndr_set (bndr, rhs)
-- here because that is what we are setting!
WTUD unf_tuds unf' = occAnalUnfolding rhs_env unf
adj_unf_uds = adjustTailArity (JoinPoint rhs_ja) unf_tuds
- -- `rhs_ja` is `joinRhsArity rhs` and is the prediction for source M
+ -- `rhs_ja` is `joinRhsArity rhs` and is the prediction for source MAr
-- of Note [Join arity prediction based on joinRhsArity]
--------- IMP-RULES --------
@@ -1780,7 +1781,7 @@ makeNode !env imp_rule_edges bndr_set (bndr, rhs)
--------- All rules --------
-- See Note [Join points and unfoldings/rules]
- -- `rhs_ja` is `joinRhsArity rhs'` and is the prediction for source M
+ -- `rhs_ja` is `joinRhsArity rhs'` and is the prediction for source MAr
-- of Note [Join arity prediction based on joinRhsArity]
rules_w_uds :: [(CoreRule, UsageDetails, UsageDetails)]
rules_w_uds = [ (r,l,adjustTailArity (JoinPoint rhs_ja) rhs_wuds)
@@ -2182,7 +2183,9 @@ occAnalLamTail :: OccEnv -> CoreExpr -> WithTailUsageDetails CoreExpr
-- See Note [Adjusting right-hand sides]
occAnalLamTail env expr
= let !(WUD usage expr') = occ_anal_lam_tail env expr
- in WTUD (TUD (joinRhsArity expr) usage) expr'
+ in WTUD (TUD (joinRhsArity expr') usage) expr'
+ -- If expr looks like (\x. let dead = e in \y. blah), where `dead` is dead
+ -- then joinRhsArity expr' might exceed joinRhsArity expr
occ_anal_lam_tail :: OccEnv -> CoreExpr -> WithUsageDetails CoreExpr
-- Does not markInsideLam etc for the outmost batch of lambdas
@@ -3643,7 +3646,12 @@ data LocalOcc -- See Note [LocalOcc]
-- Combining (AlwaysTailCalled 2) and (AlwaysTailCalled 3)
-- gives NoTailCallInfo
, lo_int_cxt :: !InterestingCxt }
+
| ManyOccL !TailCallInfo
+ -- Why do we need TailCallInfo on ManyOccL?
+ -- Answer: recursive bindings are entered many times:
+ -- rec { j x = ...j x'... } in j y
+ -- See the uses of `andUDs` in `tagRecBinders`
instance Outputable LocalOcc where
ppr (OneOccL { lo_n_br = n, lo_tail = tci })
@@ -3678,7 +3686,7 @@ instance Outputable UsageDetails where
-- | TailUsageDetails captures the result of applying 'occAnalLamTail'
-- to a function `\xyz.body`. The TailUsageDetails pairs together
-- * the number of lambdas (including type lambdas: a JoinArity)
--- * UsageDetails for the `body` of the lambda, unadjusted by `adjustTailUsage`.
+-- * UsageDetails for the `body` of the lambda, /unadjusted/ by `adjustTailUsage`.
-- If the binding turns out to be a join point with the indicated join
-- arity, this unadjusted usage details is just what we need; otherwise we
-- need to discard tail calls. That's what `adjustTailUsage` does.
@@ -3865,8 +3873,6 @@ lookupOccInfoByUnique (UD { ud_env = env
| uniq `elemVarEnvByKey` z_tail = NoTailCallInfo
| otherwise = ti
-
-
-------------------
-- See Note [Adjusting right-hand sides]
@@ -3876,21 +3882,22 @@ adjustNonRecRhs :: JoinPointHood
-- ^ This function concentrates shared logic between occAnalNonRecBind and the
-- AcyclicSCC case of occAnalRec.
-- It returns the adjusted rhs UsageDetails combined with the body usage
-adjustNonRecRhs mb_join_arity rhs_wuds@(WTUD _ rhs)
- = WUD (adjustTailUsage mb_join_arity rhs_wuds) rhs
-
+adjustNonRecRhs mb_join_arity (WTUD (TUD rhs_ja uds) rhs)
+ = WUD (adjustTailUsage exact_join rhs uds) rhs
+ where
+ exact_join = mb_join_arity == JoinPoint rhs_ja
-adjustTailUsage :: JoinPointHood
- -> WithTailUsageDetails CoreExpr -- Rhs usage, AFTER occAnalLamTail
+adjustTailUsage :: Bool -- True <=> Exactly-matching join point; don't do markNonTail
+ -> CoreExpr -- Rhs usage, AFTER occAnalLamTail
+ -> UsageDetails
-> UsageDetails
-adjustTailUsage mb_join_arity (WTUD (TUD rhs_ja uds) rhs)
+adjustTailUsage exact_join rhs uds
= -- c.f. occAnal (Lam {})
markAllInsideLamIf (not one_shot) $
markAllNonTailIf (not exact_join) $
uds
where
one_shot = isOneShotFun rhs
- exact_join = mb_join_arity == JoinPoint rhs_ja
adjustTailArity :: JoinPointHood -> TailUsageDetails -> UsageDetails
adjustTailArity mb_rhs_ja (TUD ja usage)
@@ -3937,8 +3944,9 @@ tagNonRecBinder lvl occ bndr
tagRecBinders :: TopLevelFlag -- At top level?
-> UsageDetails -- Of body of let ONLY
-> [NodeDetails]
- -> WithUsageDetails -- Adjusted details for whole scope,
- -- with binders removed
+ -> WithUsageDetails -- Adjusted details for whole scope
+ -- still including the binders;
+ -- (they are removed by `addInScope`)
[IdWithOccInfo] -- Tagged binders
-- Substantially more complicated than non-recursive case. Need to adjust RHS
-- details *before* tagging binders (because the tags depend on the RHSes).
@@ -3948,32 +3956,21 @@ tagRecBinders lvl body_uds details_s
-- 1. See Note [Join arity prediction based on joinRhsArity]
-- Determine possible join-point-hood of whole group, by testing for
- -- manifest join arity M.
- -- This (re-)asserts that makeNode had made tuds for that same arity M!
+ -- manifest join arity MAr.
+ -- This (re-)asserts that makeNode had made tuds for that same arity MAr!
unadj_uds = foldr (andUDs . test_manifest_arity) body_uds details_s
- test_manifest_arity ND{nd_rhs = WTUD tuds rhs}
- = adjustTailArity (JoinPoint (joinRhsArity rhs)) tuds
+ test_manifest_arity ND{nd_rhs = WTUD (TUD rhs_ja uds) rhs}
+ = assertPpr (rhs_ja == joinRhsArity rhs) (ppr rhs_ja $$ ppr uds $$ ppr rhs) $
+ uds
+ will_be_joins :: Bool
will_be_joins = decideRecJoinPointHood lvl unadj_uds bndrs
- mb_join_arity :: Id -> JoinPointHood
- -- mb_join_arity: See Note [Join arity prediction based on joinRhsArity]
- -- This is the source O
- mb_join_arity bndr
- -- Can't use willBeJoinId_maybe here because we haven't tagged
- -- the binder yet (the tag depends on these adjustments!)
- | will_be_joins
- , AlwaysTailCalled arity <- lookupTailCallInfo unadj_uds bndr
- = JoinPoint arity
- | otherwise
- = assert (not will_be_joins) -- Should be AlwaysTailCalled if
- NotJoinPoint -- we are making join points!
-
-- 2. Adjust usage details of each RHS, taking into account the
-- join-point-hood decision
- rhs_udss' = [ adjustTailUsage (mb_join_arity bndr) rhs_wuds
+ rhs_udss' = [ adjustTailUsage will_be_joins rhs rhs_uds
-- Matching occAnalLamTail in makeNode
- | ND { nd_bndr = bndr, nd_rhs = rhs_wuds } <- details_s ]
+ | ND { nd_rhs = WTUD (TUD _ rhs_uds) rhs } <- details_s ]
-- 3. Compute final usage details from adjusted RHS details
adj_uds = foldr andUDs body_uds rhs_udss'
@@ -3992,9 +3989,9 @@ setBinderOcc occ_info bndr
| otherwise = setIdOccInfo bndr occ_info
-- | Decide whether some bindings should be made into join points or not, based
--- on its occurrences. This is
+-- on its occurrences.
-- Returns `False` if they can't be join points. Note that it's an
--- all-or-nothing decision, as if multiple binders are given, they're
+-- all-or-nothing decision: if multiple binders are given, they are
-- assumed to be mutually recursive.
--
-- It must, however, be a final decision. If we say `True` for 'f',
=====================================
compiler/GHC/Core/Opt/Simplify/Iteration.hs
=====================================
@@ -4598,12 +4598,12 @@ mkLetUnfolding :: SimplEnv -> TopLevelFlag -> UnfoldingSource
-> InId -> Bool -- True <=> this is a join point
-> OutExpr -> SimplM Unfolding
mkLetUnfolding env top_lvl src id is_join new_rhs
- | is_join
- , UnfNever <- guidance
- = -- For large join points, don't keep an unfolding at all if it is large
- -- This is just an attempt to keep residency under control in
- -- deeply-nested join-point such as those arising in #26425
- return NoUnfolding
+-- | is_join
+-- , UnfNever <- guidance
+-- = -- For large join points, don't keep an unfolding at all if it is large
+-- -- This is just an attempt to keep residency under control in
+-- -- deeply-nested join-point such as those arising in #26425
+-- return NoUnfolding
| otherwise
= return (mkCoreUnfolding src is_top_lvl new_rhs Nothing guidance)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/193bf31249a81c6c5bcddb956dbca7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/193bf31249a81c6c5bcddb956dbca7…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Add a perf test for #26425
by Marge Bot (@marge-bot) 31 Oct '25
by Marge Bot (@marge-bot) 31 Oct '25
31 Oct '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
4038a28b by Andreas Klebinger at 2025-10-30T12:38:52-04:00
Add a perf test for #26425
- - - - -
f997618e by Andreas Klebinger at 2025-10-30T12:38:52-04:00
OccAnal: Be stricter for better compiler perf.
In particular we are now stricter:
* When combining usageDetails.
* When computing binder info.
In combineUsageDetails when combining the underlying adds we compute a
new `LocalOcc` for each entry by combining the two existing ones.
Rather than wait for those entries to be forced down the road we now
force them immediately. Speeding up T26425 by about 10% with little
effect on the common case.
We also force binders we put into the Core AST everywhere now.
Failure to do so risks leaking the occ env used to set the binders
OccInfo.
For T26425 compiler residency went down by a factor of ~10x.
Compile time also improved by a factor of ~1.6.
-------------------------
Metric Decrease:
T18698a
T26425
T9233
-------------------------
- - - - -
5618645b by Vladislav Zavialov at 2025-10-30T12:39:33-04:00
Fix namespace specifiers in subordinate exports (#12488)
This patch fixes an oversight in the `lookupChildrenExport` function that
caused explicit namespace specifiers of subordinate export items to be
ignored:
module M (T (type A)) where -- should be rejected
data T = A
Based on the `IEWrappedName` data type, there are 5 cases to consider:
1. Unadorned name: P(X)
2. Named default: P(default X)
3. Pattern synonym: P(pattern X)
4. Type name: P(type X)
5. Data name: P(data X)
Case 1 is already handled correctly; cases 2 and 3 are parse errors; and
it is cases 4 and 5 that we are concerned with in this patch.
Following the precedent established in `LookupExactName`, we introduce
a boolean flag in `LookupChildren` to control whether to look up in all
namespaces or in a specific one. If an export item is accompanied by an
explicit namespace specifier `type` or `data`, we restrict the lookup in
`lookupGRE` to a specific namespace.
The newly introduced diagnostic `TcRnExportedSubordinateNotFound`
provides error messages and suggestions more tailored to this context
than the previously used `reportUnboundName`.
- - - - -
3f30366b by Peter Trommler at 2025-10-31T13:12:51-04:00
ghc-toolchain: detect PowerPC 64 bit ABI
Check preprocessor macro defined for ABI v2 and assume v1 otherwise.
Fixes #26521
- - - - -
aae591ae by Peter Trommler at 2025-10-31T13:12:51-04:00
ghc-toolchain: refactor, move lastLine to Utils
- - - - -
da43e877 by Vladislav Zavialov at 2025-10-31T13:12:52-04:00
Tests for -Wduplicate-exports, -Wdodgy-exports
Add test cases for the previously untested diagnostics:
[GHC-51876] TcRnDupeModuleExport
[GHC-64649] TcRnNullExportedModule
This also revealed a typo (incorrect capitalization of "module") in the
warning text for TcRnDupeModuleExport, which is now fixed.
- - - - -
44 changed files:
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/Hint.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Var/Env.hs
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/module/mod4.stderr
- + testsuite/tests/parser/should_fail/T12488c.hs
- + testsuite/tests/parser/should_fail/T12488c.stderr
- + testsuite/tests/parser/should_fail/T12488d.hs
- + testsuite/tests/parser/should_fail/T12488d.stderr
- testsuite/tests/parser/should_fail/all.T
- + testsuite/tests/perf/compiler/T26425.hs
- testsuite/tests/perf/compiler/all.T
- + testsuite/tests/rename/should_compile/T12488b.hs
- + testsuite/tests/rename/should_compile/T12488f.hs
- testsuite/tests/rename/should_compile/all.T
- + testsuite/tests/rename/should_fail/T12488a.hs
- + testsuite/tests/rename/should_fail/T12488a.stderr
- + testsuite/tests/rename/should_fail/T12488a_foo.hs
- + testsuite/tests/rename/should_fail/T12488a_foo.stderr
- + testsuite/tests/rename/should_fail/T12488e.hs
- + testsuite/tests/rename/should_fail/T12488e.stderr
- + testsuite/tests/rename/should_fail/T12488g.hs
- + testsuite/tests/rename/should_fail/T12488g.stderr
- testsuite/tests/rename/should_fail/T25899e2.stderr
- testsuite/tests/rename/should_fail/all.T
- + testsuite/tests/warnings/should_compile/DuplicateModExport.hs
- + testsuite/tests/warnings/should_compile/DuplicateModExport.stderr
- + testsuite/tests/warnings/should_compile/EmptyModExport.hs
- + testsuite/tests/warnings/should_compile/EmptyModExport.stderr
- testsuite/tests/warnings/should_compile/all.T
- utils/ghc-toolchain/ghc-toolchain.cabal
- utils/ghc-toolchain/src/GHC/Toolchain/CheckArm.hs
- + utils/ghc-toolchain/src/GHC/Toolchain/CheckPower.hs
- utils/ghc-toolchain/src/GHC/Toolchain/ParseTriple.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/46bf1b5806d531b0164ccc0f730100…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/46bf1b5806d531b0164ccc0f730100…
You're receiving this email because of your account on gitlab.haskell.org.
1
0