[Git][ghc/ghc][wip/27162/rts-explicit-dllimport] 3 commits: Use __attribute__((dllimport)) for external RTS symbol declarations
by David Eichmann (@DavidEichmann) 30 Apr '26
by David Eichmann (@DavidEichmann) 30 Apr '26
30 Apr '26
David Eichmann pushed to branch wip/27162/rts-explicit-dllimport at Glasgow Haskell Compiler / GHC
Commits:
5a6ba22b by Duncan Coutts at 2026-04-30T11:40:09+01:00
Use __attribute__((dllimport)) for external RTS symbol declarations
This is needed to be hygenic about DLL symbol imports and exports.
The attribute is ignored on platforms other than Windows.
Use of the attribute however means that external data symbols do not
have a compile-time constant address (they are loaded using an
indirection). This means we have to adjust the rtsSyms initial linker
table so that it is a local constant in a function, rather than a global
constant. We now define it within a function that pre-populates the
symbol table with the RTS symbols.
- - - - -
6833e03c by Duncan Coutts at 2026-04-30T11:40:09+01:00
Fix the rts linker declarations for a few data symbols
and ensure that the (windows only) rts_IOManagerIsWin32Native data
symbol is marked as externally visible.
- - - - -
793008fb by David Eichmann at 2026-04-30T11:40:09+01:00
Hadrian: Disable runtime pseudo relocations for RTS on windows hosts
- - - - -
7 changed files:
- hadrian/src/Settings/Packages.hs
- rts/IOManager.h
- rts/Linker.c
- rts/LinkerInternals.h
- rts/RtsSymbols.c
- rts/RtsSymbols.h
- rts/linker/Elf.c
Changes:
=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -321,6 +321,7 @@ rtsPackageArgs = package rts ? do
, Profiling `wayUnit` way ? arg "-DPROFILING"
, Threaded `wayUnit` way ? arg "-DTHREADED_RTS"
, notM targetSupportsSMP ? arg "-optc-DNOSMP"
+ , isWinHost ? arg "-optl-Wl,--disable-runtime-pseudo-reloc"
-- See Note [AutoApply.cmm for vectors] in genapply/Main.hs
--
=====================================
rts/IOManager.h
=====================================
@@ -21,6 +21,15 @@
#include "sm/GC.h" // for evac_fn
+#if defined(mingw32_HOST_OS)
+/* Global var (only on Windows) that is exported (hence before BeginPrivate.h)
+ * to be shared with the I/O code in the base library to tell us which style
+ * of I/O manager we are using: one that uses the Windows native API HANDLEs,
+ * or one that uses Posix style fds.
+ */
+extern bool rts_IOManagerIsWin32Native;
+#endif
+
#include "BeginPrivate.h"
/* The ./configure gives us a set of CPP flags, one for each named I/O manager:
@@ -160,14 +169,6 @@ typedef enum {
/* Global var to tell us which I/O manager impl we are using */
extern IOManagerType iomgr_type;
-#if defined(mingw32_HOST_OS)
-/* Global var (only on Windows) that is exported to be shared with the I/O code
- * in the base library to tell us which style of I/O manager we are using: one
- * that uses the Windows native API HANDLEs, or one that uses Posix style fds.
- */
-extern bool rts_IOManagerIsWin32Native;
-#endif
-
/* The CapIOManager is the per-capability data structure belonging to the I/O
* manager. It is defined in full in IOManagerInternals.h. The opaque forward
=====================================
rts/Linker.c
=====================================
@@ -478,16 +478,7 @@ initLinker_ (int retain_cafs)
symhash = allocStrHashTable();
/* populate the symbol table with stuff from the RTS */
- IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
- for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
- IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
- if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
- symhash, sym->lbl, sym->addr,
- sym->strength, sym->type, 0, NULL)) {
- barf("ghciInsertSymbolTable failed");
- }
- }
- IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
+ initLinkerRtsSyms(symhash);
/* Add extra symbols. rtsExtraSyms() is a weakly defined symbol in the rts,
* that can be overrided by linking in an object with a corresponding
=====================================
rts/LinkerInternals.h
=====================================
@@ -502,4 +502,6 @@ ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
void initSegment(Segment *s, void *start, size_t size, SegmentProt prot, int n_sections);
void freeSegments(ObjectCode *oc);
+void initLinkerRtsSyms(StrHashTable *symhash);
+
#include "EndPrivate.h"
=====================================
rts/RtsSymbols.c
=====================================
@@ -9,6 +9,8 @@
#include "ghcplatform.h"
#include "Rts.h"
#include "RtsSymbols.h"
+#include "LinkerInternals.h"
+#include "PathUtils.h"
#include "TopHandler.h"
#include "HsFFI.h"
@@ -51,6 +53,20 @@ extern char **environ;
/* -----------------------------------------------------------------------------
* Symbols to be inserted into the RTS symbol table.
+ *
+ * Note [Naming Scheme for Symbol Macros]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * SymI_*: symbol is internal to the RTS. It resides in an object
+ * file/library that is linked into the RTS library (as a static
+ * archive or dynamic shared library).
+ * SymE_*: symbol is external to the RTS library. It might be linked
+ * dynamically.
+ *
+ * Sym*_HasProto : the symbol prototype is imported in an include file
+ * or defined explicitly
+ * Sym*_NeedsProto: the symbol is undefined and we add a dummy
+ * default proto extern void sym(void);
*/
#define Maybe_Stable_Names SymI_HasProto(stg_mkWeakzh) \
@@ -162,7 +178,7 @@ extern char **environ;
SymI_HasProto(stg_asyncWritezh) \
SymI_HasProto(stg_asyncDoProczh) \
SymI_HasProto(rts_InstallConsoleEvent) \
- SymI_HasProto(rts_IOManagerIsWin32Native) \
+ SymI_HasDataProto(rts_IOManagerIsWin32Native) \
SymI_HasProto(rts_ConsoleHandlerDone) \
SymI_NeedsProto(__mingw_module_is_dll) \
RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \
@@ -913,7 +929,7 @@ extern char **environ;
SymI_HasProto(freeExecPage) \
SymI_HasProto(getAllocations) \
SymI_HasProto(revertCAFs) \
- SymI_HasProto(RtsFlags) \
+ SymI_HasDataProto(RtsFlags) \
SymI_NeedsDataProto(rts_breakpoint_io_action) \
SymI_NeedsDataProto(rts_stop_next_breakpoint) \
SymI_NeedsDataProto(rts_stop_on_exception) \
@@ -924,9 +940,9 @@ extern char **environ;
SymI_NeedsProto(rts_enableStopAfterReturn) \
SymI_NeedsProto(rts_disableStopAfterReturn) \
SymI_HasProto(stopTimer) \
- SymI_HasProto(n_capabilities) \
- SymI_HasProto(max_n_capabilities) \
- SymI_HasProto(enabled_capabilities) \
+ SymI_HasDataProto(n_capabilities) \
+ SymI_HasDataProto(max_n_capabilities) \
+ SymI_HasDataProto(enabled_capabilities) \
SymI_HasDataProto(stg_traceEventzh) \
SymI_HasDataProto(stg_traceMarkerzh) \
SymI_HasDataProto(stg_traceBinaryEventzh) \
@@ -1144,12 +1160,27 @@ extern char **environ;
SymI_HasProto(hs_word2float64)
-/* entirely bogus claims about types of these symbols */
-#define SymI_NeedsProto(vvv) extern void vvv(void);
-#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
-#define SymE_NeedsProto(vvv) SymI_NeedsProto(vvv);
-#define SymE_NeedsDataProto(vvv) SymI_NeedsDataProto(vvv);
-#define SymE_HasProto(vvv) SymI_HasProto(vvv);
+/* Declare prototypes for the symbols that need it, so we can refer
+ * to them in the rtsSyms table below.
+ *
+ * In particular, for the external ones (SymE_*) we use the dllimport attribute
+ * to indicate that (on Windows) they come from external DLLs. This attribute
+ * is ignored on other platforms.
+ *
+ * The claims about the types of these symbols are entirely bogus.
+ */
+#if defined(mingw32_HOST_OS) && defined(DYNAMIC)
+#define DLLIMPORT __attribute__((dllimport))
+#else
+#define DLLIMPORT /**/
+#endif
+
+#define SymI_NeedsProto(vvv) extern void vvv(void);
+#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
+#define SymE_NeedsProto(vvv) extern DLLIMPORT void vvv(void);
+#define SymE_NeedsDataProto(vvv) extern DLLIMPORT StgWord vvv[];
+
+#define SymE_HasProto(vvv) /**/
#define SymI_HasProto(vvv) /**/
#define SymI_HasDataProto(vvv) /**/
#define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
@@ -1178,6 +1209,8 @@ RTS_SYMBOLS_PRIM
#undef SymE_NeedsProto
#undef SymE_NeedsDataProto
+/* See Note [Naming Scheme for Symbol Macros] */
+
#define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
#define SymI_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
@@ -1198,7 +1231,16 @@ RTS_SYMBOLS_PRIM
{ MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(xxx)), strength, ty },
-RtsSymbolVal rtsSyms[] = {
+
+
+/* Initialize (if not already initialized) and return an array of symbols with stuff from the RTS. */
+void initLinkerRtsSyms (StrHashTable *symhash) {
+ /* The address of data symbols with the dllimport attribute are not
+ * compile-time constants and so cannot be used in constant initialisers.
+ * For this reason, rtsSyms is a local variable within this function
+ * rather than a global constant (as it was historically).
+ */
+ const RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS
RTS_RET_SYMBOLS
RTS_POSIX_ONLY_SYMBOLS
@@ -1213,7 +1255,20 @@ RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS_PRIM
SymI_HasDataProto(nonmoving_write_barrier_enabled)
{ 0, 0, STRENGTH_NORMAL, SYM_TYPE_CODE } /* sentinel */
-};
+ };
+
+ IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
+ for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
+ IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
+ if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
+ symhash, sym->lbl, sym->addr,
+ sym->strength, sym->type, 0, NULL)) {
+ barf("ghciInsertSymbolTable failed");
+ }
+ }
+ IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
+}
+
// Note [Extra RTS symbols]
=====================================
rts/RtsSymbols.h
=====================================
@@ -46,8 +46,6 @@ typedef struct _RtsSymbolVal {
SymType type;
} RtsSymbolVal;
-extern RtsSymbolVal rtsSyms[];
-
extern RtsSymbolVal* __attribute__((weak)) rtsExtraSyms(void);
/* See Note [_iob_func symbol]. */
=====================================
rts/linker/Elf.c
=====================================
@@ -76,18 +76,6 @@
*
* See bug #781
* See thread http://www.haskell.org/pipermail/cvs-ghc/2007-September/038458.html
- *
- * Naming Scheme for Symbol Macros
- *
- * SymI_*: symbol is internal to the RTS. It resides in an object
- * file/library that is statically.
- * SymE_*: symbol is external to the RTS library. It might be linked
- * dynamically.
- *
- * Sym*_HasProto : the symbol prototype is imported in an include file
- * or defined explicitly
- * Sym*_NeedsProto: the symbol is undefined and we add a dummy
- * default proto extern void sym(void);
*/
#define X86_64_ELF_NONPIC_HACK (!RtsFlags.MiscFlags.linkerAlwaysPic)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b3b923fb7d54c9b41221f026cc6433…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b3b923fb7d54c9b41221f026cc6433…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/27162/rts-explicit-dllimport_work] 3 commits: Use __attribute__((dllimport)) for external RTS symbol declarations
by David Eichmann (@DavidEichmann) 30 Apr '26
by David Eichmann (@DavidEichmann) 30 Apr '26
30 Apr '26
David Eichmann pushed to branch wip/27162/rts-explicit-dllimport_work at Glasgow Haskell Compiler / GHC
Commits:
5a6ba22b by Duncan Coutts at 2026-04-30T11:40:09+01:00
Use __attribute__((dllimport)) for external RTS symbol declarations
This is needed to be hygenic about DLL symbol imports and exports.
The attribute is ignored on platforms other than Windows.
Use of the attribute however means that external data symbols do not
have a compile-time constant address (they are loaded using an
indirection). This means we have to adjust the rtsSyms initial linker
table so that it is a local constant in a function, rather than a global
constant. We now define it within a function that pre-populates the
symbol table with the RTS symbols.
- - - - -
6833e03c by Duncan Coutts at 2026-04-30T11:40:09+01:00
Fix the rts linker declarations for a few data symbols
and ensure that the (windows only) rts_IOManagerIsWin32Native data
symbol is marked as externally visible.
- - - - -
793008fb by David Eichmann at 2026-04-30T11:40:09+01:00
Hadrian: Disable runtime pseudo relocations for RTS on windows hosts
- - - - -
7 changed files:
- hadrian/src/Settings/Packages.hs
- rts/IOManager.h
- rts/Linker.c
- rts/LinkerInternals.h
- rts/RtsSymbols.c
- rts/RtsSymbols.h
- rts/linker/Elf.c
Changes:
=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -321,6 +321,7 @@ rtsPackageArgs = package rts ? do
, Profiling `wayUnit` way ? arg "-DPROFILING"
, Threaded `wayUnit` way ? arg "-DTHREADED_RTS"
, notM targetSupportsSMP ? arg "-optc-DNOSMP"
+ , isWinHost ? arg "-optl-Wl,--disable-runtime-pseudo-reloc"
-- See Note [AutoApply.cmm for vectors] in genapply/Main.hs
--
=====================================
rts/IOManager.h
=====================================
@@ -21,6 +21,15 @@
#include "sm/GC.h" // for evac_fn
+#if defined(mingw32_HOST_OS)
+/* Global var (only on Windows) that is exported (hence before BeginPrivate.h)
+ * to be shared with the I/O code in the base library to tell us which style
+ * of I/O manager we are using: one that uses the Windows native API HANDLEs,
+ * or one that uses Posix style fds.
+ */
+extern bool rts_IOManagerIsWin32Native;
+#endif
+
#include "BeginPrivate.h"
/* The ./configure gives us a set of CPP flags, one for each named I/O manager:
@@ -160,14 +169,6 @@ typedef enum {
/* Global var to tell us which I/O manager impl we are using */
extern IOManagerType iomgr_type;
-#if defined(mingw32_HOST_OS)
-/* Global var (only on Windows) that is exported to be shared with the I/O code
- * in the base library to tell us which style of I/O manager we are using: one
- * that uses the Windows native API HANDLEs, or one that uses Posix style fds.
- */
-extern bool rts_IOManagerIsWin32Native;
-#endif
-
/* The CapIOManager is the per-capability data structure belonging to the I/O
* manager. It is defined in full in IOManagerInternals.h. The opaque forward
=====================================
rts/Linker.c
=====================================
@@ -478,16 +478,7 @@ initLinker_ (int retain_cafs)
symhash = allocStrHashTable();
/* populate the symbol table with stuff from the RTS */
- IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
- for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
- IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
- if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
- symhash, sym->lbl, sym->addr,
- sym->strength, sym->type, 0, NULL)) {
- barf("ghciInsertSymbolTable failed");
- }
- }
- IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
+ initLinkerRtsSyms(symhash);
/* Add extra symbols. rtsExtraSyms() is a weakly defined symbol in the rts,
* that can be overrided by linking in an object with a corresponding
=====================================
rts/LinkerInternals.h
=====================================
@@ -502,4 +502,6 @@ ObjectCode* mkOc( ObjectType type, pathchar *path, char *image, int imageSize,
void initSegment(Segment *s, void *start, size_t size, SegmentProt prot, int n_sections);
void freeSegments(ObjectCode *oc);
+void initLinkerRtsSyms(StrHashTable *symhash);
+
#include "EndPrivate.h"
=====================================
rts/RtsSymbols.c
=====================================
@@ -9,6 +9,8 @@
#include "ghcplatform.h"
#include "Rts.h"
#include "RtsSymbols.h"
+#include "LinkerInternals.h"
+#include "PathUtils.h"
#include "TopHandler.h"
#include "HsFFI.h"
@@ -51,6 +53,20 @@ extern char **environ;
/* -----------------------------------------------------------------------------
* Symbols to be inserted into the RTS symbol table.
+ *
+ * Note [Naming Scheme for Symbol Macros]
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * SymI_*: symbol is internal to the RTS. It resides in an object
+ * file/library that is linked into the RTS library (as a static
+ * archive or dynamic shared library).
+ * SymE_*: symbol is external to the RTS library. It might be linked
+ * dynamically.
+ *
+ * Sym*_HasProto : the symbol prototype is imported in an include file
+ * or defined explicitly
+ * Sym*_NeedsProto: the symbol is undefined and we add a dummy
+ * default proto extern void sym(void);
*/
#define Maybe_Stable_Names SymI_HasProto(stg_mkWeakzh) \
@@ -162,7 +178,7 @@ extern char **environ;
SymI_HasProto(stg_asyncWritezh) \
SymI_HasProto(stg_asyncDoProczh) \
SymI_HasProto(rts_InstallConsoleEvent) \
- SymI_HasProto(rts_IOManagerIsWin32Native) \
+ SymI_HasDataProto(rts_IOManagerIsWin32Native) \
SymI_HasProto(rts_ConsoleHandlerDone) \
SymI_NeedsProto(__mingw_module_is_dll) \
RTS_WIN64_ONLY(SymI_NeedsProto(___chkstk_ms)) \
@@ -913,7 +929,7 @@ extern char **environ;
SymI_HasProto(freeExecPage) \
SymI_HasProto(getAllocations) \
SymI_HasProto(revertCAFs) \
- SymI_HasProto(RtsFlags) \
+ SymI_HasDataProto(RtsFlags) \
SymI_NeedsDataProto(rts_breakpoint_io_action) \
SymI_NeedsDataProto(rts_stop_next_breakpoint) \
SymI_NeedsDataProto(rts_stop_on_exception) \
@@ -924,9 +940,9 @@ extern char **environ;
SymI_NeedsProto(rts_enableStopAfterReturn) \
SymI_NeedsProto(rts_disableStopAfterReturn) \
SymI_HasProto(stopTimer) \
- SymI_HasProto(n_capabilities) \
- SymI_HasProto(max_n_capabilities) \
- SymI_HasProto(enabled_capabilities) \
+ SymI_HasDataProto(n_capabilities) \
+ SymI_HasDataProto(max_n_capabilities) \
+ SymI_HasDataProto(enabled_capabilities) \
SymI_HasDataProto(stg_traceEventzh) \
SymI_HasDataProto(stg_traceMarkerzh) \
SymI_HasDataProto(stg_traceBinaryEventzh) \
@@ -1144,12 +1160,27 @@ extern char **environ;
SymI_HasProto(hs_word2float64)
-/* entirely bogus claims about types of these symbols */
-#define SymI_NeedsProto(vvv) extern void vvv(void);
-#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
-#define SymE_NeedsProto(vvv) SymI_NeedsProto(vvv);
-#define SymE_NeedsDataProto(vvv) SymI_NeedsDataProto(vvv);
-#define SymE_HasProto(vvv) SymI_HasProto(vvv);
+/* Declare prototypes for the symbols that need it, so we can refer
+ * to them in the rtsSyms table below.
+ *
+ * In particular, for the external ones (SymE_*) we use the dllimport attribute
+ * to indicate that (on Windows) they come from external DLLs. This attribute
+ * is ignored on other platforms.
+ *
+ * The claims about the types of these symbols are entirely bogus.
+ */
+#if defined(mingw32_HOST_OS) && defined(DYNAMIC)
+#define DLLIMPORT __attribute__((dllimport))
+#else
+#define DLLIMPORT /**/
+#endif
+
+#define SymI_NeedsProto(vvv) extern void vvv(void);
+#define SymI_NeedsDataProto(vvv) extern StgWord vvv[];
+#define SymE_NeedsProto(vvv) extern DLLIMPORT void vvv(void);
+#define SymE_NeedsDataProto(vvv) extern DLLIMPORT StgWord vvv[];
+
+#define SymE_HasProto(vvv) /**/
#define SymI_HasProto(vvv) /**/
#define SymI_HasDataProto(vvv) /**/
#define SymI_HasProto_redirect(vvv,xxx,strength,ty) /**/
@@ -1178,6 +1209,8 @@ RTS_SYMBOLS_PRIM
#undef SymE_NeedsProto
#undef SymE_NeedsDataProto
+/* See Note [Naming Scheme for Symbol Macros] */
+
#define SymI_HasProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(vvv)), STRENGTH_NORMAL, SYM_TYPE_CODE },
#define SymI_HasDataProto(vvv) { MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
@@ -1198,7 +1231,16 @@ RTS_SYMBOLS_PRIM
{ MAYBE_LEADING_UNDERSCORE_STR(#vvv), \
(void*)(&(xxx)), strength, ty },
-RtsSymbolVal rtsSyms[] = {
+
+
+/* Initialize (if not already initialized) and return an array of symbols with stuff from the RTS. */
+void initLinkerRtsSyms (StrHashTable *symhash) {
+ /* The address of data symbols with the dllimport attribute are not
+ * compile-time constants and so cannot be used in constant initialisers.
+ * For this reason, rtsSyms is a local variable within this function
+ * rather than a global constant (as it was historically).
+ */
+ const RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS
RTS_RET_SYMBOLS
RTS_POSIX_ONLY_SYMBOLS
@@ -1213,7 +1255,20 @@ RtsSymbolVal rtsSyms[] = {
RTS_SYMBOLS_PRIM
SymI_HasDataProto(nonmoving_write_barrier_enabled)
{ 0, 0, STRENGTH_NORMAL, SYM_TYPE_CODE } /* sentinel */
-};
+ };
+
+ IF_DEBUG(linker, debugBelch("populating linker symbol table with built-in RTS symbols\n"));
+ for (const RtsSymbolVal *sym = rtsSyms; sym->lbl != NULL; sym++) {
+ IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
+ if (! ghciInsertSymbolTable(WSTR("(GHCi built-in symbols)"),
+ symhash, sym->lbl, sym->addr,
+ sym->strength, sym->type, 0, NULL)) {
+ barf("ghciInsertSymbolTable failed");
+ }
+ }
+ IF_DEBUG(linker, debugBelch("done with built-in RTS symbols\n"));
+}
+
// Note [Extra RTS symbols]
=====================================
rts/RtsSymbols.h
=====================================
@@ -46,8 +46,6 @@ typedef struct _RtsSymbolVal {
SymType type;
} RtsSymbolVal;
-extern RtsSymbolVal rtsSyms[];
-
extern RtsSymbolVal* __attribute__((weak)) rtsExtraSyms(void);
/* See Note [_iob_func symbol]. */
=====================================
rts/linker/Elf.c
=====================================
@@ -76,18 +76,6 @@
*
* See bug #781
* See thread http://www.haskell.org/pipermail/cvs-ghc/2007-September/038458.html
- *
- * Naming Scheme for Symbol Macros
- *
- * SymI_*: symbol is internal to the RTS. It resides in an object
- * file/library that is statically.
- * SymE_*: symbol is external to the RTS library. It might be linked
- * dynamically.
- *
- * Sym*_HasProto : the symbol prototype is imported in an include file
- * or defined explicitly
- * Sym*_NeedsProto: the symbol is undefined and we add a dummy
- * default proto extern void sym(void);
*/
#define X86_64_ELF_NONPIC_HACK (!RtsFlags.MiscFlags.linkerAlwaysPic)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b3b923fb7d54c9b41221f026cc6433…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b3b923fb7d54c9b41221f026cc6433…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/fendor/fix-note-dep_boot_deps] Fix name of Note [Structure of dep_boot_mods]
by Hannes Siebenhandl (@fendor) 30 Apr '26
by Hannes Siebenhandl (@fendor) 30 Apr '26
30 Apr '26
Hannes Siebenhandl pushed to branch wip/fendor/fix-note-dep_boot_deps at Glasgow Haskell Compiler / GHC
Commits:
7200d2e4 by fendor at 2026-04-30T11:05:47+02:00
Fix name of Note [Structure of dep_boot_mods]
- - - - -
1 changed file:
- compiler/GHC/Unit/Module/Deps.hs
Changes:
=====================================
compiler/GHC/Unit/Module/Deps.hs
=====================================
@@ -96,7 +96,7 @@ data Dependencies = Deps
, dep_boot_mods_ :: Set (UnitId, ModuleNameWithIsBoot)
-- ^ All modules which have boot files below this one, and whether we
-- should use the boot file or not.
- -- This information is only used to populate the eps_is_boot field.
+ -- This information is only used to populate the 'eps_is_boot' field.
-- See Note [Structure of dep_boot_mods]
, dep_orphs_ :: [Module]
@@ -605,7 +605,7 @@ hash of the module. The export hash is computed in `GHC.Iface.Recomp.addFingerpr
-}
{-
-Note [Structure of dep_boot_deps]
+Note [Structure of dep_boot_mods]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In `-c` mode we always need to know whether to load the normal or boot version of
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7200d2e4c79832b45aa69d1b6dd51d7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7200d2e4c79832b45aa69d1b6dd51d7…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/fendor/fix-note-dep_boot_deps
by Hannes Siebenhandl (@fendor) 30 Apr '26
by Hannes Siebenhandl (@fendor) 30 Apr '26
30 Apr '26
Hannes Siebenhandl pushed new branch wip/fendor/fix-note-dep_boot_deps at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fendor/fix-note-dep_boot_deps
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Replace GHC 9.16 references with GHC 10.0
by Marge Bot (@marge-bot) 30 Apr '26
by Marge Bot (@marge-bot) 30 Apr '26
30 Apr '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
e16854c3 by Vladislav Zavialov at 2026-04-30T04:56:57-04:00
Replace GHC 9.16 references with GHC 10.0
- - - - -
10 changed files:
- compiler/GHC/Driver/Flags.hs
- docs/users_guide/debug-info.rst
- docs/users_guide/exts/explicit_namespaces.rst
- docs/users_guide/exts/linear_types.rst
- docs/users_guide/exts/modifiers.rst
- docs/users_guide/exts/qualified_strings.rst
- docs/users_guide/exts/required_type_arguments.rst
- docs/users_guide/using-warnings.rst
- docs/users_guide/using.rst
- testsuite/tests/typecheck/should_fail/all.T
Changes:
=====================================
compiler/GHC/Driver/Flags.hs
=====================================
@@ -1112,9 +1112,9 @@ data WarningFlag =
-- ^ @since 9.14, scheduled to be removed in 9.18
--
-- See Note [Quantifying over equalities in RULES] in GHC.Tc.Gen.Sig
- | Opt_WarnUnusableUnpackPragmas -- Since 9.14
- | Opt_WarnPatternNamespaceSpecifier -- Since 9.14
- | Opt_WarnUnrecognisedModifiers -- ^ @since 9.16
+ | Opt_WarnUnusableUnpackPragmas -- ^ @since 9.14
+ | Opt_WarnPatternNamespaceSpecifier -- ^ @since 9.14
+ | Opt_WarnUnrecognisedModifiers -- ^ @since 10.0
deriving (Eq, Ord, Show, Enum, Bounded)
-- | Return the names of a WarningFlag
@@ -1377,7 +1377,7 @@ standardWarnings -- see Note [Documenting warning flags]
Opt_WarnTypeEqualityRequiresOperators,
Opt_WarnInconsistentFlags,
Opt_WarnTypeEqualityOutOfScope,
- Opt_WarnImplicitRhsQuantification, -- was in -Wcompat since 9.8, enabled by default since 9.14, to turn into a hard error in 9.16
+ Opt_WarnImplicitRhsQuantification, -- was in -Wcompat since 9.8, enabled by default since 9.14, to turn into a hard error in 10.2 (#25911)
Opt_WarnViewPatternSignatures,
Opt_WarnUselessSpecialisations,
Opt_WarnDeprecatedPragmas,
=====================================
docs/users_guide/debug-info.rst
=====================================
@@ -478,7 +478,7 @@ to a source location. This lookup table is generated by using the ``-finfo-table
:type: dynamic
:category: debugging
- :since: 9.16
+ :since: 10.0
Disable generation of distinct info tables for all constructors.
@@ -488,7 +488,7 @@ to a source location. This lookup table is generated by using the ``-finfo-table
:type: dynamic
:category: debugging
- :since: 9.16
+ :since: 10.0
The entries in the info table map resulting from
:ghc-flag:`-fdistinct-constructor-tables` flag may significantly
=====================================
docs/users_guide/exts/explicit_namespaces.rst
=====================================
@@ -121,7 +121,7 @@ there is a need to support older GHC versions.
Wildcards in import/export lists
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**Since:** GHC 9.16
+**Since:** GHC 10.0
Namespace-specified wildcards ``type ..`` and ``data ..`` may be used to import
all names in the corresponding namespace from a module: ::
=====================================
docs/users_guide/exts/linear_types.rst
=====================================
@@ -318,7 +318,7 @@ hidden; it is an essential part of the exposed interface.)
Interaction with Modifiers
--------------------------
-Since GHC version 9.16, Linear types use :extension:`Modifiers` syntax, and by
+Since GHC version 10.0, Linear types use :extension:`Modifiers` syntax, and by
default enable that extension. In earlier versions, linear types used a more
restricted variant of that syntax.
=====================================
docs/users_guide/exts/modifiers.rst
=====================================
@@ -6,7 +6,7 @@ Modifiers
.. extension:: Modifiers
:shortdesc: Allow experimental modifier syntax.
- :since: 9.16
+ :since: 10.0
:status: Experimental
Enable modifier syntax in various places, such as arrows (``a %m -> b``) and
@@ -138,10 +138,10 @@ and limitations.
let %1 (Just x) = ... -- (2b)
let %1 !(Just x) = ... -- (2c)
- In 9.14, (1a) and (2a) parsed as (1b) and (2b) respectively. From 9.16, (1a)
+ In 9.14, (1a) and (2a) parsed as (1b) and (2b) respectively. From 10.0, (1a)
parses as (1d), and (2a) fails to parse.
- Note that linear bindings must be strict. (1c) and (2c) parse in 9.16 the same
+ Note that linear bindings must be strict. (1c) and (2c) parse in 10.0 the same
as in 9.14. But with ``-XStrict`` enabled, (1a) and (2a) would previously have
been accepted, and are now rejected, even with
``-XLinearTypes -XNoModifiers``.
=====================================
docs/users_guide/exts/qualified_strings.rst
=====================================
@@ -6,7 +6,7 @@ Qualified string literals
.. extension:: QualifiedStrings
:shortdesc: Enable qualified string literals.
- :since: 9.16.1
+ :since: 10.0.1
Enable qualified string literals.
=====================================
docs/users_guide/exts/required_type_arguments.rst
=====================================
@@ -303,7 +303,7 @@ A few limitations apply:
* In term syntax, in positions where ``*`` is a direct argument to ``->``, e.g.
in ``f (* -> * -> *)`` and ``f (* -> Constraint)``, the ``*``\s stand for
``Type``, provided the :extension:`StarIsType` extension is enabled.
- This is supported from GHC 9.16 onwards; earlier versions will produce
+ This is supported from GHC 10.0 onwards; earlier versions will produce
a parse error.
What to do instead: use ``Type`` from the ``Data.Kind`` module.
=====================================
docs/users_guide/using-warnings.rst
=====================================
@@ -2711,7 +2711,7 @@ of ``-W(no-)*``.
:type: dynamic
:reverse: -Wno-unrecognised-modifiers
- :since: 9.16
+ :since: 10.0
:default: on
=====================================
docs/users_guide/using.rst
=====================================
@@ -1618,7 +1618,7 @@ Some flags only make sense for particular target platforms.
:type: dynamic
:category: platform-options
- :since: 9.16.1
+ :since: 10.0.1
:implies: :ghc-flag:`-mavx512f`
(x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
@@ -1639,7 +1639,7 @@ Some flags only make sense for particular target platforms.
:type: dynamic
:category: platform-options
- :since: 9.16.1
+ :since: 10.0.1
:implies: :ghc-flag:`-mavx512f`
(x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
@@ -1684,7 +1684,7 @@ Some flags only make sense for particular target platforms.
:type: dynamic
:category: platform-options
- :since: 9.16.1
+ :since: 10.0.1
:implies: :ghc-flag:`-mavx512f`
(x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
@@ -1823,7 +1823,7 @@ Some flags only make sense for particular target platforms.
:type: dynamic
:category: platform-options
- :since: 9.16.1
+ :since: 10.0.1
(x86 only) This flag allows the code generator (whether the :ref:`native code generator <native-code-gen>`
or the :ref:`LLVM backend <llvm-code-gen>`) to emit x86 GFNI instructions.
=====================================
testsuite/tests/typecheck/should_fail/all.T
=====================================
@@ -720,7 +720,7 @@ test('T17940', normal, compile_fail, [''])
test('ErrorIndexLinks', normal, compile_fail, ['-fprint-error-index-links=always'])
test('T24064', normal, compile_fail, [''])
test('T24090a', normal, compile_fail, [''])
-test('T24090b', normal, compile, ['']) # scheduled to become an actual error in GHC 9.16
+test('T24090b', normal, compile, ['']) # scheduled to become an actual error in GHC 10.2 (#25911)
test('T24298', normal, compile_fail, [''])
test('T24279', normal, compile, ['']) # Now accepted (Nov 2025)
test('T24318', normal, compile_fail, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e16854c3d812806bb705fbdbd7cc25c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e16854c3d812806bb705fbdbd7cc25c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] compiler: avoid unique OccNames for internal Names in bytecode objects
by Marge Bot (@marge-bot) 30 Apr '26
by Marge Bot (@marge-bot) 30 Apr '26
30 Apr '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
2128ba85 by Cheng Shao at 2026-04-30T04:56:14-04:00
compiler: avoid unique OccNames for internal Names in bytecode objects
This patch improves bytecode object serialization logic by avoiding
the construction of unique `OccName`s when serializing/deserializing
internal `Name`s. Closes #27213.
-------------------------
Metric Decrease:
LinkableUsage01
-------------------------
- - - - -
1 changed file:
- compiler/GHC/ByteCode/Binary.hs
Changes:
=====================================
compiler/GHC/ByteCode/Binary.hs
=====================================
@@ -20,7 +20,7 @@ module GHC.ByteCode.Binary (
import GHC.Prelude
import GHC.ByteCode.Types
-import GHC.Data.FastString
+import qualified GHC.Data.Word64Map.Strict as Word64Map
import GHC.Types.Name
import GHC.Types.Name.Cache
import GHC.Types.Name.Env
@@ -291,9 +291,8 @@ addBinNameWriter bh' = do
| otherwise -> do
putByte bh 1
key <- getBinNameKey env_ref nm
- -- Delimit the OccName from the deterministic counter to keep the
- -- encoding injective, avoiding collisions like "foo1" vs "foo#1".
- put_ bh (occNameFS (occName nm) `appendFS` mkFastString ('#' : show key))
+ put_ bh $ occNameFS $ occName nm
+ put_ bh key
where
-- Find a deterministic key for local names. This
getBinNameKey ref name = do
@@ -304,7 +303,7 @@ addBinNameWriter bh' = do
addBinNameReader :: NameCache -> ReadBinHandle -> IO ReadBinHandle
addBinNameReader nc bh' = do
- env_ref <- newIORef emptyOccEnv
+ env_ref <- newIORef Word64Map.empty
pure $ flip addReaderToUserData bh' $ BinaryReader $ \bh -> do
t <- getByte bh
case t of
@@ -313,15 +312,16 @@ addBinNameReader nc bh' = do
pure $ BinName nm
1 -> do
occ <- mkVarOccFS <$> get bh
+ key <- get bh
-- We don't want to get a new unique from the NameCache each time we
-- see a name.
nm' <- unsafeInterleaveIO $ do
u <- takeUniqFromNameCache nc
evaluate $ mkInternalName u occ noSrcSpan
fmap BinName $ atomicModifyIORef' env_ref $ \env ->
- case lookupOccEnv env occ of
+ case Word64Map.lookup key env of
Just nm -> (env, nm)
- _ -> nm' `seq` (extendOccEnv env occ nm', nm')
+ _ -> nm' `seq` (Word64Map.insert key nm' env, nm')
_ -> panic "Binary BinName: invalid byte"
-- Note [Serializing Names in bytecode]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2128ba85729762660ddddefcd9509fc…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2128ba85729762660ddddefcd9509fc…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Split GHC.Driver.Main.hs up into multiple components.
by Marge Bot (@marge-bot) 30 Apr '26
by Marge Bot (@marge-bot) 30 Apr '26
30 Apr '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
3d41368f by Andreas Klebinger at 2026-04-30T04:55:32-04:00
Split GHC.Driver.Main.hs up into multiple components.
This commit splits GHC.Driver.Main into four components:
* GHC.Driver.Main.Compile
* GHC.Driver.Main.Hsc
* GHC.Driver.Main.Interactive
* GHC.Driver.Main.Passes
We might improve that separation further in the future but this should
hopefully make it easier to reason about and work with this part of the
code.
- - - - -
15 changed files:
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Env/Types.hs
- compiler/GHC/Driver/Main.hs
- + compiler/GHC/Driver/Main/Compile.hs
- compiler/GHC/Driver/Main.hs-boot → compiler/GHC/Driver/Main/Compile.hs-boot
- + compiler/GHC/Driver/Main/Hsc.hs
- + compiler/GHC/Driver/Main/Interactive.hs
- + compiler/GHC/Driver/Main/Passes.hs
- + compiler/GHC/Driver/Main/Passes.hs-boot
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Tidy.hs
- compiler/GHC/Types/Error.hs
- compiler/GHC/Types/Error.hs-boot
- compiler/ghc.cabal.in
- testsuite/tests/linters/notes.stdout
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d41368f3c55a23d4fe50bc59ff52c7…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3d41368f3c55a23d4fe50bc59ff52c7…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: Hadrian: withResponseFile outputs response file when verbodity is Verbose
by Marge Bot (@marge-bot) 30 Apr '26
by Marge Bot (@marge-bot) 30 Apr '26
30 Apr '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
a4ff6315 by David Eichmann at 2026-04-30T04:54:51-04:00
Hadrian: withResponseFile outputs response file when verbodity is Verbose
At the Verbose verbosity, shake will display full commandlines. With the
use of response files, the full command is hidden. That makes it hard to run
the command manually. This commit outputs the contents of the response
file so that that full command can be recreated and also hints at the
use of the --keep-response-files hadrian flag.
- - - - -
cd732ee3 by Duncan Coutts at 2026-04-30T04:54:51-04:00
Use response files for hadrian linking with ghc (support long command lines)
In future support for windows dynamic linking, we expect long command
lines for linking dll files with ghc. Experiments with dynamic linking the
ghc-internal library yielded a link command well over 32kb. We did not
encounter this before for static libs, since we already use ar's @file
feature (if available, which it is for the llvm toolchain).
Co-authored-by: David Eichmann <davide(a)well-typed.com>
- - - - -
4 changed files:
- hadrian/src/Builder.hs
- hadrian/src/Hadrian/Builder.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Settings/Builders/Ghc.hs
Changes:
=====================================
hadrian/src/Builder.hs
=====================================
@@ -345,11 +345,7 @@ instance H.Builder Builder where
Haddock BuildPackage -> runHaddock path buildArgs buildInputs
- Ghc FindHsDependencies _ -> do
- -- Use a response file for ghc -M invocations, to
- -- avoid issues with command line size limit on
- -- Windows (#26637)
- runGhcWithResponse path buildArgs buildInputs
+ Ghc _ _ -> runGhcWithResponse path buildArgs buildInputs buildOptions
HsCpp -> captureStdout
@@ -393,14 +389,19 @@ runHaddock haddockPath flagArgs fileInputs = withResponseFile $ \tmp -> do
writeFile' tmp $ escapeArgs fileInputs
cmd [haddockPath] flagArgs ('@' : tmp)
-runGhcWithResponse :: FilePath -> [String] -> [FilePath] -> Action ()
-runGhcWithResponse ghcPath flagArgs fileInputs = withResponseFile $ \tmp -> do
- writeFile' tmp $ escapeArgs fileInputs
- -- We can't put the flags in a response file, because some flags
- -- require empty arguments (such as the -dep-suffix flag), but
- -- that isn't supported yet due to #26560.
- cmd [ghcPath] flagArgs ('@' : tmp)
-
+-- | Use a response file for ghc invocations to avoid issues with command line
+-- size limit on Windows (#26637).
+runGhcWithResponse :: FilePath -- ^ Path to ghc
+ -> [String] -- ^ Arguments passed on the command line
+ -> [FilePath] -- ^ Input file paths (passed via response file)
+ -> [CmdOption]
+ -> Action ()
+runGhcWithResponse ghcPath buildArgs buildInputs buildOptions = withResponseFile $ \tmp -> do
+ -- We can't put the buildArgs in a response file, because some flags require
+ -- empty arguments (such as the -dep-suffix flag), but that isn't supported
+ -- yet due to #26560.
+ writeFile' tmp (escapeArgs buildInputs)
+ cmd [ghcPath] buildArgs ('@' : tmp) buildOptions
-- TODO: Some builders are required only on certain platforms. For example,
-- 'Objdump' is only required on OpenBSD and AIX. Add support for platform
=====================================
hadrian/src/Hadrian/Builder.hs
=====================================
@@ -29,7 +29,9 @@ import Hadrian.Utilities
-- | This data structure captures all information relevant to invoking a builder.
data BuildInfo = BuildInfo {
- -- | Command line arguments.
+ -- | Command line arguments. Some builders (e.g. Ar, Ghc, Haddock) omit
+ -- buildInputs from buildArgs so that buildInputs can be passed separately
+ -- using a response file.
buildArgs :: [String],
-- | Input files.
buildInputs :: [FilePath],
=====================================
hadrian/src/Hadrian/Utilities.hs
=====================================
@@ -334,13 +334,23 @@ keepResponseFiles = do
withResponseFile :: (FilePath -> Action a) -> Action a
withResponseFile action = do
keep <- keepResponseFiles
+ let putVerboseResponseFile tmp = do
+ verbosity <- getVerbosity
+ when (verbosity >= Verbose) $ do
+ tmpContent <- liftIO (readFile tmp)
+ putVerbose (tmp <> " (use hadrian flag --keep-response-files to keep this file):\n" <> tmpContent)
if keep
then do
(tmp, h) <- liftIO $ openTempFile "." "hadrian-rsp"
liftIO $ hClose h
putInfo $ "Keeping response file: " ++ tmp
- action tmp
- else withTempFile action
+ result <- action tmp
+ putVerboseResponseFile tmp
+ return result
+ else withTempFile $ \tmp -> do
+ result <- action tmp
+ putVerboseResponseFile tmp
+ return result
-- | Link a file tracking the link target. Create the target directory if
-- missing.
=====================================
hadrian/src/Settings/Builders/Ghc.hs
=====================================
@@ -62,7 +62,6 @@ compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do
[ arg "-fwrite-ide-info"
, arg "-hiedir", arg hie_path
]
- , getInputs
, arg "-o", arg =<< getOutput ]
compileC :: Args
@@ -78,7 +77,6 @@ compileC = builder (Ghc CompileCWithGhc) ? do
, mconcat (map (map ("-optc" ++) <$>) ccArgs)
, defaultGhcWarningsArgs
, arg "-c"
- , getInputs
, arg "-o"
, arg =<< getOutput ]
@@ -95,7 +93,6 @@ compileCxx = builder (Ghc CompileCppWithGhc) ? do
, mconcat (map (map ("-optcxx" ++) <$>) ccArgs)
, defaultGhcWarningsArgs
, arg "-c"
- , getInputs
, arg "-o"
, arg =<< getOutput ]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce97fd3ed13028034ba27c34a6decd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce97fd3ed13028034ba27c34a6decd…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: New rts Message to {set,unset} TSO flags
by Marge Bot (@marge-bot) 30 Apr '26
by Marge Bot (@marge-bot) 30 Apr '26
30 Apr '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
5bd6a964 by Rodrigo Mesquita at 2026-04-30T04:54:08-04:00
New rts Message to {set,unset} TSO flags
This commit introduces stg_MSG_SET_TSO_FLAG_info and
stg_MSG_UNSET_TSO_FLAG_info, which allows setting flags of a TSO other
than yourself.
This is especially useful/necessary to set breakpoints and toggle
breakpoints of different threads, which is needed to safely implement
features like pausing, toggling step-out, toggling step-in per thread,
etc.
Fixes #27131
-------------------------
Metric Decrease:
T3294
-------------------------
- - - - -
ce97fd3e by Rodrigo Mesquita at 2026-04-30T04:54:08-04:00
test: Add test setting another TSO's flags
Introduces a test that runs on two capabilities. The main thread running
on Capability 0 sets the flags on a TSO running on Capability 1.
The TSO from Capability 1 itself checks whether its flags were set and
reports that back.
This validates that the RTS messages for setting TSO flags work, even if
it doesn't test a harsher scenario with race conditions to exercise why
the message passing is necessary for safely setting another TSO's flags.
Part of #27131
- - - - -
12 changed files:
- + changelog.d/T27131
- rts/Interpreter.c
- rts/Messages.c
- rts/StgMiscClosures.cmm
- rts/Threads.c
- rts/Threads.h
- rts/include/rts/storage/Closures.h
- rts/include/stg/MiscClosures.h
- + testsuite/tests/rts/T27131.hs
- + testsuite/tests/rts/T27131.stdout
- + testsuite/tests/rts/T27131_c.c
- testsuite/tests/rts/all.T
Changes:
=====================================
changelog.d/T27131
=====================================
@@ -0,0 +1,8 @@
+section: rts
+synopsis: Add rts Message to set/unset TSO flags
+issues: #27131
+mrs: !15831
+description: This enables e.g. toggling breakpoints from different threads,
+ which is necessary to safely implement features like pausing, per-thread
+ step-in, and more in the haskell debugger.
+
=====================================
rts/Interpreter.c
=====================================
@@ -416,12 +416,22 @@ void rts_disableStopNextBreakpointAll(void)
void rts_enableStopNextBreakpoint(StgTSO* tso)
{
- tso->flags |= TSO_STOP_NEXT_BREAKPOINT;
+#if defined(THREADED_RTS)
+ Capability* cap = rts_unsafeGetMyCapability();
+ setThreadFlag(cap, tso, TSO_STOP_NEXT_BREAKPOINT);
+#else
+ tso->flags |= TSO_STOP_NEXT_BREAKPOINT;
+#endif
}
void rts_disableStopNextBreakpoint(StgTSO* tso)
{
- tso->flags &= ~TSO_STOP_NEXT_BREAKPOINT;
+#if defined(THREADED_RTS)
+ Capability* cap = rts_unsafeGetMyCapability();
+ unsetThreadFlag(cap, tso, TSO_STOP_NEXT_BREAKPOINT);
+#else
+ tso->flags &= ~TSO_STOP_NEXT_BREAKPOINT;
+#endif
}
/* ---------------------------------------------------------------------------
@@ -430,12 +440,22 @@ void rts_disableStopNextBreakpoint(StgTSO* tso)
void rts_enableStopAfterReturn(StgTSO* tso)
{
+#if defined(THREADED_RTS)
+ Capability* cap = rts_unsafeGetMyCapability();
+ setThreadFlag(cap, tso, TSO_STOP_AFTER_RETURN);
+#else
tso->flags |= TSO_STOP_AFTER_RETURN;
+#endif
}
void rts_disableStopAfterReturn(StgTSO* tso)
{
+#if defined(THREADED_RTS)
+ Capability* cap = rts_unsafeGetMyCapability();
+ unsetThreadFlag(cap, tso, TSO_STOP_AFTER_RETURN);
+#else
tso->flags &= ~TSO_STOP_AFTER_RETURN;
+#endif
}
/*
=====================================
rts/Messages.c
=====================================
@@ -35,7 +35,9 @@ void sendMessage(Capability *from_cap, Capability *to_cap, Message *msg)
i != &stg_MSG_TRY_WAKEUP_info &&
i != &stg_IND_info && // can happen if a MSG_BLACKHOLE is revoked
i != &stg_WHITEHOLE_info &&
- i != &stg_MSG_CLONE_STACK_info) {
+ i != &stg_MSG_CLONE_STACK_info &&
+ i != &stg_MSG_SET_TSO_FLAG_info &&
+ i != &stg_MSG_UNSET_TSO_FLAG_info) {
barf("sendMessage: %p", i);
}
}
@@ -137,6 +139,16 @@ loop:
MessageCloneStack *cloneStackMessage = (MessageCloneStack*) m;
handleCloneStackMessage(cap, cloneStackMessage);
}
+ else if(i == &stg_MSG_SET_TSO_FLAG_info){
+ MessageUpdTSOFlag *u = (MessageUpdTSOFlag*) m;
+ u->tso->flags |= u->flag;
+ return;
+ }
+ else if(i == &stg_MSG_UNSET_TSO_FLAG_info){
+ MessageUpdTSOFlag *u = (MessageUpdTSOFlag*) m;
+ u->tso->flags &= ~u->flag;
+ return;
+ }
else
{
barf("executeMessage: %p", i);
=====================================
rts/StgMiscClosures.cmm
=====================================
@@ -855,6 +855,12 @@ INFO_TABLE_CONSTR(stg_MSG_NULL,1,0,0,PRIM,"MSG_NULL","MSG_NULL")
INFO_TABLE_CONSTR(stg_MSG_CLONE_STACK,3,0,0,PRIM,"MSG_CLONE_STACK","MSG_CLONE_STACK")
{ ccall pbarf("stg_MSG_CLONE_STACK object (%p) entered!", R1 "ptr") never returns; }
+INFO_TABLE_CONSTR(stg_MSG_SET_TSO_FLAG,2,1,0,PRIM,"MSG_SET_TSO_FLAG","MSG_SET_TSO_FLAG")
+{ foreign "C" barf("stg_MSG_SET_TSO_FLAG object (%p) entered!", R1) never returns; }
+
+INFO_TABLE_CONSTR(stg_MSG_UNSET_TSO_FLAG,2,1,0,PRIM,"MSG_UNSET_TSO_FLAG","MSG_UNSET_TSO_FLAG")
+{ foreign "C" barf("stg_MSG_UNSET_TSO_FLAG object (%p) entered!", R1) never returns; }
+
/* ----------------------------------------------------------------------------
END_TSO_QUEUE
=====================================
rts/Threads.c
=====================================
@@ -376,6 +376,38 @@ migrateThread (Capability *from, StgTSO *tso, Capability *to)
tryWakeupThread(from, tso);
}
+/* ----------------------------------------------------------------------------
+ {set,unset}ThreadFlag
+
+ sets or unsets a flag in a given TSO
+ ------------------------------------------------------------------------- */
+
+#if defined(THREADED_RTS)
+static void
+updThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag, const StgInfoTable* info);
+
+void setThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag)
+{
+ updThreadFlag(from, tso, flag, &stg_MSG_SET_TSO_FLAG_info);
+}
+
+void unsetThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag)
+{
+ updThreadFlag(from, tso, flag, &stg_MSG_UNSET_TSO_FLAG_info);
+}
+
+static void
+updThreadFlag(Capability *from, StgTSO *tso, StgWord32 flag, const StgInfoTable* info)
+{
+ MessageUpdTSOFlag *msg;
+ msg = (MessageUpdTSOFlag *)allocate(from,sizeofW(MessageUpdTSOFlag));
+ msg->tso = tso;
+ msg->flag = flag;
+ SET_HDR_RELEASE(msg, info, CCS_SYSTEM);
+ sendMessage(from, tso->cap, (Message*)msg);
+}
+#endif
+
/* ----------------------------------------------------------------------------
awakenBlockedQueue
=====================================
rts/Threads.h
=====================================
@@ -19,6 +19,11 @@ void checkBlockingQueues (Capability *cap, StgTSO *tso);
void tryWakeupThread (Capability *cap, StgTSO *tso);
void migrateThread (Capability *from, StgTSO *tso, Capability *to);
+#if defined(THREADED_RTS)
+void setThreadFlag (Capability *from, StgTSO *tso, StgWord32 flag);
+void unsetThreadFlag (Capability *from, StgTSO *tso, StgWord32 flag);
+#endif
+
// Wakes up a thread on a Capability (probably a different Capability
// from the one held by the current Task).
//
=====================================
rts/include/rts/storage/Closures.h
=====================================
@@ -620,6 +620,12 @@ typedef struct MessageCloneStack_ {
StgTSO *tso;
} MessageCloneStack;
+typedef struct MessageUpdTSOFlag_ {
+ StgHeader header;
+ Message *link;
+ StgTSO *tso;
+ StgWord flag;
+} MessageUpdTSOFlag;
/* ----------------------------------------------------------------------------
Compact Regions
=====================================
rts/include/stg/MiscClosures.h
=====================================
@@ -152,6 +152,8 @@ RTS_ENTRY(stg_MSG_TRY_WAKEUP);
RTS_ENTRY(stg_MSG_THROWTO);
RTS_ENTRY(stg_MSG_BLACKHOLE);
RTS_ENTRY(stg_MSG_CLONE_STACK);
+RTS_ENTRY(stg_MSG_SET_TSO_FLAG);
+RTS_ENTRY(stg_MSG_UNSET_TSO_FLAG);
RTS_ENTRY(stg_MSG_NULL);
RTS_ENTRY(stg_MVAR_TSO_QUEUE);
RTS_ENTRY(stg_catch);
=====================================
testsuite/tests/rts/T27131.hs
=====================================
@@ -0,0 +1,81 @@
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE UnliftedFFITypes #-}
+
+module Main where
+
+import Control.Concurrent
+import Control.Monad
+import Foreign.C.Types
+import GHC.Conc.Sync (ThreadId(..), forkOn, myThreadId, setNumCapabilities)
+import GHC.Exts (ThreadId#)
+
+foreign import ccall unsafe "rts_enableStopNextBreakpoint"
+ rts_enableStopNextBreakpoint :: ThreadId# -> IO ()
+
+foreign import ccall unsafe "rts_disableStopNextBreakpoint"
+ rts_disableStopNextBreakpoint :: ThreadId# -> IO ()
+
+foreign import ccall unsafe "rts_enableStopAfterReturn"
+ rts_enableStopAfterReturn :: ThreadId# -> IO ()
+
+foreign import ccall unsafe "rts_disableStopAfterReturn"
+ rts_disableStopAfterReturn :: ThreadId# -> IO ()
+
+foreign import ccall unsafe "has_local_stop_next_breakpoint"
+ c_hasLocalStopNextBreakpoint :: IO CInt
+
+foreign import ccall unsafe "has_local_stop_after_return"
+ c_hasLocalStopAfterReturn :: IO CInt
+
+main :: IO ()
+main = do
+ setNumCapabilities 2
+ checkFlag
+ "TSO_STOP_NEXT_BREAKPOINT"
+ rts_enableStopNextBreakpoint
+ rts_disableStopNextBreakpoint
+ c_hasLocalStopNextBreakpoint
+ checkFlag
+ "TSO_STOP_AFTER_RETURN"
+ rts_enableStopAfterReturn
+ rts_disableStopAfterReturn
+ c_hasLocalStopAfterReturn
+
+checkFlag
+ :: String
+ -> (ThreadId# -> IO ())
+ -> (ThreadId# -> IO ())
+ -> IO CInt
+ -> IO ()
+checkFlag label enable disable isMyThreadFlagSet = do
+ -- Print the main thread's capability (should be 0)
+ print =<< threadCapability =<< myThreadId
+
+ -- Target thread will write its own flag value here
+ targetCheckVar <- newEmptyMVar
+
+ -- Run the new TSO runs on capability 1
+ ThreadId tid# <- forkOn 1 $ do
+ replicateM_ 2 $ do
+ replyVar <- takeMVar targetCheckVar
+ isSet <- (/= 0) <$> isMyThreadFlagSet
+ putMVar replyVar isSet
+
+ -- Enable the other TSO's flag
+ enable tid#
+ -- It will check whether it is set and reply here
+ renderCheck label "set" =<< checkTarget targetCheckVar
+
+ -- Ditto.
+ disable tid#
+ renderCheck label "unset" . not =<< checkTarget targetCheckVar
+
+checkTarget :: MVar (MVar Bool) -> IO Bool
+checkTarget targetCheckVar = do
+ replyVar <- newEmptyMVar
+ putMVar targetCheckVar replyVar
+ takeMVar replyVar
+
+renderCheck :: String -> String -> Bool -> IO ()
+renderCheck label state ok = putStrLn $
+ label ++ " " ++ state ++ ": " ++ if ok then "ok" else "failed"
=====================================
testsuite/tests/rts/T27131.stdout
=====================================
@@ -0,0 +1,6 @@
+(0,False)
+TSO_STOP_NEXT_BREAKPOINT set: ok
+TSO_STOP_NEXT_BREAKPOINT unset: ok
+(0,False)
+TSO_STOP_AFTER_RETURN set: ok
+TSO_STOP_AFTER_RETURN unset: ok
=====================================
testsuite/tests/rts/T27131_c.c
=====================================
@@ -0,0 +1,15 @@
+#include "Rts.h"
+
+int has_local_stop_next_breakpoint(void)
+{
+ CapabilityPublic *cap = (CapabilityPublic *) rts_unsafeGetMyCapability();
+ StgTSO *tso = cap->r.rCurrentTSO;
+ return (tso->flags & TSO_STOP_NEXT_BREAKPOINT) != 0;
+}
+
+int has_local_stop_after_return(void)
+{
+ CapabilityPublic *cap = (CapabilityPublic *) rts_unsafeGetMyCapability();
+ StgTSO *tso = cap->r.rCurrentTSO;
+ return (tso->flags & TSO_STOP_AFTER_RETURN) != 0;
+}
=====================================
testsuite/tests/rts/all.T
=====================================
@@ -623,6 +623,13 @@ test('T20201b', [js_skip, exit_code(1)], compile_and_run, ['-with-rtsopts -A64z'
test('T22012', [js_skip, extra_ways(['ghci'])], compile_and_run, ['T22012_c.c'])
+test('T27131',
+ [ only_ways(['threaded1', 'threaded2'])
+ , req_ghc_with_threaded_rts
+ , req_target_smp
+ ],
+ compile_and_run, ['T27131_c.c'])
+
# Skip for JS platform as the JS RTS is always single threaded
test('T22795a', [only_ways(['normal']), js_skip, req_ghc_with_threaded_rts], compile_and_run, ['-threaded'])
test('T22795b', [only_ways(['normal']), js_skip], compile_and_run, ['-single-threaded'])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d59b7c7109e4d8ef9035ec4b9d9f16…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d59b7c7109e4d8ef9035ec4b9d9f16…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] Move code that uses `GHC.Internal.Text.Read` into `base`
by Marge Bot (@marge-bot) 30 Apr '26
by Marge Bot (@marge-bot) 30 Apr '26
30 Apr '26
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
d59b7c71 by Wolfgang Jeltsch at 2026-04-30T04:53:25-04:00
Move code that uses `GHC.Internal.Text.Read` into `base`
This contribution serves to remove all dependencies on
`GHC.Internal.Text.Read` from within `ghc-internal`, so that the
implementation of `Text.Read` and ultimately more reading-related code
can be moved to `base` as well.
The following things are moved from `ghc-internal` to `base`:
* I/O-related `Read` instances
* Most of the `Numeric` implementation
* The instance `Read ByteOrder`
* The `parseVersion` operation
* The `readConstr` operation
Metric Increase:
LinkableUsage01
T9198
T12425
T13035
T13820
T18140
- - - - -
21 changed files:
- libraries/base/src/Data/Data.hs
- libraries/base/src/Data/Version.hs
- libraries/base/src/GHC/ByteOrder.hs
- libraries/base/src/Numeric.hs
- libraries/base/src/System/IO.hs
- libraries/base/src/Text/Printf.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
- libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Device.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
- libraries/ghc-internal/src/GHC/Internal/IO/IOMode.hs
- libraries/ghc-internal/src/GHC/Internal/Numeric.hs
- libraries/ghc-internal/src/GHC/Internal/Read.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/plugins/plugins09.stdout
- testsuite/tests/plugins/plugins10.stdout
- testsuite/tests/plugins/plugins11.stdout
- testsuite/tests/plugins/static-plugins.stdout
Changes:
=====================================
libraries/base/src/Data/Data.hs
=====================================
@@ -99,3 +99,38 @@ module Data.Data (
import GHC.Internal.Data.Data
import Data.Typeable
+
+import GHC.Real (toRational)
+import GHC.Float (Double)
+import Data.Eq ((==))
+import Data.Function ((.))
+import Data.Maybe (Maybe (Nothing, Just))
+import Data.List (filter)
+import Data.String (String)
+import Text.Read (Read, reads)
+
+-- | Lookup a constructor via a string
+readConstr :: DataType -> String -> Maybe Constr
+readConstr dt str =
+ case dataTypeRep dt of
+ AlgRep cons -> idx cons
+ IntRep -> mkReadCon (\i -> (mkPrimCon dt str (IntConstr i)))
+ FloatRep -> mkReadCon ffloat
+ CharRep -> mkReadCon (\c -> (mkPrimCon dt str (CharConstr c)))
+ NoRep -> Nothing
+ where
+
+ -- Read a value and build a constructor
+ mkReadCon :: Read t => (t -> Constr) -> Maybe Constr
+ mkReadCon f = case (reads str) of
+ [(t,"")] -> Just (f t)
+ _ -> Nothing
+
+ -- Traverse list of algebraic datatype constructors
+ idx :: [Constr] -> Maybe Constr
+ idx cons = case filter ((==) str . showConstr) cons of
+ [] -> Nothing
+ hd : _ -> Just hd
+
+ ffloat :: Double -> Constr
+ ffloat = mkPrimCon dt str . FloatConstr . toRational
=====================================
libraries/base/src/Data/Version.hs
=====================================
@@ -1,5 +1,9 @@
{-# LANGUAGE Safe #-}
+{-# LANGUAGE StandaloneDeriving #-}
+
+{-# OPTIONS_GHC -Wno-orphans #-}
+
-- |
-- Module : Data.Version
-- Copyright : (c) The University of Glasgow 2004
@@ -33,3 +37,25 @@ module Data.Version (
) where
import GHC.Internal.Data.Version
+
+import Control.Applicative (pure, (*>))
+import Data.Functor (fmap)
+import Data.Char (isDigit, isAlphaNum)
+import Text.ParserCombinators.ReadP (ReadP, char, munch1, sepBy1, many)
+import Text.Read (Read, read)
+
+{-NOTE:
+ The following instance is technically an orphan, but practically it is not,
+ since ordinary users should not use @ghc-internal@ directly and thus get
+ 'Version' only through this module.
+-}
+
+-- | @since base-2.01
+deriving instance Read Version
+
+-- | A parser for versions in the format produced by 'showVersion'.
+--
+parseVersion :: ReadP Version
+parseVersion = do branch <- sepBy1 (fmap read (munch1 isDigit)) (char '.')
+ tags <- many (char '-' *> munch1 isAlphaNum)
+ pure (Version branch tags)
=====================================
libraries/base/src/GHC/ByteOrder.hs
=====================================
@@ -1,5 +1,9 @@
{-# LANGUAGE Safe #-}
+{-# LANGUAGE StandaloneDeriving #-}
+
+{-# OPTIONS_GHC -Wno-orphans #-}
+
-- |
--
-- Module : GHC.ByteOrder
@@ -19,4 +23,15 @@ module GHC.ByteOrder
targetByteOrder
) where
-import GHC.Internal.ByteOrder
\ No newline at end of file
+import GHC.Internal.ByteOrder
+
+import Text.Read
+
+{-NOTE:
+ The following instance is technically an orphan, but practically it is not,
+ since ordinary users should not use @ghc-internal@ directly and thus get
+ 'ByteOrder' only through this module.
+-}
+
+-- | @since base-4.11.0.0
+deriving instance Read ByteOrder
=====================================
libraries/base/src/Numeric.hs
=====================================
@@ -1,4 +1,6 @@
-{-# LANGUAGE Safe #-}
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE ImportQualifiedPost #-}
-- |
--
@@ -48,3 +50,279 @@ module Numeric
) where
import GHC.Internal.Numeric
+
+import GHC.Types (Char (C#))
+import GHC.Err (error, errorWithoutStackTrace)
+import GHC.Base (unsafeChr)
+import GHC.Num (Num, (+), (-), (*))
+import GHC.Real
+ (
+ Integral,
+ Real,
+ RealFrac,
+ fromIntegral,
+ fromRational,
+ quotRem,
+ showSigned
+ )
+import GHC.Float
+ (
+ Floating (..),
+ RealFloat,
+ Float,
+ Double,
+ isNegativeZero,
+ isInfinite,
+ isNaN,
+ fromRat,
+ floatToDigits,
+ FFFormat (FFExponent, FFFixed, FFGeneric),
+ formatRealFloat,
+ formatRealFloatAlt,
+ showFloat
+ )
+import GHC.Read (lexDigits)
+import Control.Monad (return)
+import Data.Eq (Eq, (==))
+import Data.Ord ((<))
+import Data.Function (($), (.))
+import Data.Bool (Bool (False, True), otherwise, (||), (&&))
+import Data.Maybe (Maybe)
+import Data.List ((++))
+import Data.Char (ord, intToDigit)
+import Data.Int (Int)
+import Text.ParserCombinators.ReadP (ReadP, pfail, readP_to_S)
+import Text.Read (ReadS, readParen, lex)
+import Text.Read.Lex qualified as L
+ (
+ Lexeme (Number),
+ lex,
+ numberToRational,
+ readIntP,
+ readBinP,
+ readOctP,
+ readDecP,
+ readHexP
+ )
+import Text.Show (ShowS, show, showString)
+
+-- $setup
+-- >>> import Prelude
+
+-- -----------------------------------------------------------------------------
+-- Reading
+
+-- | Reads an /unsigned/ integral value in an arbitrary base.
+readInt :: Num a
+ => a -- ^ the base
+ -> (Char -> Bool) -- ^ a predicate distinguishing valid digits in this base
+ -> (Char -> Int) -- ^ a function converting a valid digit character to an 'Int'
+ -> ReadS a
+readInt base isDigit valDigit = readP_to_S (L.readIntP base isDigit valDigit)
+
+-- | Read an unsigned number in binary notation.
+--
+-- >>> readBin "10011"
+-- [(19,"")]
+readBin :: (Eq a, Num a) => ReadS a
+readBin = readP_to_S L.readBinP
+
+-- | Read an unsigned number in octal notation.
+--
+-- >>> readOct "0644"
+-- [(420,"")]
+readOct :: (Eq a, Num a) => ReadS a
+readOct = readP_to_S L.readOctP
+
+-- | Read an unsigned number in decimal notation.
+--
+-- >>> readDec "0644"
+-- [(644,"")]
+readDec :: (Eq a, Num a) => ReadS a
+readDec = readP_to_S L.readDecP
+
+-- | Read an unsigned number in hexadecimal notation.
+-- Both upper or lower case letters are allowed.
+--
+-- >>> readHex "deadbeef"
+-- [(3735928559,"")]
+readHex :: (Eq a, Num a) => ReadS a
+readHex = readP_to_S L.readHexP
+
+-- | Reads an /unsigned/ 'RealFrac' value,
+-- expressed in decimal scientific notation.
+--
+-- Note that this function takes time linear in the magnitude of its input
+-- which can scale exponentially with input size (e.g. @"1e100000000"@ is a
+-- very large number while having a very small textual form).
+-- For this reason, users should take care to avoid using this function on
+-- untrusted input. Users needing to parse floating point values
+-- (e.g. 'Float') are encouraged to instead use 'read', which does
+-- not suffer from this issue.
+readFloat :: RealFrac a => ReadS a
+readFloat = readP_to_S readFloatP
+
+readFloatP :: RealFrac a => ReadP a
+readFloatP =
+ do tok <- L.lex
+ case tok of
+ L.Number n -> return $ fromRational $ L.numberToRational n
+ _ -> pfail
+
+-- It's turgid to have readSigned work using list comprehensions,
+-- but it's specified as a ReadS to ReadS transformer
+-- With a bit of luck no one will use it.
+
+-- | Reads a /signed/ 'Real' value, given a reader for an unsigned value.
+readSigned :: (Real a) => ReadS a -> ReadS a
+readSigned readPos = readParen False read'
+ where read' r = read'' r ++
+ (do
+ ("-",s) <- lex r
+ (x,t) <- read'' s
+ return (-x,t))
+ read'' r = do
+ (str,s) <- lex r
+ (n,"") <- readPos str
+ return (n,s)
+
+-- -----------------------------------------------------------------------------
+-- Showing
+
+-- | Show /non-negative/ 'Integral' numbers in base 10.
+showInt :: Integral a => a -> ShowS
+showInt n0 cs0
+ | n0 < 0 = errorWithoutStackTrace "GHC.Internal.Numeric.showInt: can't show negative numbers"
+ | otherwise = go n0 cs0
+ where
+ go n cs
+ | n < 10 = case unsafeChr (ord '0' + fromIntegral n) of
+ c@(C# _) -> c:cs
+ | otherwise = case unsafeChr (ord '0' + fromIntegral r) of
+ c@(C# _) -> go q (c:cs)
+ where
+ (q,r) = n `quotRem` 10
+
+-- Controlling the format and precision of floats. The code that
+-- implements the formatting itself is in @PrelNum@ to avoid
+-- mutual module deps.
+
+{-# SPECIALIZE showEFloat ::
+ Maybe Int -> Float -> ShowS #-}
+{-# SPECIALIZE showEFloat ::
+ Maybe Int -> Double -> ShowS #-}
+{-# SPECIALIZE showFFloat ::
+ Maybe Int -> Float -> ShowS #-}
+{-# SPECIALIZE showFFloat ::
+ Maybe Int -> Double -> ShowS #-}
+{-# SPECIALIZE showGFloat ::
+ Maybe Int -> Float -> ShowS #-}
+{-# SPECIALIZE showGFloat ::
+ Maybe Int -> Double -> ShowS #-}
+
+-- | Show a signed 'RealFloat' value
+-- using scientific (exponential) notation (e.g. @2.45e2@, @1.5e-3@).
+--
+-- In the call @'showEFloat' digs val@, if @digs@ is 'Nothing',
+-- the value is shown to full precision; if @digs@ is @'Just' d@,
+-- then at most @d@ digits after the decimal point are shown.
+showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
+
+-- | Show a signed 'RealFloat' value
+-- using standard decimal notation (e.g. @245000@, @0.0015@).
+--
+-- In the call @'showFFloat' digs val@, if @digs@ is 'Nothing',
+-- the value is shown to full precision; if @digs@ is @'Just' d@,
+-- then at most @d@ digits after the decimal point are shown.
+showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
+
+-- | Show a signed 'RealFloat' value
+-- using standard decimal notation for arguments whose absolute value lies
+-- between @0.1@ and @9,999,999@, and scientific notation otherwise.
+--
+-- In the call @'showGFloat' digs val@, if @digs@ is 'Nothing',
+-- the value is shown to full precision; if @digs@ is @'Just' d@,
+-- then at most @d@ digits after the decimal point are shown.
+showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
+
+showEFloat d x = showString (formatRealFloat FFExponent d x)
+showFFloat d x = showString (formatRealFloat FFFixed d x)
+showGFloat d x = showString (formatRealFloat FFGeneric d x)
+
+-- | Show a signed 'RealFloat' value
+-- using standard decimal notation (e.g. @245000@, @0.0015@).
+--
+-- This behaves as 'showFFloat', except that a decimal point
+-- is always guaranteed, even if not needed.
+--
+-- @since base-4.7.0.0
+showFFloatAlt :: (RealFloat a) => Maybe Int -> a -> ShowS
+
+-- | Show a signed 'RealFloat' value
+-- using standard decimal notation for arguments whose absolute value lies
+-- between @0.1@ and @9,999,999@, and scientific notation otherwise.
+--
+-- This behaves as 'showFFloat', except that a decimal point
+-- is always guaranteed, even if not needed.
+--
+-- @since base-4.7.0.0
+showGFloatAlt :: (RealFloat a) => Maybe Int -> a -> ShowS
+
+showFFloatAlt d x = showString (formatRealFloatAlt FFFixed d True x)
+showGFloatAlt d x = showString (formatRealFloatAlt FFGeneric d True x)
+
+{- | Show a floating-point value in the hexadecimal format,
+similar to the @%a@ specifier in C's printf.
+
+ >>> showHFloat (212.21 :: Double) ""
+ "0x1.a86b851eb851fp7"
+ >>> showHFloat (-12.76 :: Float) ""
+ "-0x1.9851ecp3"
+ >>> showHFloat (-0 :: Double) ""
+ "-0x0p+0"
+
+@since base-4.11.0.0
+-}
+showHFloat :: RealFloat a => a -> ShowS
+showHFloat = showString . fmt
+ where
+ fmt x
+ | isNaN x = "NaN"
+ | isInfinite x = (if x < 0 then "-" else "") ++ "Infinity"
+ | x < 0 || isNegativeZero x = '-' : cvt (-x)
+ | otherwise = cvt x
+
+ cvt x
+ | x == 0 = "0x0p+0"
+ | otherwise =
+ case floatToDigits 2 x of
+ r@([], _) -> error $ "Impossible happened: showHFloat: " ++ show r
+ (d:ds, e) -> "0x" ++ show d ++ frac ds ++ "p" ++ show (e-1)
+
+ -- Given binary digits, convert them to hex in blocks of 4
+ -- Special case: If all 0's, just drop it.
+ frac digits
+ | allZ digits = ""
+ | otherwise = "." ++ hex digits
+ where
+ hex ds =
+ case ds of
+ [] -> ""
+ [a] -> hexDigit a 0 0 0 ""
+ [a,b] -> hexDigit a b 0 0 ""
+ [a,b,c] -> hexDigit a b c 0 ""
+ a : b : c : d : r -> hexDigit a b c d (hex r)
+
+ hexDigit a b c d = showHex (8*a + 4*b + 2*c + d)
+
+ allZ xs = case xs of
+ x : more -> x == 0 && allZ more
+ [] -> True
+
+-- | Show /non-negative/ 'Integral' numbers in base 8.
+showOct :: Integral a => a -> ShowS
+showOct = showIntAtBase 8 intToDigit
+
+-- | Show /non-negative/ 'Integral' numbers in base 2.
+showBin :: Integral a => a -> ShowS
+showBin = showIntAtBase 2 intToDigit
=====================================
libraries/base/src/System/IO.hs
=====================================
@@ -1,5 +1,8 @@
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE CPP #-}
+{-# LANGUAGE StandaloneDeriving #-}
+
+{-# OPTIONS_GHC -Wno-orphans #-}
-- |
--
@@ -895,3 +898,24 @@ rw_flags = output_flags .|. o_RDWR
-- output
-- > input^D
-- output
+
+{-NOTE:
+ The following instances are technically orphans, but practically they are
+ not, since ordinary users should not use @ghc-internal@ directly and thus
+ get the instantiated types only through this module.
+-}
+
+-- | @since base-4.2.0.0
+deriving instance Read IOMode
+
+-- | @since base-4.2.0.0
+deriving instance Read BufferMode
+
+-- | @since base-4.2.0.0
+deriving instance Read SeekMode
+
+-- | @since base-4.3.0.0
+deriving instance Read Newline
+
+-- | @since base-4.3.0.0
+deriving instance Read NewlineMode
=====================================
libraries/base/src/Text/Printf.hs
=====================================
@@ -97,8 +97,8 @@ import Data.Char
import GHC.Internal.Int
import GHC.Internal.Data.List (stripPrefix)
import GHC.Internal.Word
-import GHC.Internal.Numeric
import GHC.Internal.Numeric.Natural
+import Numeric
import System.IO
-- $setup
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Data.hs
=====================================
@@ -61,6 +61,7 @@ module GHC.Internal.Data.Data (
mkIntType,
mkFloatType,
mkCharType,
+ mkPrimCon,
mkNoRepType,
-- ** Observers
dataTypeName,
@@ -94,7 +95,6 @@ module GHC.Internal.Data.Data (
constrIndex,
-- ** From strings to constructors and vice versa: all data types
showConstr,
- readConstr,
-- * Convenience functions: take type constructors apart
tyconUQname,
@@ -126,10 +126,8 @@ import GHC.Internal.Base (
import GHC.Internal.Err (errorWithoutStackTrace)
import GHC.Internal.List
import GHC.Internal.Num
-import GHC.Internal.Read
import GHC.Internal.Show
import GHC.Internal.Tuple (Solo (..))
-import GHC.Internal.Text.Read( reads )
import GHC.Internal.Types (
Bool(..), Char, Coercible, Float, Double, Type, type (~), type (~~),
)
@@ -688,32 +686,6 @@ showConstr :: Constr -> String
showConstr = constring
--- | Lookup a constructor via a string
-readConstr :: DataType -> String -> Maybe Constr
-readConstr dt str =
- case dataTypeRep dt of
- AlgRep cons -> idx cons
- IntRep -> mkReadCon (\i -> (mkPrimCon dt str (IntConstr i)))
- FloatRep -> mkReadCon ffloat
- CharRep -> mkReadCon (\c -> (mkPrimCon dt str (CharConstr c)))
- NoRep -> Nothing
- where
-
- -- Read a value and build a constructor
- mkReadCon :: Read t => (t -> Constr) -> Maybe Constr
- mkReadCon f = case (reads str) of
- [(t,"")] -> Just (f t)
- _ -> Nothing
-
- -- Traverse list of algebraic datatype constructors
- idx :: [Constr] -> Maybe Constr
- idx cons = case filter ((==) str . showConstr) cons of
- [] -> Nothing
- hd : _ -> Just hd
-
- ffloat :: Double -> Constr
- ffloat = mkPrimCon dt str . FloatConstr . toRational
-
------------------------------------------------------------------------------
--
-- Convenience functions: algebraic data types
=====================================
libraries/ghc-internal/src/GHC/Internal/Data/Version.hs
=====================================
@@ -10,7 +10,7 @@
--
-- Maintainer : libraries(a)haskell.org
-- Stability : stable
--- Portability : non-portable (local universal quantification in ReadP)
+-- Portability : non-portable
--
-- A general library for representation and manipulation of versions.
--
@@ -31,23 +31,17 @@ module GHC.Internal.Data.Version (
-- * The @Version@ type
Version(..),
-- * A concrete representation of @Version@
- showVersion, parseVersion,
+ showVersion,
-- * Constructor function
makeVersion
) where
-import GHC.Internal.Classes ( Eq(..), (&&) )
-import GHC.Internal.Data.Functor ( Functor(..) )
+import GHC.Internal.Classes ( Eq ((==)), (&&) )
import GHC.Internal.Int ( Int )
import GHC.Internal.Data.List ( map, sort, concat, concatMap, intersperse, (++) )
import GHC.Internal.Data.Ord
import GHC.Internal.Data.String ( String )
-import GHC.Internal.Base ( Applicative(..) )
-import GHC.Internal.Unicode ( isDigit, isAlphaNum )
-import GHC.Internal.Read
import GHC.Internal.Show
-import GHC.Internal.Text.ParserCombinators.ReadP
-import GHC.Internal.Text.Read ( read )
{- |
A 'Version' represents the version of a software entity.
@@ -69,8 +63,8 @@ operations are the right thing for every 'Version'.
Similarly, concrete representations of versions may differ. One
possible concrete representation is provided (see 'showVersion' and
-'parseVersion'), but depending on the application a different concrete
-representation may be more appropriate.
+'Data.Version.parseVersion'), but depending on the application a
+different concrete representation may be more appropriate.
-}
data Version =
Version { versionBranch :: [Int],
@@ -92,8 +86,7 @@ data Version =
-- The interpretation of the list of tags is entirely dependent
-- on the entity that this version applies to.
}
- deriving ( Read -- ^ @since base-2.01
- , Show -- ^ @since base-2.01
+ deriving ( Show -- ^ @since base-2.01
)
{-# DEPRECATED versionTags "See GHC ticket #2496" #-}
-- TODO. Remove all references to versionTags in GHC 8.0 release.
@@ -120,13 +113,6 @@ showVersion (Version branch tags)
= concat (intersperse "." (map show branch)) ++
concatMap ('-':) tags
--- | A parser for versions in the format produced by 'showVersion'.
---
-parseVersion :: ReadP Version
-parseVersion = do branch <- sepBy1 (fmap read (munch1 isDigit)) (char '.')
- tags <- many (char '-' *> munch1 isAlphaNum)
- pure Version{versionBranch=branch, versionTags=tags}
-
-- | Construct tag-less 'Version'
--
-- @since base-4.8.0.0
=====================================
libraries/ghc-internal/src/GHC/Internal/IO/Device.hs
=====================================
@@ -34,7 +34,6 @@ import GHC.Internal.Types ( Bool(..), Int )
import GHC.Internal.Word
import GHC.Internal.Arr
import GHC.Internal.Enum
-import GHC.Internal.Read
import GHC.Internal.Show
import GHC.Internal.Ptr
import GHC.Internal.Num
@@ -182,7 +181,6 @@ data SeekMode
, Ord -- ^ @since base-4.2.0.0
, Ix -- ^ @since base-4.2.0.0
, Enum -- ^ @since base-4.2.0.0
- , Read -- ^ @since base-4.2.0.0
, Show -- ^ @since base-4.2.0.0
)
=====================================
libraries/ghc-internal/src/GHC/Internal/IO/Handle/Types.hs
=====================================
@@ -50,7 +50,6 @@ import GHC.Internal.IO.BufferedIO
import GHC.Internal.IO.Encoding.Types
import GHC.Internal.IORef
import GHC.Internal.Show
-import GHC.Internal.Read
import GHC.Internal.Types (Bool(..), Int)
import GHC.Internal.Word
import GHC.Internal.IO.Device
@@ -273,7 +272,6 @@ data BufferMode
-- is 'Just' @n@ and is otherwise implementation-dependent.
deriving ( Eq -- ^ @since base-4.2.0.0
, Ord -- ^ @since base-4.2.0.0
- , Read -- ^ @since base-4.2.0.0
, Show -- ^ @since base-4.2.0.0
)
@@ -379,7 +377,6 @@ data Newline = LF -- ^ @\'\\n\'@
| CRLF -- ^ @\'\\r\\n\'@
deriving ( Eq -- ^ @since base-4.2.0.0
, Ord -- ^ @since base-4.3.0.0
- , Read -- ^ @since base-4.3.0.0
, Show -- ^ @since base-4.3.0.0
)
@@ -396,7 +393,6 @@ data NewlineMode
}
deriving ( Eq -- ^ @since base-4.2.0.0
, Ord -- ^ @since base-4.3.0.0
- , Read -- ^ @since base-4.3.0.0
, Show -- ^ @since base-4.3.0.0
)
=====================================
libraries/ghc-internal/src/GHC/Internal/IO/IOMode.hs
=====================================
@@ -20,7 +20,6 @@ module GHC.Internal.IO.IOMode (IOMode(..)) where
import GHC.Internal.Classes (Eq, Ord)
import GHC.Internal.Show
-import GHC.Internal.Read
import GHC.Internal.Arr
import GHC.Internal.Enum
@@ -30,7 +29,6 @@ data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
, Ord -- ^ @since base-4.2.0.0
, Ix -- ^ @since base-4.2.0.0
, Enum -- ^ @since base-4.2.0.0
- , Read -- ^ @since base-4.2.0.0
, Show -- ^ @since base-4.2.0.0
)
=====================================
libraries/ghc-internal/src/GHC/Internal/Numeric.hs
=====================================
@@ -1,5 +1,4 @@
{-# LANGUAGE Trustworthy #-}
-{-# LANGUAGE NoImplicitPrelude, MagicHash #-}
-----------------------------------------------------------------------------
-- |
@@ -16,279 +15,16 @@
--
-----------------------------------------------------------------------------
-module GHC.Internal.Numeric (
+module GHC.Internal.Numeric (showIntAtBase, showHex) where
- -- * Showing
-
- showSigned,
-
- showIntAtBase,
- showInt,
- showBin,
- showHex,
- showOct,
-
- showEFloat,
- showFFloat,
- showGFloat,
- showFFloatAlt,
- showGFloatAlt,
- showFloat,
- showHFloat,
-
- floatToDigits,
-
- -- * Reading
-
- -- | /NB:/ 'readInt' is the \'dual\' of 'showIntAtBase',
- -- and 'readDec' is the \`dual\' of 'showInt'.
- -- The inconsistent naming is a historical accident.
-
- readSigned,
-
- readInt,
- readBin,
- readDec,
- readOct,
- readHex,
-
- readFloat,
-
- lexDigits,
-
- -- * Miscellaneous
-
- fromRat,
- Floating(..)
-
- ) where
-
-import GHC.Internal.Base (ord, otherwise, return, unsafeChr, ($), (.), (++))
-import GHC.Internal.Classes (Eq(..), Ord(..), (&&), (||))
-import GHC.Internal.Err (error, errorWithoutStackTrace)
-import GHC.Internal.Maybe (Maybe(..))
import GHC.Internal.Prim (seq)
-import GHC.Internal.Read
-import GHC.Internal.Real
-import GHC.Internal.Float
-import GHC.Internal.Num
-import GHC.Internal.Show
-import GHC.Internal.Text.ParserCombinators.ReadP( ReadP, readP_to_S, pfail )
-import qualified GHC.Internal.Text.Read.Lex as L
-import GHC.Internal.Types (Bool(..), Char(..), Int)
-
--- $setup
--- >>> import Prelude
-
--- -----------------------------------------------------------------------------
--- Reading
-
--- | Reads an /unsigned/ integral value in an arbitrary base.
-readInt :: Num a
- => a -- ^ the base
- -> (Char -> Bool) -- ^ a predicate distinguishing valid digits in this base
- -> (Char -> Int) -- ^ a function converting a valid digit character to an 'Int'
- -> ReadS a
-readInt base isDigit valDigit = readP_to_S (L.readIntP base isDigit valDigit)
-
--- | Read an unsigned number in binary notation.
---
--- >>> readBin "10011"
--- [(19,"")]
-readBin :: (Eq a, Num a) => ReadS a
-readBin = readP_to_S L.readBinP
-
--- | Read an unsigned number in octal notation.
---
--- >>> readOct "0644"
--- [(420,"")]
-readOct :: (Eq a, Num a) => ReadS a
-readOct = readP_to_S L.readOctP
-
--- | Read an unsigned number in decimal notation.
---
--- >>> readDec "0644"
--- [(644,"")]
-readDec :: (Eq a, Num a) => ReadS a
-readDec = readP_to_S L.readDecP
-
--- | Read an unsigned number in hexadecimal notation.
--- Both upper or lower case letters are allowed.
---
--- >>> readHex "deadbeef"
--- [(3735928559,"")]
-readHex :: (Eq a, Num a) => ReadS a
-readHex = readP_to_S L.readHexP
-
--- | Reads an /unsigned/ 'RealFrac' value,
--- expressed in decimal scientific notation.
---
--- Note that this function takes time linear in the magnitude of its input
--- which can scale exponentially with input size (e.g. @"1e100000000"@ is a
--- very large number while having a very small textual form).
--- For this reason, users should take care to avoid using this function on
--- untrusted input. Users needing to parse floating point values
--- (e.g. 'Float') are encouraged to instead use 'read', which does
--- not suffer from this issue.
-readFloat :: RealFrac a => ReadS a
-readFloat = readP_to_S readFloatP
-
-readFloatP :: RealFrac a => ReadP a
-readFloatP =
- do tok <- L.lex
- case tok of
- L.Number n -> return $ fromRational $ L.numberToRational n
- _ -> pfail
-
--- It's turgid to have readSigned work using list comprehensions,
--- but it's specified as a ReadS to ReadS transformer
--- With a bit of luck no one will use it.
-
--- | Reads a /signed/ 'Real' value, given a reader for an unsigned value.
-readSigned :: (Real a) => ReadS a -> ReadS a
-readSigned readPos = readParen False read'
- where read' r = read'' r ++
- (do
- ("-",s) <- lex r
- (x,t) <- read'' s
- return (-x,t))
- read'' r = do
- (str,s) <- lex r
- (n,"") <- readPos str
- return (n,s)
-
--- -----------------------------------------------------------------------------
--- Showing
-
--- | Show /non-negative/ 'Integral' numbers in base 10.
-showInt :: Integral a => a -> ShowS
-showInt n0 cs0
- | n0 < 0 = errorWithoutStackTrace "GHC.Internal.Numeric.showInt: can't show negative numbers"
- | otherwise = go n0 cs0
- where
- go n cs
- | n < 10 = case unsafeChr (ord '0' + fromIntegral n) of
- c@(C# _) -> c:cs
- | otherwise = case unsafeChr (ord '0' + fromIntegral r) of
- c@(C# _) -> go q (c:cs)
- where
- (q,r) = n `quotRem` 10
-
--- Controlling the format and precision of floats. The code that
--- implements the formatting itself is in @PrelNum@ to avoid
--- mutual module deps.
-
-{-# SPECIALIZE showEFloat ::
- Maybe Int -> Float -> ShowS #-}
-{-# SPECIALIZE showEFloat ::
- Maybe Int -> Double -> ShowS #-}
-{-# SPECIALIZE showFFloat ::
- Maybe Int -> Float -> ShowS #-}
-{-# SPECIALIZE showFFloat ::
- Maybe Int -> Double -> ShowS #-}
-{-# SPECIALIZE showGFloat ::
- Maybe Int -> Float -> ShowS #-}
-{-# SPECIALIZE showGFloat ::
- Maybe Int -> Double -> ShowS #-}
-
--- | Show a signed 'RealFloat' value
--- using scientific (exponential) notation (e.g. @2.45e2@, @1.5e-3@).
---
--- In the call @'showEFloat' digs val@, if @digs@ is 'Nothing',
--- the value is shown to full precision; if @digs@ is @'Just' d@,
--- then at most @d@ digits after the decimal point are shown.
-showEFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
-
--- | Show a signed 'RealFloat' value
--- using standard decimal notation (e.g. @245000@, @0.0015@).
---
--- In the call @'showFFloat' digs val@, if @digs@ is 'Nothing',
--- the value is shown to full precision; if @digs@ is @'Just' d@,
--- then at most @d@ digits after the decimal point are shown.
-showFFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
-
--- | Show a signed 'RealFloat' value
--- using standard decimal notation for arguments whose absolute value lies
--- between @0.1@ and @9,999,999@, and scientific notation otherwise.
---
--- In the call @'showGFloat' digs val@, if @digs@ is 'Nothing',
--- the value is shown to full precision; if @digs@ is @'Just' d@,
--- then at most @d@ digits after the decimal point are shown.
-showGFloat :: (RealFloat a) => Maybe Int -> a -> ShowS
-
-showEFloat d x = showString (formatRealFloat FFExponent d x)
-showFFloat d x = showString (formatRealFloat FFFixed d x)
-showGFloat d x = showString (formatRealFloat FFGeneric d x)
-
--- | Show a signed 'RealFloat' value
--- using standard decimal notation (e.g. @245000@, @0.0015@).
---
--- This behaves as 'showFFloat', except that a decimal point
--- is always guaranteed, even if not needed.
---
--- @since base-4.7.0.0
-showFFloatAlt :: (RealFloat a) => Maybe Int -> a -> ShowS
-
--- | Show a signed 'RealFloat' value
--- using standard decimal notation for arguments whose absolute value lies
--- between @0.1@ and @9,999,999@, and scientific notation otherwise.
---
--- This behaves as 'showFFloat', except that a decimal point
--- is always guaranteed, even if not needed.
---
--- @since base-4.7.0.0
-showGFloatAlt :: (RealFloat a) => Maybe Int -> a -> ShowS
-
-showFFloatAlt d x = showString (formatRealFloatAlt FFFixed d True x)
-showGFloatAlt d x = showString (formatRealFloatAlt FFGeneric d True x)
-
-{- | Show a floating-point value in the hexadecimal format,
-similar to the @%a@ specifier in C's printf.
-
- >>> showHFloat (212.21 :: Double) ""
- "0x1.a86b851eb851fp7"
- >>> showHFloat (-12.76 :: Float) ""
- "-0x1.9851ecp3"
- >>> showHFloat (-0 :: Double) ""
- "-0x0p+0"
-
-@since base-4.11.0.0
--}
-showHFloat :: RealFloat a => a -> ShowS
-showHFloat = showString . fmt
- where
- fmt x
- | isNaN x = "NaN"
- | isInfinite x = (if x < 0 then "-" else "") ++ "Infinity"
- | x < 0 || isNegativeZero x = '-' : cvt (-x)
- | otherwise = cvt x
-
- cvt x
- | x == 0 = "0x0p+0"
- | otherwise =
- case floatToDigits 2 x of
- r@([], _) -> error $ "Impossible happened: showHFloat: " ++ show r
- (d:ds, e) -> "0x" ++ show d ++ frac ds ++ "p" ++ show (e-1)
-
- -- Given binary digits, convert them to hex in blocks of 4
- -- Special case: If all 0's, just drop it.
- frac digits
- | allZ digits = ""
- | otherwise = "." ++ hex digits
- where
- hex ds =
- case ds of
- [] -> ""
- [a] -> hexDigit a 0 0 0 ""
- [a,b] -> hexDigit a b 0 0 ""
- [a,b,c] -> hexDigit a b c 0 ""
- a : b : c : d : r -> hexDigit a b c d (hex r)
-
- hexDigit a b c d = showHex (8*a + 4*b + 2*c + d)
-
- allZ xs = case xs of
- x : more -> x == 0 && allZ more
- [] -> True
+import GHC.Internal.Types (Char, Int)
+import GHC.Internal.Classes ((<), (<=))
+import GHC.Internal.Err (errorWithoutStackTrace)
+import GHC.Internal.Base (($), otherwise)
+import GHC.Internal.List ((++))
+import GHC.Internal.Real (Integral, toInteger, fromIntegral, quotRem)
+import GHC.Internal.Show (ShowS, show, intToDigit)
-- ---------------------------------------------------------------------------
-- Integer printing functions
@@ -312,11 +48,3 @@ showIntAtBase base toChr n0 r0
-- | Show /non-negative/ 'Integral' numbers in base 16.
showHex :: Integral a => a -> ShowS
showHex = showIntAtBase 16 intToDigit
-
--- | Show /non-negative/ 'Integral' numbers in base 8.
-showOct :: Integral a => a -> ShowS
-showOct = showIntAtBase 8 intToDigit
-
--- | Show /non-negative/ 'Integral' numbers in base 2.
-showBin :: Integral a => a -> ShowS
-showBin = showIntAtBase 2 intToDigit
=====================================
libraries/ghc-internal/src/GHC/Internal/Read.hs
=====================================
@@ -80,7 +80,6 @@ import GHC.Internal.Types (Bool(..), Char, Int, Ordering(..))
import GHC.Internal.Word
import GHC.Internal.List (filter)
import GHC.Internal.Tuple (Solo (..))
-import GHC.Internal.ByteOrder
-- | @'readParen' 'True' p@ parses what @p@ parses, but surrounded with
@@ -840,6 +839,3 @@ instance (Read a, Read b, Read c, Read d, Read e, Read f, Read g, Read h,
; return (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) })
readListPrec = readListPrecDefault
readList = readListDefault
-
--- | @since base-4.11.0.0
-deriving instance Read ByteOrder
=====================================
testsuite/tests/interface-stability/base-exports.stdout
=====================================
@@ -9455,7 +9455,7 @@ module GHC.Word where
uncheckedShiftRL64# :: GHC.Internal.Prim.Word64# -> GHC.Internal.Prim.Int# -> GHC.Internal.Prim.Word64#
module Numeric where
- -- Safety: Safe
+ -- Safety: Trustworthy
type Floating :: * -> Constraint
class GHC.Internal.Real.Fractional a => Floating a where
pi :: a
@@ -12432,7 +12432,6 @@ instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (GHC.Inter
instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (GHC.Internal.Data.Bits.Xor a) -- Defined in ‘GHC.Internal.Data.Bits’
instance forall a b. (GHC.Internal.Ix.Ix a, GHC.Internal.Read.Read a, GHC.Internal.Read.Read b) => GHC.Internal.Read.Read (GHC.Internal.Arr.Array a b) -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Bool -- Defined in ‘GHC.Internal.Read’
-instance GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Char -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Double -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Float -- Defined in ‘GHC.Internal.Read’
@@ -12499,7 +12498,7 @@ instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Semi
instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Semigroup.Min a) -- Defined in ‘Data.Semigroup’
instance forall m. GHC.Internal.Read.Read m => GHC.Internal.Read.Read (Data.Semigroup.WrappedMonoid m) -- Defined in ‘Data.Semigroup’
instance forall k (a :: k) (b :: k). Coercible a b => GHC.Internal.Read.Read (GHC.Internal.Data.Type.Coercion.Coercion a b) -- Defined in ‘GHC.Internal.Data.Type.Coercion’
-instance GHC.Internal.Read.Read GHC.Internal.Data.Version.Version -- Defined in ‘GHC.Internal.Data.Version’
+instance [safe] GHC.Internal.Read.Read GHC.Internal.Data.Version.Version -- Defined in ‘Data.Version’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.Ptr.IntPtr -- Defined in ‘GHC.Internal.Foreign.Ptr’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.Ptr.WordPtr -- Defined in ‘GHC.Internal.Foreign.Ptr’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CBool -- Defined in ‘GHC.Internal.Foreign.C.Types’
@@ -12528,6 +12527,7 @@ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CULong -- Defined i
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’
+instance [safe] GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.ByteOrder’
instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’
instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’
instance forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1). GHC.Internal.Read.Read (f (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:.:) f g p) -- Defined in ‘GHC.Internal.Generics’
@@ -12542,16 +12542,16 @@ instance GHC.Internal.Read.Read GHC.Internal.Generics.SourceStrictness -- Define
instance GHC.Internal.Read.Read GHC.Internal.Generics.SourceUnpackedness -- Defined in ‘GHC.Internal.Generics’
instance forall k (p :: k). GHC.Internal.Read.Read (GHC.Internal.Generics.U1 p) -- Defined in ‘GHC.Internal.Generics’
instance forall k (p :: k). GHC.Internal.Read.Read (GHC.Internal.Generics.V1 p) -- Defined in ‘GHC.Internal.Generics’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Device.SeekMode -- Defined in ‘GHC.Internal.IO.Device’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.BufferMode -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.IOMode.IOMode -- Defined in ‘GHC.Internal.IO.IOMode’
instance [safe] GHC.Internal.Read.Read GHC.Stats.GCDetails -- Defined in ‘GHC.Stats’
instance [safe] GHC.Internal.Read.Read GHC.Stats.RTSStats -- Defined in ‘GHC.Stats’
instance GHC.Internal.Read.Read GHC.Internal.TypeNats.SomeNat -- Defined in ‘GHC.Internal.TypeNats’
instance GHC.Internal.Read.Read GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
instance GHC.Internal.Read.Read GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.BufferMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.IOMode.IOMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Device.SeekMode -- Defined in ‘System.IO’
instance forall k a (b :: k). GHC.Internal.Real.Fractional a => GHC.Internal.Real.Fractional (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’
instance forall a. GHC.Internal.Float.RealFloat a => GHC.Internal.Real.Fractional (Data.Complex.Complex a) -- Defined in ‘Data.Complex’
instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Real.Fractional (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’
=====================================
testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
=====================================
@@ -9493,7 +9493,7 @@ module GHC.Word where
uncheckedShiftRL64# :: GHC.Internal.Prim.Word64# -> GHC.Internal.Prim.Int# -> GHC.Internal.Prim.Word64#
module Numeric where
- -- Safety: Safe
+ -- Safety: Trustworthy
type Floating :: * -> Constraint
class GHC.Internal.Real.Fractional a => Floating a where
pi :: a
@@ -12461,7 +12461,6 @@ instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (GHC.Inter
instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (GHC.Internal.Data.Bits.Xor a) -- Defined in ‘GHC.Internal.Data.Bits’
instance forall a b. (GHC.Internal.Ix.Ix a, GHC.Internal.Read.Read a, GHC.Internal.Read.Read b) => GHC.Internal.Read.Read (GHC.Internal.Arr.Array a b) -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Bool -- Defined in ‘GHC.Internal.Read’
-instance GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Char -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Double -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Float -- Defined in ‘GHC.Internal.Read’
@@ -12528,7 +12527,7 @@ instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Semi
instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Semigroup.Min a) -- Defined in ‘Data.Semigroup’
instance forall m. GHC.Internal.Read.Read m => GHC.Internal.Read.Read (Data.Semigroup.WrappedMonoid m) -- Defined in ‘Data.Semigroup’
instance forall k (a :: k) (b :: k). Coercible a b => GHC.Internal.Read.Read (GHC.Internal.Data.Type.Coercion.Coercion a b) -- Defined in ‘GHC.Internal.Data.Type.Coercion’
-instance GHC.Internal.Read.Read GHC.Internal.Data.Version.Version -- Defined in ‘GHC.Internal.Data.Version’
+instance [safe] GHC.Internal.Read.Read GHC.Internal.Data.Version.Version -- Defined in ‘Data.Version’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.Ptr.IntPtr -- Defined in ‘GHC.Internal.Foreign.Ptr’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.Ptr.WordPtr -- Defined in ‘GHC.Internal.Foreign.Ptr’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CBool -- Defined in ‘GHC.Internal.Foreign.C.Types’
@@ -12557,6 +12556,7 @@ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CULong -- Defined i
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’
+instance [safe] GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.ByteOrder’
instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’
instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’
instance forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1). GHC.Internal.Read.Read (f (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:.:) f g p) -- Defined in ‘GHC.Internal.Generics’
@@ -12571,16 +12571,16 @@ instance GHC.Internal.Read.Read GHC.Internal.Generics.SourceStrictness -- Define
instance GHC.Internal.Read.Read GHC.Internal.Generics.SourceUnpackedness -- Defined in ‘GHC.Internal.Generics’
instance forall k (p :: k). GHC.Internal.Read.Read (GHC.Internal.Generics.U1 p) -- Defined in ‘GHC.Internal.Generics’
instance forall k (p :: k). GHC.Internal.Read.Read (GHC.Internal.Generics.V1 p) -- Defined in ‘GHC.Internal.Generics’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Device.SeekMode -- Defined in ‘GHC.Internal.IO.Device’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.BufferMode -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.IOMode.IOMode -- Defined in ‘GHC.Internal.IO.IOMode’
instance [safe] GHC.Internal.Read.Read GHC.Stats.GCDetails -- Defined in ‘GHC.Stats’
instance [safe] GHC.Internal.Read.Read GHC.Stats.RTSStats -- Defined in ‘GHC.Stats’
instance GHC.Internal.Read.Read GHC.Internal.TypeNats.SomeNat -- Defined in ‘GHC.Internal.TypeNats’
instance GHC.Internal.Read.Read GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
instance GHC.Internal.Read.Read GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.BufferMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.IOMode.IOMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Device.SeekMode -- Defined in ‘System.IO’
instance forall k a (b :: k). GHC.Internal.Real.Fractional a => GHC.Internal.Real.Fractional (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’
instance forall a. GHC.Internal.Float.RealFloat a => GHC.Internal.Real.Fractional (Data.Complex.Complex a) -- Defined in ‘Data.Complex’
instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Real.Fractional (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’
=====================================
testsuite/tests/interface-stability/base-exports.stdout-mingw32
=====================================
@@ -9735,7 +9735,7 @@ module GHC.Word where
uncheckedShiftRL64# :: GHC.Internal.Prim.Word64# -> GHC.Internal.Prim.Int# -> GHC.Internal.Prim.Word64#
module Numeric where
- -- Safety: Safe
+ -- Safety: Trustworthy
type Floating :: * -> Constraint
class GHC.Internal.Real.Fractional a => Floating a where
pi :: a
@@ -12703,7 +12703,6 @@ instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (GHC.Inter
instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (GHC.Internal.Data.Bits.Xor a) -- Defined in ‘GHC.Internal.Data.Bits’
instance forall a b. (GHC.Internal.Ix.Ix a, GHC.Internal.Read.Read a, GHC.Internal.Read.Read b) => GHC.Internal.Read.Read (GHC.Internal.Arr.Array a b) -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Bool -- Defined in ‘GHC.Internal.Read’
-instance GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Char -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Double -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Float -- Defined in ‘GHC.Internal.Read’
@@ -12770,7 +12769,7 @@ instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Semi
instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Semigroup.Min a) -- Defined in ‘Data.Semigroup’
instance forall m. GHC.Internal.Read.Read m => GHC.Internal.Read.Read (Data.Semigroup.WrappedMonoid m) -- Defined in ‘Data.Semigroup’
instance forall k (a :: k) (b :: k). Coercible a b => GHC.Internal.Read.Read (GHC.Internal.Data.Type.Coercion.Coercion a b) -- Defined in ‘GHC.Internal.Data.Type.Coercion’
-instance GHC.Internal.Read.Read GHC.Internal.Data.Version.Version -- Defined in ‘GHC.Internal.Data.Version’
+instance [safe] GHC.Internal.Read.Read GHC.Internal.Data.Version.Version -- Defined in ‘Data.Version’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.Ptr.IntPtr -- Defined in ‘GHC.Internal.Foreign.Ptr’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.Ptr.WordPtr -- Defined in ‘GHC.Internal.Foreign.Ptr’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CBool -- Defined in ‘GHC.Internal.Foreign.C.Types’
@@ -12799,6 +12798,7 @@ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CULong -- Defined i
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’
+instance [safe] GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.ByteOrder’
instance GHC.Internal.Read.Read GHC.Internal.Event.Windows.ConsoleEvent.ConsoleEvent -- Defined in ‘GHC.Internal.Event.Windows.ConsoleEvent’
instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’
instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’
@@ -12814,16 +12814,16 @@ instance GHC.Internal.Read.Read GHC.Internal.Generics.SourceStrictness -- Define
instance GHC.Internal.Read.Read GHC.Internal.Generics.SourceUnpackedness -- Defined in ‘GHC.Internal.Generics’
instance forall k (p :: k). GHC.Internal.Read.Read (GHC.Internal.Generics.U1 p) -- Defined in ‘GHC.Internal.Generics’
instance forall k (p :: k). GHC.Internal.Read.Read (GHC.Internal.Generics.V1 p) -- Defined in ‘GHC.Internal.Generics’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Device.SeekMode -- Defined in ‘GHC.Internal.IO.Device’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.BufferMode -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.IOMode.IOMode -- Defined in ‘GHC.Internal.IO.IOMode’
instance [safe] GHC.Internal.Read.Read GHC.Stats.GCDetails -- Defined in ‘GHC.Stats’
instance [safe] GHC.Internal.Read.Read GHC.Stats.RTSStats -- Defined in ‘GHC.Stats’
instance GHC.Internal.Read.Read GHC.Internal.TypeNats.SomeNat -- Defined in ‘GHC.Internal.TypeNats’
instance GHC.Internal.Read.Read GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
instance GHC.Internal.Read.Read GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.BufferMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.IOMode.IOMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Device.SeekMode -- Defined in ‘System.IO’
instance forall k a (b :: k). GHC.Internal.Real.Fractional a => GHC.Internal.Real.Fractional (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’
instance forall a. GHC.Internal.Float.RealFloat a => GHC.Internal.Real.Fractional (Data.Complex.Complex a) -- Defined in ‘Data.Complex’
instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Real.Fractional (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’
=====================================
testsuite/tests/interface-stability/base-exports.stdout-ws-32
=====================================
@@ -9455,7 +9455,7 @@ module GHC.Word where
uncheckedShiftRL64# :: GHC.Internal.Prim.Word64# -> GHC.Internal.Prim.Int# -> GHC.Internal.Prim.Word64#
module Numeric where
- -- Safety: Safe
+ -- Safety: Trustworthy
type Floating :: * -> Constraint
class GHC.Internal.Real.Fractional a => Floating a where
pi :: a
@@ -12432,7 +12432,6 @@ instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (GHC.Inter
instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (GHC.Internal.Data.Bits.Xor a) -- Defined in ‘GHC.Internal.Data.Bits’
instance forall a b. (GHC.Internal.Ix.Ix a, GHC.Internal.Read.Read a, GHC.Internal.Read.Read b) => GHC.Internal.Read.Read (GHC.Internal.Arr.Array a b) -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Bool -- Defined in ‘GHC.Internal.Read’
-instance GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Char -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Double -- Defined in ‘GHC.Internal.Read’
instance GHC.Internal.Read.Read GHC.Internal.Types.Float -- Defined in ‘GHC.Internal.Read’
@@ -12499,7 +12498,7 @@ instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Semi
instance forall a. GHC.Internal.Read.Read a => GHC.Internal.Read.Read (Data.Semigroup.Min a) -- Defined in ‘Data.Semigroup’
instance forall m. GHC.Internal.Read.Read m => GHC.Internal.Read.Read (Data.Semigroup.WrappedMonoid m) -- Defined in ‘Data.Semigroup’
instance forall k (a :: k) (b :: k). Coercible a b => GHC.Internal.Read.Read (GHC.Internal.Data.Type.Coercion.Coercion a b) -- Defined in ‘GHC.Internal.Data.Type.Coercion’
-instance GHC.Internal.Read.Read GHC.Internal.Data.Version.Version -- Defined in ‘GHC.Internal.Data.Version’
+instance [safe] GHC.Internal.Read.Read GHC.Internal.Data.Version.Version -- Defined in ‘Data.Version’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.Ptr.IntPtr -- Defined in ‘GHC.Internal.Foreign.Ptr’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.Ptr.WordPtr -- Defined in ‘GHC.Internal.Foreign.Ptr’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CBool -- Defined in ‘GHC.Internal.Foreign.C.Types’
@@ -12528,6 +12527,7 @@ instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CULong -- Defined i
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUSeconds -- Defined in ‘GHC.Internal.Foreign.C.Types’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CUShort -- Defined in ‘GHC.Internal.Foreign.C.Types’
instance GHC.Internal.Read.Read GHC.Internal.Foreign.C.Types.CWchar -- Defined in ‘GHC.Internal.Foreign.C.Types’
+instance [safe] GHC.Internal.Read.Read GHC.Internal.ByteOrder.ByteOrder -- Defined in ‘GHC.ByteOrder’
instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:*:) f g p) -- Defined in ‘GHC.Internal.Generics’
instance forall k (f :: k -> *) (g :: k -> *) (p :: k). (GHC.Internal.Read.Read (f p), GHC.Internal.Read.Read (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:+:) f g p) -- Defined in ‘GHC.Internal.Generics’
instance forall k2 k1 (f :: k2 -> *) (g :: k1 -> k2) (p :: k1). GHC.Internal.Read.Read (f (g p)) => GHC.Internal.Read.Read ((GHC.Internal.Generics.:.:) f g p) -- Defined in ‘GHC.Internal.Generics’
@@ -12542,16 +12542,16 @@ instance GHC.Internal.Read.Read GHC.Internal.Generics.SourceStrictness -- Define
instance GHC.Internal.Read.Read GHC.Internal.Generics.SourceUnpackedness -- Defined in ‘GHC.Internal.Generics’
instance forall k (p :: k). GHC.Internal.Read.Read (GHC.Internal.Generics.U1 p) -- Defined in ‘GHC.Internal.Generics’
instance forall k (p :: k). GHC.Internal.Read.Read (GHC.Internal.Generics.V1 p) -- Defined in ‘GHC.Internal.Generics’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Device.SeekMode -- Defined in ‘GHC.Internal.IO.Device’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.BufferMode -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘GHC.Internal.IO.Handle.Types’
-instance GHC.Internal.Read.Read GHC.Internal.IO.IOMode.IOMode -- Defined in ‘GHC.Internal.IO.IOMode’
instance [safe] GHC.Internal.Read.Read GHC.Stats.GCDetails -- Defined in ‘GHC.Stats’
instance [safe] GHC.Internal.Read.Read GHC.Stats.RTSStats -- Defined in ‘GHC.Stats’
instance GHC.Internal.Read.Read GHC.Internal.TypeNats.SomeNat -- Defined in ‘GHC.Internal.TypeNats’
instance GHC.Internal.Read.Read GHC.Internal.TypeLits.SomeChar -- Defined in ‘GHC.Internal.TypeLits’
instance GHC.Internal.Read.Read GHC.Internal.TypeLits.SomeSymbol -- Defined in ‘GHC.Internal.TypeLits’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.BufferMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.IOMode.IOMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.Newline -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Handle.Types.NewlineMode -- Defined in ‘System.IO’
+instance GHC.Internal.Read.Read GHC.Internal.IO.Device.SeekMode -- Defined in ‘System.IO’
instance forall k a (b :: k). GHC.Internal.Real.Fractional a => GHC.Internal.Real.Fractional (GHC.Internal.Data.Functor.Const.Const a b) -- Defined in ‘GHC.Internal.Data.Functor.Const’
instance forall a. GHC.Internal.Float.RealFloat a => GHC.Internal.Real.Fractional (Data.Complex.Complex a) -- Defined in ‘Data.Complex’
instance forall k (a :: k). Data.Fixed.HasResolution a => GHC.Internal.Real.Fractional (Data.Fixed.Fixed a) -- Defined in ‘Data.Fixed’
=====================================
testsuite/tests/plugins/plugins09.stdout
=====================================
@@ -1,5 +1,6 @@
parsePlugin(a,b)
interfacePlugin: Prelude
+interfacePlugin: System.IO
interfacePlugin: GHC.Internal.Base
interfacePlugin: GHC.Internal.Data.NonEmpty
interfacePlugin: GHC.Internal.Float
=====================================
testsuite/tests/plugins/plugins10.stdout
=====================================
@@ -2,6 +2,8 @@ parsePlugin()
interfacePlugin: Prelude
interfacePlugin: Language.Haskell.TH
interfacePlugin: Language.Haskell.TH.Quote
+interfacePlugin: Data.Version
+interfacePlugin: System.IO
interfacePlugin: GHC.Internal.Base
interfacePlugin: GHC.Internal.Data.NonEmpty
interfacePlugin: GHC.Internal.Float
=====================================
testsuite/tests/plugins/plugins11.stdout
=====================================
@@ -1,5 +1,6 @@
parsePlugin()
interfacePlugin: Prelude
+interfacePlugin: System.IO
interfacePlugin: GHC.Internal.Base
interfacePlugin: GHC.Internal.Data.NonEmpty
interfacePlugin: GHC.Internal.Float
=====================================
testsuite/tests/plugins/static-plugins.stdout
=====================================
@@ -1,6 +1,7 @@
==pure.0
parsePlugin()
interfacePlugin: Prelude
+interfacePlugin: System.IO
interfacePlugin: GHC.Internal.Base
interfacePlugin: GHC.Internal.Data.NonEmpty
interfacePlugin: GHC.Internal.Float
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d59b7c7109e4d8ef9035ec4b9d9f164…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d59b7c7109e4d8ef9035ec4b9d9f164…
You're receiving this email because of your account on gitlab.haskell.org.
1
0