sheaf pushed new branch wip/T26595-fragile at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T26595-fragile
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/torsten.schmits/mercury-ghc910-mhu-transitive-th-deps_ospath] 2 commits: remove redundant core bindings typecheck in initWholeCoreBindings
by Torsten Schmits (@torsten.schmits) 19 Nov '25
by Torsten Schmits (@torsten.schmits) 19 Nov '25
19 Nov '25
Torsten Schmits pushed to branch wip/torsten.schmits/mercury-ghc910-mhu-transitive-th-deps_ospath at Glasgow Haskell Compiler / GHC
Commits:
4d6ffa22 by Torsten Schmits at 2025-11-06T16:10:01+01:00
remove redundant core bindings typecheck in initWholeCoreBindings
- - - - -
75206a24 by Georgios Karachalias at 2025-11-19T13:58:58+01:00
Use OsPath in PkgDbRef and UnitDatabase, not FilePath
- - - - -
8 changed files:
- + compiler/GHC/Data/OsPath.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Linker/Deps.hs
- compiler/GHC/Unit/State.hs
- compiler/ghc.cabal.in
Changes:
=====================================
compiler/GHC/Data/OsPath.hs
=====================================
@@ -0,0 +1,45 @@
+module GHC.Data.OsPath
+ (
+ -- * OsPath initialisation and transformation
+ OsPath
+ , OsString
+ , encodeUtf
+ , decodeUtf
+ , unsafeDecodeUtf
+ , unsafeEncodeUtf
+ , os
+ -- * Common utility functions
+ , (</>)
+ , (<.>)
+ , splitSearchPath
+ , isRelative
+ , dropTrailingPathSeparator
+ , takeDirectory
+ , isSuffixOf
+ , doesDirectoryExist
+ , doesFileExist
+ , getDirectoryContents
+ , createDirectoryIfMissing
+ , pprOsPath
+ )
+ where
+
+import GHC.Prelude
+
+import GHC.Utils.Misc (HasCallStack)
+import GHC.Utils.Outputable qualified as Outputable
+import GHC.Utils.Panic (panic)
+
+import System.OsPath
+import System.OsString (isSuffixOf)
+import System.Directory.OsPath (doesDirectoryExist, doesFileExist, getDirectoryContents, createDirectoryIfMissing)
+import System.Directory.Internal (os)
+
+-- | Decode an 'OsPath' to 'FilePath', throwing an 'error' if decoding failed.
+-- Prefer 'decodeUtf' and gracious error handling.
+unsafeDecodeUtf :: HasCallStack => OsPath -> FilePath
+unsafeDecodeUtf p =
+ either (\err -> panic $ "Failed to decodeUtf \"" ++ show p ++ "\", because: " ++ show err) id (decodeUtf p)
+
+pprOsPath :: HasCallStack => OsPath -> Outputable.SDoc
+pprOsPath = Outputable.text . unsafeDecodeUtf
=====================================
compiler/GHC/Driver/Backpack.hs
=====================================
@@ -76,6 +76,7 @@ import qualified GHC.LanguageExtensions as LangExt
import GHC.Data.Maybe
import GHC.Data.StringBuffer
import GHC.Data.FastString
+import qualified GHC.Data.OsPath as OsPath
import qualified GHC.Data.EnumSet as EnumSet
import qualified GHC.Data.ShortText as ST
@@ -433,7 +434,7 @@ addUnit u = do
Nothing -> panic "addUnit: called too early"
Just dbs ->
let newdb = UnitDatabase
- { unitDatabasePath = "(in memory " ++ showSDoc dflags0 (ppr (unitId u)) ++ ")"
+ { unitDatabasePath = OsPath.unsafeEncodeUtf $ "(in memory " ++ showSDoc dflags0 (ppr (unitId u)) ++ ")"
, unitDatabaseUnits = [u]
}
in return (dbs ++ [newdb]) -- added at the end because ordering matters
=====================================
compiler/GHC/Driver/DynFlags.hs
=====================================
@@ -96,6 +96,7 @@ import GHC.Core.Unfold
import GHC.Data.Bool
import GHC.Data.EnumSet (EnumSet)
import GHC.Data.Maybe
+import GHC.Data.OsPath (OsPath)
import GHC.Builtin.Names ( mAIN_NAME )
import GHC.Driver.Backend
import GHC.Driver.Flags
@@ -948,7 +949,7 @@ setDynamicNow dflags0 =
data PkgDbRef
= GlobalPkgDb
| UserPkgDb
- | PkgDbPath FilePath
+ | PkgDbPath OsPath
deriving Eq
-- | Used to differentiate the scope an include needs to apply to.
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -1009,11 +1009,6 @@ initWholeCoreBindings hsc_env mod_iface details (LM utc_time this_mod uls) = do
types_var <- newIORef (md_types details)
let kv = knotVarsFromModuleEnv (mkModuleEnv [(this_mod, types_var)])
let hsc_env' = hscUpdateHPT act hsc_env { hsc_type_env_vars = kv }
- core_binds <- initIfaceCheck (text "l") hsc_env' $ typecheckWholeCoreBindings types_var fi
- -- MP: The NoStubs here is only from (I think) the TH `qAddForeignFilePath` feature but it's a bit unclear what to do
- -- with these files, do we have to read and serialise the foreign file? I will leave it for now until someone
- -- reports a bug.
- let cgi_guts = CgInteractiveGuts this_mod core_binds (typeEnvTyCons (md_types details)) NoStubs Nothing []
-- The bytecode generation itself is lazy because otherwise even when doing
-- recompilation checking the bytecode will be generated (which slows things down a lot)
-- the laziness is OK because generateByteCode just depends on things already loaded
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -255,6 +255,7 @@ import GHC.Types.SrcLoc
import GHC.Types.SafeHaskell
import GHC.Types.Basic ( treatZeroAsInf )
import GHC.Data.FastString
+import qualified GHC.Data.OsPath as OsPath
import GHC.Utils.TmpFs
import GHC.Utils.Fingerprint
import GHC.Utils.Outputable
@@ -1962,7 +1963,7 @@ package_flags_deps :: [(Deprecation, Flag (CmdLineP DynFlags))]
package_flags_deps = [
------- Packages ----------------------------------------------------
make_ord_flag defFlag "package-db"
- (HasArg (addPkgDbRef . PkgDbPath))
+ (HasArg (addPkgDbRef . PkgDbPath . OsPath.unsafeEncodeUtf))
, make_ord_flag defFlag "clear-package-db" (NoArg clearPkgDb)
, make_ord_flag defFlag "no-global-package-db" (NoArg removeGlobalPkgDb)
, make_ord_flag defFlag "no-user-package-db" (NoArg removeUserPkgDb)
@@ -1972,7 +1973,7 @@ package_flags_deps = [
(NoArg (addPkgDbRef UserPkgDb))
-- backwards compat with GHC<=7.4 :
, make_dep_flag defFlag "package-conf"
- (HasArg $ addPkgDbRef . PkgDbPath) "Use -package-db instead"
+ (HasArg $ addPkgDbRef . PkgDbPath . OsPath.unsafeEncodeUtf) "Use -package-db instead"
, make_dep_flag defFlag "no-user-package-conf"
(NoArg removeUserPkgDb) "Use -no-user-package-db instead"
, make_ord_flag defGhcFlag "package-name" (HasArg $ \name ->
@@ -3377,7 +3378,7 @@ parseEnvFile :: FilePath -> String -> DynP ()
parseEnvFile envfile = mapM_ parseEntry . lines
where
parseEntry str = case words str of
- ("package-db": _) -> addPkgDbRef (PkgDbPath (envdir </> db))
+ ("package-db": _) -> addPkgDbRef (PkgDbPath (OsPath.unsafeEncodeUtf (envdir </> db)))
-- relative package dbs are interpreted relative to the env file
where envdir = takeDirectory envfile
db = drop 11 str
=====================================
compiler/GHC/Linker/Deps.hs
=====================================
@@ -54,8 +54,6 @@ import Control.Monad.IO.Class (MonadIO (liftIO))
import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE)
import qualified Data.Set as Set
-import qualified Data.Map as M
-import Data.List (isSuffixOf)
import System.FilePath
import System.Directory
=====================================
compiler/GHC/Unit/State.hs
=====================================
@@ -103,6 +103,8 @@ import GHC.Data.Maybe
import System.Environment ( getEnv )
import GHC.Data.FastString
import qualified GHC.Data.ShortText as ST
+import GHC.Data.OsPath (OsPath)
+import qualified GHC.Data.OsPath as OsPath
import GHC.Utils.Logger
import GHC.Utils.Error
import GHC.Utils.Exception
@@ -112,7 +114,7 @@ import System.FilePath as FilePath
import Control.Monad
import Data.Graph (stronglyConnComp, SCC(..))
import Data.Char ( toUpper )
-import Data.List ( intersperse, partition, sortBy, isSuffixOf, sortOn )
+import Data.List ( intersperse, partition, sortBy, sortOn )
import Data.Set (Set)
import Data.Monoid (First(..))
import qualified Data.Semigroup as Semigroup
@@ -405,7 +407,7 @@ initUnitConfig dflags cached_dbs home_units =
where
offsetPackageDb :: Maybe FilePath -> PackageDBFlag -> PackageDBFlag
- offsetPackageDb (Just offset) (PackageDB (PkgDbPath p)) | isRelative p = PackageDB (PkgDbPath (offset </> p))
+ offsetPackageDb (Just offset) (PackageDB (PkgDbPath p)) | OsPath.isRelative p = PackageDB (PkgDbPath (OsPath.unsafeEncodeUtf offset OsPath.</> p))
offsetPackageDb _ p = p
@@ -500,12 +502,12 @@ emptyUnitState = UnitState {
-- | Unit database
data UnitDatabase unit = UnitDatabase
- { unitDatabasePath :: FilePath
+ { unitDatabasePath :: OsPath
, unitDatabaseUnits :: [GenUnitInfo unit]
}
instance Outputable u => Outputable (UnitDatabase u) where
- ppr (UnitDatabase fp _u) = text "DB:" <+> text fp
+ ppr (UnitDatabase fp _u) = text "DB:" <+> OsPath.pprOsPath fp
type UnitInfoMap = UniqMap UnitId UnitInfo
@@ -720,9 +722,9 @@ getUnitDbRefs cfg = do
Left _ -> system_conf_refs
Right path
| Just (xs, x) <- snocView path, isSearchPathSeparator x
- -> map PkgDbPath (splitSearchPath xs) ++ system_conf_refs
+ -> map PkgDbPath (OsPath.splitSearchPath (OsPath.unsafeEncodeUtf xs)) ++ system_conf_refs
| otherwise
- -> map PkgDbPath (splitSearchPath path)
+ -> map PkgDbPath (OsPath.splitSearchPath (OsPath.unsafeEncodeUtf path))
-- Apply the package DB-related flags from the command line to get the
-- final list of package DBs.
@@ -751,24 +753,24 @@ getUnitDbRefs cfg = do
-- NB: This logic is reimplemented in Cabal, so if you change it,
-- make sure you update Cabal. (Or, better yet, dump it in the
-- compiler info so Cabal can use the info.)
-resolveUnitDatabase :: UnitConfig -> PkgDbRef -> IO (Maybe FilePath)
-resolveUnitDatabase cfg GlobalPkgDb = return $ Just (unitConfigGlobalDB cfg)
+resolveUnitDatabase :: UnitConfig -> PkgDbRef -> IO (Maybe OsPath)
+resolveUnitDatabase cfg GlobalPkgDb = return $ Just $ OsPath.unsafeEncodeUtf $ unitConfigGlobalDB cfg
resolveUnitDatabase cfg UserPkgDb = runMaybeT $ do
dir <- versionedAppDir (unitConfigProgramName cfg) (unitConfigPlatformArchOS cfg)
let pkgconf = dir </> unitConfigDBName cfg
exist <- tryMaybeT $ doesDirectoryExist pkgconf
- if exist then return pkgconf else mzero
+ if exist then return (OsPath.unsafeEncodeUtf pkgconf) else mzero
resolveUnitDatabase _ (PkgDbPath name) = return $ Just name
-readUnitDatabase :: Logger -> UnitConfig -> FilePath -> IO (UnitDatabase UnitId)
+readUnitDatabase :: Logger -> UnitConfig -> OsPath -> IO (UnitDatabase UnitId)
readUnitDatabase logger cfg conf_file = do
- isdir <- doesDirectoryExist conf_file
+ isdir <- OsPath.doesDirectoryExist conf_file
proto_pkg_configs <-
if isdir
then readDirStyleUnitInfo conf_file
else do
- isfile <- doesFileExist conf_file
+ isfile <- OsPath.doesFileExist conf_file
if isfile
then do
mpkgs <- tryReadOldFileStyleUnitInfo
@@ -776,48 +778,49 @@ readUnitDatabase logger cfg conf_file = do
Just pkgs -> return pkgs
Nothing -> throwGhcExceptionIO $ InstallationError $
"ghc no longer supports single-file style package " ++
- "databases (" ++ conf_file ++
+ "databases (" ++ show conf_file ++
") use 'ghc-pkg init' to create the database with " ++
"the correct format."
else throwGhcExceptionIO $ InstallationError $
- "can't find a package database at " ++ conf_file
+ "can't find a package database at " ++ show conf_file
let
-- Fix #16360: remove trailing slash from conf_file before calculating pkgroot
- conf_file' = dropTrailingPathSeparator conf_file
- top_dir = unitConfigGHCDir cfg
- pkgroot = takeDirectory conf_file'
+ conf_file' = OsPath.dropTrailingPathSeparator conf_file
+ top_dir = OsPath.unsafeEncodeUtf (unitConfigGHCDir cfg) -- TODO: hm.
+ pkgroot = OsPath.takeDirectory conf_file'
pkg_configs1 = map (mungeUnitInfo top_dir pkgroot . mapUnitInfo (\(UnitKey x) -> UnitId x) . mkUnitKeyInfo)
proto_pkg_configs
--
return $ UnitDatabase conf_file' pkg_configs1
where
+ readDirStyleUnitInfo :: OsPath -> IO [DbUnitInfo]
readDirStyleUnitInfo conf_dir = do
- let filename = conf_dir </> "package.cache"
- cache_exists <- doesFileExist filename
+ let filename = conf_dir OsPath.</> (OsPath.unsafeEncodeUtf "package.cache")
+ cache_exists <- OsPath.doesFileExist filename
if cache_exists
then do
- debugTraceMsg logger 2 $ text "Using binary package database:" <+> text filename
- readPackageDbForGhc filename
+ debugTraceMsg logger 2 $ text "Using binary package database:" <+> OsPath.pprOsPath filename
+ readPackageDbForGhc (OsPath.unsafeDecodeUtf filename) -- TODO: Can we help it with this one? it comes from the ghc-boot package
else do
-- If there is no package.cache file, we check if the database is not
-- empty by inspecting if the directory contains any .conf file. If it
-- does, something is wrong and we fail. Otherwise we assume that the
-- database is empty.
debugTraceMsg logger 2 $ text "There is no package.cache in"
- <+> text conf_dir
+ <+> OsPath.pprOsPath conf_dir
<> text ", checking if the database is empty"
- db_empty <- all (not . isSuffixOf ".conf")
- <$> getDirectoryContents conf_dir
+ db_empty <- all (not . OsPath.isSuffixOf (OsPath.unsafeEncodeUtf ".conf"))
+ <$> OsPath.getDirectoryContents conf_dir
if db_empty
then do
debugTraceMsg logger 3 $ text "There are no .conf files in"
- <+> text conf_dir <> text ", treating"
+ <+> OsPath.pprOsPath conf_dir <> text ", treating"
<+> text "package database as empty"
return []
else
throwGhcExceptionIO $ InstallationError $
- "there is no package.cache in " ++ conf_dir ++
+ "there is no package.cache in " ++ show conf_dir ++
" even though package database is not empty"
@@ -830,13 +833,13 @@ readUnitDatabase logger cfg conf_file = do
-- assumes it's a file and tries to overwrite with 'writeFile'.
-- ghc-pkg also cooperates with this workaround.
tryReadOldFileStyleUnitInfo = do
- content <- readFile conf_file `catchIO` \_ -> return ""
+ content <- readFile (OsPath.unsafeDecodeUtf conf_file) `catchIO` \_ -> return ""
if take 2 content == "[]"
then do
- let conf_dir = conf_file <.> "d"
- direxists <- doesDirectoryExist conf_dir
+ let conf_dir = conf_file OsPath.<.> OsPath.unsafeEncodeUtf "d"
+ direxists <- OsPath.doesDirectoryExist conf_dir
if direxists
- then do debugTraceMsg logger 2 (text "Ignoring old file-style db and trying:" <+> text conf_dir)
+ then do debugTraceMsg logger 2 (text "Ignoring old file-style db and trying:" <+> OsPath.pprOsPath conf_dir)
liftM Just (readDirStyleUnitInfo conf_dir)
else return (Just []) -- ghc-pkg will create it when it's updated
else return Nothing
@@ -846,11 +849,12 @@ distrustAllUnits pkgs = map distrust pkgs
where
distrust pkg = pkg{ unitIsTrusted = False }
-mungeUnitInfo :: FilePath -> FilePath
+-- TODO: Can we help it with this one? it comes from the ghc-boot package
+mungeUnitInfo :: OsPath -> OsPath
-> UnitInfo -> UnitInfo
mungeUnitInfo top_dir pkgroot =
mungeDynLibFields
- . mungeUnitInfoPaths (ST.pack top_dir) (ST.pack pkgroot)
+ . mungeUnitInfoPaths (ST.pack (OsPath.unsafeDecodeUtf top_dir)) (ST.pack (OsPath.unsafeDecodeUtf pkgroot))
mungeDynLibFields :: UnitInfo -> UnitInfo
mungeDynLibFields pkg =
@@ -1388,7 +1392,7 @@ mergeDatabases logger = foldM merge (emptyUniqMap, emptyUniqMap) . zip [1..]
where
merge (pkg_map, prec_map) (i, UnitDatabase db_path db) = do
debugTraceMsg logger 2 $
- text "loading package database" <+> text db_path
+ text "loading package database" <+> OsPath.pprOsPath db_path
forM_ (Set.toList override_set) $ \pkg ->
debugTraceMsg logger 2 $
text "package" <+> ppr pkg <+>
=====================================
compiler/ghc.cabal.in
=====================================
@@ -115,6 +115,7 @@ Library
containers >= 0.6.2.1 && < 0.8,
array >= 0.1 && < 0.6,
filepath >= 1 && < 1.6,
+ os-string >= 2.0.1 && < 2.1,
template-haskell == 2.22.*,
hpc >= 0.6 && < 0.8,
transformers >= 0.5 && < 0.7,
@@ -430,6 +431,7 @@ Library
GHC.Data.List.SetOps
GHC.Data.Maybe
GHC.Data.OrdList
+ GHC.Data.OsPath
GHC.Data.Pair
GHC.Data.SmallArray
GHC.Data.Stream
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f166735f14fcdbbe054d15ccdd03ec…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f166735f14fcdbbe054d15ccdd03ec…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Make PmLit be in Ord, and use it in Map
by Marge Bot (@marge-bot) 19 Nov '25
by Marge Bot (@marge-bot) 19 Nov '25
19 Nov '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
c12fa73e by Simon Peyton Jones at 2025-11-19T02:55:01-05:00
Make PmLit be in Ord, and use it in Map
This MR addresses #26514, by changing from
data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
to
data PmAltConSet = PACS !(UniqDSet ConLike) !(Map PmLit PmLit)
This matters when doing pattern-match overlap checking, when there
is a very large set of patterns. For most programs it makes
no difference at all.
For the N=5000 case of the repro case in #26514, compiler
mutator time (with `-fno-code`) goes from 1.9s to 0.43s.
All for the price for an Ord instance for PmLit
- - - - -
41b84f40 by sheaf at 2025-11-19T02:55:52-05:00
Add passing tests for #26311 and #26072
This commit adds two tests cases that now pass since landing the changes
to typechecking of data constructors in b33284c7.
Fixes #26072 #26311
- - - - -
1faa758a by sheaf at 2025-11-19T02:55:52-05:00
mkCast: weaken bad cast warning for multiplicity
This commit weakens the warning message emitted when constructing a bad
cast in mkCast to ignore multiplicity.
Justification: since b33284c7, GHC uses sub-multiplicity coercions to
typecheck data constructors. The coercion optimiser is free to discard
these coercions, both for performance reasons, and because GHC's Core
simplifier does not (yet) preserve linearity.
We thus weaken 'mkCast' to use 'eqTypeIgnoringMultiplicity' instead of
'eqType', to avoid getting many spurious warnings about mismatched
multiplicities.
- - - - -
903b9f29 by Julian Ospald at 2025-11-19T07:33:54-05:00
Support statically linking executables properly
Fixes #26434
In detail, this does a number of things:
* Makes GHC aware of 'extra-libraries-static' (this changes the package
database format).
* Adds a switch '-static-external' that will honour 'extra-libraries-static'
to link external system dependencies statically.
* Adds a new field to settings/targets: "ld supports verbatim namespace".
This field is used by '-static-external' to conditionally use '-l:foo.a'
syntax during linking, which is more robust than trying to find the
absolute path to an archive on our own.
* Adds a switch '-fully-static' that is meant as a high-level interface
for e.g. cabal. This also honours 'extra-libraries-static'.
This also attempts to clean up the confusion around library search directories.
At the moment, we have 3 types of directories in the package database
format:
* library-dirs
* library-dirs-static
* dynamic-library-dirs
However, we only have two types of linking: dynamic or static. Given the
existing logic in 'mungeDynLibFields', this patch assumes that
'library-dirs' is really just nothing but a fallback and always
prefers the more specific variants if they exist and are non-empty.
Conceptually, we should be ok with even just one search dirs variant.
Haskell libraries are named differently depending on whether they're
static or dynamic, so GHC can conveniently pick the right one depending
on the linking needs. That means we don't really need to play tricks
with search paths to convince the compiler to do linking as we want it.
For system C libraries, the convention has been anyway to place static and
dynamic libs next to each other, so we need to deal with that issue
anyway and it is outside of our control. But this is out of the scope
of this patch.
This patch is backwards compatible with cabal. Cabal should however
be patched to use the new '-fully-static' switch.
- - - - -
0dcb8314 by Julian Ospald at 2025-11-19T07:33:54-05:00
Warn when "-dynamic" is mixed with "-staticlib"
- - - - -
795f3d8c by Julian Ospald at 2025-11-19T07:33:55-05:00
Move wasm "ways" constraints to 'makeDynFlagsConsistent'
- - - - -
107ac2ce by Rodrigo Mesquita at 2025-11-19T07:33:55-05:00
Add tests for #23973 and #26565
These were fixed by 4af4f0f070f83f948e49ad5d7835fd91b8d3f0e6 in !10417
- - - - -
67 changed files:
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/Linker/Dynamic.hs
- compiler/GHC/Linker/ExtraObj.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/Static.hs
- compiler/GHC/Linker/Unit.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/StgToJS/Linker/Utils.hs
- compiler/GHC/Types/SourceText.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/State.hs
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/phases.rst
- ghc/Main.hs
- hadrian/cfg/default.host.target.in
- hadrian/cfg/default.target.in
- hadrian/src/Settings/Builders/Cabal.hs
- libraries/ghc-boot/GHC/Unit/Database.hs
- libraries/ghc-internal/ghc-internal.buildinfo.in
- libraries/ghc-internal/ghc-internal.cabal.in
- + m4/fp_linker_supports_verbatim.m4
- m4/prep_target_file.m4
- mk/system-cxx-std-lib-1.0.conf.in
- rts/configure.ac
- rts/rts.buildinfo.in
- rts/rts.cabal
- + testsuite/driver/_elffile.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/ghc-config/ghc-config.hs
- + testsuite/tests/bytecode/T23973.hs
- + testsuite/tests/bytecode/T23973.script
- + testsuite/tests/bytecode/T23973.stdout
- + testsuite/tests/bytecode/T26565.hs
- + testsuite/tests/bytecode/T26565.script
- + testsuite/tests/bytecode/T26565.stdout
- testsuite/tests/bytecode/all.T
- + testsuite/tests/driver/fully-static/Hello.hs
- + testsuite/tests/driver/fully-static/Makefile
- + testsuite/tests/driver/fully-static/all.T
- + testsuite/tests/driver/fully-static/fully-static.stdout
- + testsuite/tests/driver/fully-static/test/Test.hs
- + testsuite/tests/driver/fully-static/test/test.pkg
- + testsuite/tests/driver/mostly-static/Hello.hs
- + testsuite/tests/driver/mostly-static/Makefile
- + testsuite/tests/driver/mostly-static/all.T
- + testsuite/tests/driver/mostly-static/mostly-static.stdout
- + testsuite/tests/driver/mostly-static/test/test.c
- + testsuite/tests/driver/mostly-static/test/test.h
- + testsuite/tests/driver/mostly-static/test/test.pkg
- + testsuite/tests/linear/should_run/T26311.hs
- + testsuite/tests/linear/should_run/T26311.stdout
- testsuite/tests/linear/should_run/all.T
- testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
- + testsuite/tests/rep-poly/T26072b.hs
- testsuite/tests/rep-poly/all.T
- utils/ghc-pkg/Main.hs
- utils/ghc-toolchain/exe/Main.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3a65832ab01c09c570521bf7562d5…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3a65832ab01c09c570521bf7562d5…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed to branch wip/T23162-part2 at Glasgow Haskell Compiler / GHC
Commits:
9106adf3 by Simon Peyton Jones at 2025-11-19T10:20:53+00:00
Comments
- - - - -
1 changed file:
- compiler/GHC/Tc/Solver/FunDeps.hs
Changes:
=====================================
compiler/GHC/Tc/Solver/FunDeps.hs
=====================================
@@ -549,7 +549,7 @@ mkTopClosedFamEqFDs ax work_args work_rhs
= do { let branches = fromBranches (coAxiomBranches ax)
; traceTcS "mkTopClosed" (ppr branches $$ ppr work_args $$ ppr work_rhs)
; case getRelevantBranches ax work_args work_rhs of
- [eqn] -> return [eqn]
+ [eqn] -> return [eqn] -- If there is just one relevant equation, use it
_ -> return [] }
| otherwise
= return []
@@ -580,6 +580,7 @@ hasRelevantGiven eqs_for_me work_args (EqCt { eq_rhs = work_rhs })
= False
getRelevantBranches :: CoAxiom Branched -> [TcType] -> Xi -> [FunDepEqns]
+-- Return the FunDepEqns that arise from each relevant branch
getRelevantBranches ax work_args work_rhs
= go [] (fromBranches (coAxiomBranches ax))
where
@@ -628,16 +629,6 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args work_rhs
| otherwise
= Nothing
-trim_qtvs :: Subst -> [TcTyVar] -> (Subst,[TcTyVar])
--- Tricky stuff: see (TIF1) in
--- Note [Type inference for type families with injectivity]
-trim_qtvs subst [] = (subst, [])
-trim_qtvs subst (tv:tvs)
- | tv `elemSubst` subst = trim_qtvs subst tvs
- | otherwise = let !(subst1, tv') = substTyVarBndr subst tv
- !(subst', tvs') = trim_qtvs subst1 tvs
- in (subst', tv':tvs')
-
mkLocalFamEqFDs :: [EqCt] -> TyCon -> [Bool] -> [TcType] -> Xi -> TcS [FunDepEqns]
mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs
= do { let -- eqns_from_inerts: see (INJFAM:Wanted/other)
@@ -657,6 +648,16 @@ mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs
mk_eqn iargs = mkInjectivityFDEqn inj_flags [] work_args iargs
+trim_qtvs :: Subst -> [TcTyVar] -> (Subst,[TcTyVar])
+-- Tricky stuff: see (TIF1) in
+-- Note [Type inference for type families with injectivity]
+trim_qtvs subst [] = (subst, [])
+trim_qtvs subst (tv:tvs)
+ | tv `elemSubst` subst = trim_qtvs subst tvs
+ | otherwise = let !(subst1, tv') = substTyVarBndr subst tv
+ !(subst', tvs') = trim_qtvs subst1 tvs
+ in (subst', tv':tvs')
+
-----------------------------------------
-- Built-in type families
-----------------------------------------
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9106adf35ef38c62d2720b0ed761d35…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9106adf35ef38c62d2720b0ed761d35…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T23162-part2] 41 commits: Preserve user-written kinds in data declarations
by Simon Peyton Jones (@simonpj) 19 Nov '25
by Simon Peyton Jones (@simonpj) 19 Nov '25
19 Nov '25
Simon Peyton Jones pushed to branch wip/T23162-part2 at Glasgow Haskell Compiler / GHC
Commits:
3c2f4bb4 by sheaf at 2025-11-11T11:47:28-05:00
Preserve user-written kinds in data declarations
This commit ensures that we preserve the user-written kind for data
declarations, e.g. in
type T2T = Type -> Type
type D :: T2T
data D a where { .. }
that we preserve the user-written kind of D as 'T2T', instead of
expanding the type synonym 'T2T' during kind checking.
We do this by storing 'tyConKind' separately from 'tyConResKind'. This
means that 'tyConKind' is not necessarily equal to
'mkTyConKind binders res_kind', as e.g. in the above example the former
is 'T2T' while the latter is 'Type -> Type'.
This is explained in Note [Preserve user-written TyCon kind] in GHC.Core.TyCon.
This is particularly important for Haddock, as the kinds stored in
interface files affect the generated documentation, and we want to
preserve the user-written types as much as possible.
- - - - -
19859584 by sheaf at 2025-11-11T11:47:28-05:00
Store user-written datacon tvs in interface files
This commit ensures we store the user-written quantified type variables
of data constructors in interface files, e.g. in
data D a where
MkD1 :: forall x. x -> D x
MkD2 :: forall u v. u -> v -> D v
The previous behaviour was to rename the universal variables to match
the universal variables of the data constructor. This was undesirable
because the names that end up in interface files end up mattering for
generated Haddock documentation; it's better to preserve the user-written
type variables.
Moreover, the universal variables may not have been user-written at all,
e.g. in an example such as:
type T2T = Type -> Type
data G :: T2T where
MkG :: forall x. D x
Here GHC will invent the type variable name 'a' for the first binder of
the TyCon G. We really don't want to then rename the user-written 'x'
into the generated 'a'.
- - - - -
034b2056 by sheaf at 2025-11-11T11:47:28-05:00
DataCon univ_tvs names: pick TyCon over inferred
This commit changes how we compute the names of universal type variables
in GADT data constructors. This augments the existing logic that chose
which type variable name to use, in GHC.Tc.TyCl.mkGADTVars. We continue
to prefer DataCon tv names for user-written binders, but we now prefer
TyCon tv names for inferred (non-user-written) DataCon binders.
This makes a difference in examples such as:
type (:~~:) :: k1 -> k2 -> Type
data a :~~: b where
HRefl :: a :~~: a
Before this patch, we ended up giving HRefl the type:
forall {k2}. forall (a :: k2). a :~~: a
whereas we now give it the type:
forall {k1}. forall (a :: k1). a :~~: a
The important part isn't really 'k1' or 'k2', but more that the inferred
type variable names of the DataCon can be arbitrary/unpredictable (as
they are chosen by GHC and depend on how unification proceeds), so it's
much better to use the more predictable TyCon type variable names.
- - - - -
95078d00 by sheaf at 2025-11-11T11:47:28-05:00
Backpack Rename: use explicit record construction
This commit updates the Backpack boilerplate in GHC.Iface.Rename to
use explicit record construction rather than record update. This makes
sure that the code stays up to date when the underlying constructors
change (e.g. new fields are added). The rationale is further explained
in Note [Prefer explicit record construction].
- - - - -
2bf36263 by sheaf at 2025-11-11T11:47:28-05:00
Store # eta binders in TyCon and use for Haddock
This commit stores the number of TyCon binders that were introduced by
eta-expansion (by the function GHC.Tc.Gen.HsType.splitTyConKind).
This is then used to pretty-print the TyCon as the user wrote it, e.g.
for
type Effect :: (Type -> Type) -> Type -> Type
data State s :: Effect where {..} -- arity 3
GHC will eta-expand the data declaration to
data State s a b where {..}
but also store in the 'TyCon' that the number of binders introduced by
this eta expansion is 2. This allows us, in
'Haddock.Convert.synifyTyConKindSig', to recover the original user-written
syntax, preserving the user's intent in Haddock documentation.
See Note [Inline kind signatures with GADTSyntax] in Haddock.Convert.
- - - - -
6c91582f by Matthew Pickering at 2025-11-11T11:48:12-05:00
driver: Properly handle errors during LinkNode steps
Previously we were not properly catching errors during the LinkNode step
(see T9930fail test).
This is fixed by wrapping the `LinkNode` action in `wrapAction`, the
same handler which is used for module compilation.
Fixes #26496
- - - - -
e1e1eb32 by Matthew Pickering at 2025-11-11T11:48:54-05:00
driver: Remove unecessary call to hscInsertHPT
This call was left-over from e9445c013fbccf9318739ca3d095a3e0a2e1be8a
If you follow the functions which call `upsweep_mod`, they immediately
add the interface to the HomePackageTable when `upsweep_mod` returns.
- - - - -
b22777d4 by ARATA Mizuki at 2025-11-11T11:49:44-05:00
LLVM backend: Pass the +evex512 attribute to LLVM 18+ if -mavx512f is set
The newer LLVM requires the +evex512 attribute to enable use of ZMM registers.
LLVM exhibits a backward-compatible behavior if the cpu is `x86-64`, but not if `penryn`.
Therefore, on macOS, where the cpu is set to `penryn`, we need to explicitly pass +evex512.
Fixes #26410
- - - - -
6ead7d06 by Vladislav Zavialov at 2025-11-11T11:50:26-05:00
Comments only in GHC.Parser.PostProcess.Haddock
Remove outdated Note [Register keyword location], as the issue it describes
was addressed by commit 05eb50dff2fcc78d025e77b9418ddb369db49b9f.
- - - - -
43fa8be8 by sheaf at 2025-11-11T11:51:18-05:00
localRegistersConflict: account for assignment LHS
This commit fixes a serious oversight in GHC.Cmm.Sink.conflicts,
specifically the code that computes which local registers conflict
between an assignment and a Cmm statement.
If we have:
assignment: <local_reg> = <expr>
node: <local_reg> = <other_expr>
then clearly the two conflict, because we cannot move one statement past
the other, as they assign two different values to the same local
register. (Recall that 'conflicts (local_reg,expr) node' is False if and
only if the assignment 'local_reg = expr' can be safely commuted past
the statement 'node'.)
The fix is to update 'GHC.Cmm.Sink.localRegistersConflict' to take into
account the following two situations:
(1) 'node' defines the LHS local register of the assignment,
(2) 'node' defines a local register used in the RHS of the assignment.
The bug is precisely that we were previously missing condition (1).
Fixes #26550
- - - - -
79dfcfe0 by sheaf at 2025-11-11T11:51:18-05:00
Update assigned register format when spilling
When we come to spilling a register to put new data into it, in
GHC.CmmToAsm.Reg.Linear.allocRegsAndSpill_spill, we need to:
1. Spill the data currently in the register. That is, do a spill
with a format that matches what's currently in the register.
2. Update the register assignment, allocating a virtual register to
this real register, but crucially **updating the format** of this
assignment.
Due to shadowing in the Haskell code for allocRegsAndSpill_spill, we
were mistakenly re-using the old format. This could lead to a situation
where:
a. We were using xmm6 to store a Double#.
b. We want to store a DoubleX2# into xmm6, so we spill the current
content of xmm6 to the stack using a scalar move (correct).
c. We update the register assignment, but we fail to update the format
of the assignment, so we continue to think that xmm6 stores a
Double# and not a DoubleX2#.
d. Later on, we need to spill xmm6 because it is getting clobbered by
another instruction. We then decide to only spill the lower 64 bits
of the register, because we still think that xmm6 only stores a
Double# and not a DoubleX2#.
Fixes #26542
- - - - -
aada5db9 by ARATA Mizuki at 2025-11-11T11:52:07-05:00
Fix the order of spill/reload instructions
The AArch64 NCG could emit multiple instructions for a single spill/reload,
but their order was not consistent between the definition and a use.
Fixes #26537
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
64ec82ff by Andreas Klebinger at 2025-11-11T11:52:48-05:00
Add hpc to release script
- - - - -
741da00c by Ben Gamari at 2025-11-12T03:38:20-05:00
template-haskell: Better describe getQ semantics
Clarify that the state is a type-indexed map, as suggested by #26484.
- - - - -
8b080e04 by ARATA Mizuki at 2025-11-12T03:39:11-05:00
Fix incorrect markups in the User's Guide
* Correct markup for C--: "C-\-" in reST
* Fix internal links
* Fix code highlighting
* Fix inline code: Use ``code`` rather than `code`
* Remove extra backslashes
Fixes #16812
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
a00840ea by Simon Peyton Jones at 2025-11-14T15:23:56+00:00
Make TYPE and CONSTRAINT apart again
This patch finally fixes #24279.
* The story started with #11715
* Then #21623 articulated a plan, which made Type and Constraint
not-apart; a horrible hack but it worked. The main patch was
commit 778c6adca2c995cd8a1b84394d4d5ca26b915dac
Author: Simon Peyton Jones <simonpj(a)microsoft.com>
Date: Wed Nov 9 10:33:22 2022 +0000
Type vs Constraint: finally nailed
* #24279 reported a bug in the above big commit; this small patch fixes it
commit af6932d6c068361c6ae300d52e72fbe13f8e1f18
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jan 8 10:49:49 2024 +0000
Make TYPE and CONSTRAINT not-apart
Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty
which is supposed to make TYPE and CONSTRAINT be not-apart.
* Then !10479 implemented "unary classes".
* That change in turn allows us to make Type and Constraint apart again,
cleaning up the compiler and allowing a little bit more expressiveness.
It fixes the original hope in #24279, namely that `Type` and `Constraint`
should be distinct throughout.
- - - - -
c0a1e574 by Georgios Karachalias at 2025-11-15T05:14:31-05:00
Report all missing modules with -M
We now report all missing modules at once in GHC.Driver.Makefile.processDeps,
as opposed to only reporting a single missing module. Fixes #26551.
- - - - -
c9fa3449 by Sylvain Henry at 2025-11-15T05:15:26-05:00
JS: fix array index for registers
We used to store R32 in h$regs[-1]. While it's correct in JavaScript,
fix this to store R32 in h$regs[0] instead.
- - - - -
9e469909 by Sylvain Henry at 2025-11-15T05:15:26-05:00
JS: support more than 128 registers (#26558)
The JS backend only supported 128 registers (JS variables/array slots
used to pass function arguments). It failed in T26537 when 129
registers were required.
This commit adds support for more than 128 registers: it is now limited to
maxBound :: Int (compiler's Int). If we ever go above this threshold the
compiler now panics with a more descriptive message.
A few built-in JS functions were assuming 128 registers and have been
rewritten to use loops. Note that loops are only used for "high"
registers that are stored in an array: the 31 "low" registers are still
handled with JS global variables and with explicit switch-cases to
maintain good performance in the most common cases (i.e. few registers
used). Adjusting the number of low registers is now easy: just one
constant to adjust (GHC.StgToJS.Regs.lowRegsCount).
No new test added: T26537 is used as a regression test instead.
- - - - -
0a64a78b by Sven Tennie at 2025-11-15T20:31:10-05:00
AArch64: Simplify CmmAssign and CmmStore
The special handling for floats was fake: The general case is always
used. So, the additional code path isn't needed (and only adds
complexity for the reader.)
- - - - -
15b311be by sheaf at 2025-11-15T20:32:02-05:00
SimpleOpt: refactor & push coercions into lambdas
This commit improves the simple optimiser (in GHC.Core.SimpleOpt)
in a couple of ways:
- The logic to push coercion lambdas is shored up.
The function 'pushCoercionIntoLambda' used to be called in 'finish_app',
but this meant we could not continue to optimise the program after
performing this transformation.
Now, we call 'pushCoercionIntoLambda' as part of 'simple_app'.
Doing so can be important when dealing with unlifted newtypes,
as explained in Note [Desugaring unlifted newtypes].
- The code is re-structured to avoid duplication and out-of-sync
code paths.
Now, 'simple_opt_expr' defers to 'simple_app' for the 'App', 'Var',
'Cast' and 'Lam' cases. This means all the logic for those is
centralised in a single place (e.g. the 'go_lam' helper function).
To do this, the general structure is brought a bit closer to the
full-blown simplifier, with a notion of 'continuation'
(see 'SimpleContItem').
This commit also modifies GHC.Core.Opt.Arity.pushCoercionIntoLambda to
apply a substitution (a slight generalisation of its existing implementation).
- - - - -
b33284c7 by sheaf at 2025-11-15T20:32:02-05:00
Improve typechecking of data constructors
This commit changes the way in which we perform typecheck data
constructors, in particular how we make multiplicities line up.
Now, impedance matching occurs as part of the existing subsumption
machinery. See the revamped Note [Typechecking data constructors] in
GHC.Tc.Gen.App, as well as Note [Polymorphisation of linear fields]
in GHC.Core.Multiplicity.
This allows us to get rid of a fair amount of hacky code that was
added with the introduction of LinearTypes; in particular the logic of
GHC.Tc.Gen.Head.tcInferDataCon.
-------------------------
Metric Decrease:
T10421
T14766
T15164
T15703
T19695
T5642
T9630
WWRec
-------------------------
- - - - -
b6faf5d0 by sheaf at 2025-11-15T20:32:02-05:00
Handle unsaturated rep-poly newtypes
This commit allows GHC to handle unsaturated occurrences of unlifted
newtype constructors. The plan is detailed in
Note [Eta-expanding rep-poly unlifted newtypes]
in GHC.Tc.Utils.Concrete: for unsaturated unlifted newtypes, we perform
the appropriate representation-polymorphism check in tcInstFun.
- - - - -
682bf979 by Mike Pilgrem at 2025-11-16T16:44:14+00:00
Fix #26293 Valid stack.yaml for hadrian
- - - - -
acc70c3a by Simon Peyton Jones at 2025-11-18T16:21:20-05:00
Fix a bug in defaulting
Addresses #26582
Defaulting was doing some unification but then failing to
iterate. Silly.
I discovered that the main solver was unnecessarily iterating even
if there was a unification for an /outer/ unification variable, so
I fixed that too.
- - - - -
c12fa73e by Simon Peyton Jones at 2025-11-19T02:55:01-05:00
Make PmLit be in Ord, and use it in Map
This MR addresses #26514, by changing from
data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
to
data PmAltConSet = PACS !(UniqDSet ConLike) !(Map PmLit PmLit)
This matters when doing pattern-match overlap checking, when there
is a very large set of patterns. For most programs it makes
no difference at all.
For the N=5000 case of the repro case in #26514, compiler
mutator time (with `-fno-code`) goes from 1.9s to 0.43s.
All for the price for an Ord instance for PmLit
- - - - -
41b84f40 by sheaf at 2025-11-19T02:55:52-05:00
Add passing tests for #26311 and #26072
This commit adds two tests cases that now pass since landing the changes
to typechecking of data constructors in b33284c7.
Fixes #26072 #26311
- - - - -
1faa758a by sheaf at 2025-11-19T02:55:52-05:00
mkCast: weaken bad cast warning for multiplicity
This commit weakens the warning message emitted when constructing a bad
cast in mkCast to ignore multiplicity.
Justification: since b33284c7, GHC uses sub-multiplicity coercions to
typecheck data constructors. The coercion optimiser is free to discard
these coercions, both for performance reasons, and because GHC's Core
simplifier does not (yet) preserve linearity.
We thus weaken 'mkCast' to use 'eqTypeIgnoringMultiplicity' instead of
'eqType', to avoid getting many spurious warnings about mismatched
multiplicities.
- - - - -
277d947b by Simon Peyton Jones at 2025-11-19T09:22:17+00:00
Better injectivity for closed type families
The idea is in #23162.
more docs needed
- - - - -
36ec5f41 by Simon Peyton Jones at 2025-11-19T09:22:17+00:00
Wibbles
- - - - -
8e8c0f06 by Simon Peyton Jones at 2025-11-19T09:22:17+00:00
Only do top-level fundeps if there are no local ones
- - - - -
0833f333 by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
More wibbles
- - - - -
5a7b9503 by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
better still
- - - - -
78119961 by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
WIP [skip ci]
improving the injectivity calculation
- - - - -
b3f9985c by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
Solve Yikes1 and Yikes2
- - - - -
382894f6 by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
Wibble unused variable
- - - - -
88c932bb by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
Better
Fix Yikes 3
Ensure we do F a ~ F b for families with no eqns
- - - - -
af722cf5 by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
Refine Yikes 3
- - - - -
b653d951 by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
More good stuff
- - - - -
f2bab720 by Simon Peyton Jones at 2025-11-19T09:22:18+00:00
Wibbles
Fix to niFixSubst
- - - - -
b110ec03 by Simon Peyton Jones at 2025-11-19T10:15:56+00:00
Add missing stderr file
- - - - -
221 changed files:
- .gitlab/rel_eng/upload_ghc_libs.py
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Builtin/Types/Literals.hs
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Cmm/Sink.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/Reg/Linear.hs
- compiler/GHC/CmmToAsm/Reg/Liveness.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/DataCon.hs
- compiler/GHC/Core/FamInstEnv.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Multiplicity.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/RoughMap.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Utils.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/StgToJS/Apply.hs
- compiler/GHC/StgToJS/Expr.hs
- compiler/GHC/StgToJS/Regs.hs
- compiler/GHC/StgToJS/Rts/Rts.hs
- compiler/GHC/StgToJS/Rts/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Build.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/SourceText.hs
- compiler/GHC/Types/TyThing.hs
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/bugs.rst
- docs/users_guide/debug-info.rst
- docs/users_guide/debugging.rst
- docs/users_guide/extending_ghc.rst
- docs/users_guide/exts/arrows.rst
- docs/users_guide/exts/derive_any_class.rst
- docs/users_guide/exts/deriving_extra.rst
- docs/users_guide/exts/deriving_inferred.rst
- docs/users_guide/exts/deriving_strategies.rst
- docs/users_guide/exts/gadt.rst
- docs/users_guide/exts/generics.rst
- docs/users_guide/exts/overloaded_labels.rst
- docs/users_guide/exts/overloaded_strings.rst
- docs/users_guide/exts/pattern_synonyms.rst
- docs/users_guide/exts/poly_kinds.rst
- docs/users_guide/exts/primitives.rst
- docs/users_guide/exts/rank_polymorphism.rst
- docs/users_guide/exts/rebindable_syntax.rst
- docs/users_guide/exts/required_type_arguments.rst
- docs/users_guide/exts/scoped_type_variables.rst
- docs/users_guide/exts/standalone_deriving.rst
- docs/users_guide/exts/template_haskell.rst
- docs/users_guide/exts/tuple_sections.rst
- docs/users_guide/exts/type_data.rst
- docs/users_guide/exts/type_defaulting.rst
- docs/users_guide/gone_wrong.rst
- docs/users_guide/hints.rst
- docs/users_guide/javascript.rst
- docs/users_guide/phases.rst
- docs/users_guide/profiling.rst
- docs/users_guide/separate_compilation.rst
- docs/users_guide/using.rst
- docs/users_guide/wasm.rst
- docs/users_guide/win32-dlls.rst
- hadrian/stack.yaml
- hadrian/stack.yaml.lock
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- linters/lint-codes/LintCodes/Static.hs
- testsuite/tests/backpack/should_fail/T19244a.stderr
- + testsuite/tests/codeGen/should_run/T26537.hs
- + testsuite/tests/codeGen/should_run/T26537.stdout
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/dependent/should_fail/T11334b.stderr
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/driver/Makefile
- + testsuite/tests/driver/T26551.hs
- + testsuite/tests/driver/T26551.stderr
- testsuite/tests/driver/all.T
- testsuite/tests/generics/T10604/T10604_deriving.stderr
- testsuite/tests/ghc-e/should_fail/T9930fail.stderr
- testsuite/tests/ghc-e/should_fail/all.T
- testsuite/tests/ghci.debugger/scripts/print012.stdout
- testsuite/tests/ghci/scripts/T10321.stdout
- testsuite/tests/ghci/scripts/T24459.stdout
- testsuite/tests/ghci/scripts/T7730.stdout
- testsuite/tests/ghci/scripts/T8959b.stderr
- testsuite/tests/ghci/scripts/ghci051.stderr
- testsuite/tests/ghci/scripts/ghci065.stdout
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/indexed-types/should_compile/CEqCanOccursCheck.hs
- testsuite/tests/indexed-types/should_compile/T12538.stderr
- testsuite/tests/indexed-types/should_fail/T12522a.hs
- testsuite/tests/indexed-types/should_fail/T21092.hs
- − testsuite/tests/indexed-types/should_fail/T21092.stderr
- testsuite/tests/indexed-types/should_fail/all.T
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- + testsuite/tests/linear/should_compile/LinearEtaExpansions.hs
- testsuite/tests/linear/should_compile/all.T
- testsuite/tests/linear/should_fail/TypeClass.hs
- testsuite/tests/linear/should_fail/TypeClass.stderr
- testsuite/tests/linear/should_run/LinearGhci.stdout
- + testsuite/tests/linear/should_run/T26311.hs
- + testsuite/tests/linear/should_run/T26311.stdout
- testsuite/tests/linear/should_run/all.T
- testsuite/tests/numeric/should_compile/T16402.stderr-ws-64
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
- testsuite/tests/rename/should_fail/rnfail055.stderr
- testsuite/tests/rep-poly/RepPolyCase1.stderr
- − testsuite/tests/rep-poly/RepPolyCase2.stderr
- testsuite/tests/rep-poly/RepPolyRule3.stderr
- testsuite/tests/rep-poly/RepPolyTuple4.stderr
- testsuite/tests/rep-poly/T13233.stderr
- − testsuite/tests/rep-poly/T17021.stderr
- testsuite/tests/rep-poly/T20363b.stderr
- − testsuite/tests/rep-poly/T21650_a.stderr
- − testsuite/tests/rep-poly/T21650_b.stderr
- + testsuite/tests/rep-poly/T26072.hs
- + testsuite/tests/rep-poly/T26072b.hs
- testsuite/tests/rep-poly/UnliftedNewtypesLevityBinder.stderr
- testsuite/tests/rep-poly/all.T
- testsuite/tests/saks/should_compile/saks023.stdout
- testsuite/tests/saks/should_compile/saks034.stdout
- testsuite/tests/saks/should_compile/saks035.stdout
- testsuite/tests/showIface/Makefile
- + testsuite/tests/showIface/T26246a.hs
- + testsuite/tests/showIface/T26246a.stdout
- testsuite/tests/showIface/all.T
- + testsuite/tests/simd/should_run/T26410_ffi.hs
- + testsuite/tests/simd/should_run/T26410_ffi.stdout
- + testsuite/tests/simd/should_run/T26410_ffi_c.c
- + testsuite/tests/simd/should_run/T26410_prim.hs
- + testsuite/tests/simd/should_run/T26410_prim.stdout
- + testsuite/tests/simd/should_run/T26542.hs
- + testsuite/tests/simd/should_run/T26542.stdout
- + testsuite/tests/simd/should_run/T26550.hs
- + testsuite/tests/simd/should_run/T26550.stdout
- testsuite/tests/simd/should_run/all.T
- testsuite/tests/typecheck/T16127/T16127.stderr
- testsuite/tests/typecheck/should_compile/T22560d.stdout
- + testsuite/tests/typecheck/should_compile/T26582.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T15629.stderr
- testsuite/tests/typecheck/should_fail/T15883e.stderr
- + testsuite/tests/typecheck/should_fail/T23162b.hs
- + testsuite/tests/typecheck/should_fail/T23162b.stderr
- + testsuite/tests/typecheck/should_fail/T23162c.hs
- + testsuite/tests/typecheck/should_fail/T23162d.hs
- testsuite/tests/typecheck/should_fail/T2414.stderr
- testsuite/tests/typecheck/should_fail/T24279.hs
- − testsuite/tests/typecheck/should_fail/T24279.stderr
- testsuite/tests/typecheck/should_fail/T2534.stderr
- testsuite/tests/typecheck/should_fail/T7264.stderr
- testsuite/tests/typecheck/should_fail/all.T
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1050.html
- + utils/haddock/html-test/ref/Bug26246.html
- utils/haddock/html-test/ref/Bug85.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/BundledPatterns.html
- utils/haddock/html-test/ref/BundledPatterns2.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/GADTRecords.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/PromotedTypes.html
- + utils/haddock/html-test/src/Bug26246.hs
- utils/haddock/hypsrc-test/ref/src/Classes.html
- utils/haddock/hypsrc-test/ref/src/Quasiquoter.html
- utils/haddock/latex-test/ref/LinearTypes/LinearTypes.tex
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dd4dc342d7dcc697d7c438250aeba1…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dd4dc342d7dcc697d7c438250aeba1…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/26543] 29 commits: Preserve user-written kinds in data declarations
by Simon Peyton Jones (@simonpj) 19 Nov '25
by Simon Peyton Jones (@simonpj) 19 Nov '25
19 Nov '25
Simon Peyton Jones pushed to branch wip/26543 at Glasgow Haskell Compiler / GHC
Commits:
3c2f4bb4 by sheaf at 2025-11-11T11:47:28-05:00
Preserve user-written kinds in data declarations
This commit ensures that we preserve the user-written kind for data
declarations, e.g. in
type T2T = Type -> Type
type D :: T2T
data D a where { .. }
that we preserve the user-written kind of D as 'T2T', instead of
expanding the type synonym 'T2T' during kind checking.
We do this by storing 'tyConKind' separately from 'tyConResKind'. This
means that 'tyConKind' is not necessarily equal to
'mkTyConKind binders res_kind', as e.g. in the above example the former
is 'T2T' while the latter is 'Type -> Type'.
This is explained in Note [Preserve user-written TyCon kind] in GHC.Core.TyCon.
This is particularly important for Haddock, as the kinds stored in
interface files affect the generated documentation, and we want to
preserve the user-written types as much as possible.
- - - - -
19859584 by sheaf at 2025-11-11T11:47:28-05:00
Store user-written datacon tvs in interface files
This commit ensures we store the user-written quantified type variables
of data constructors in interface files, e.g. in
data D a where
MkD1 :: forall x. x -> D x
MkD2 :: forall u v. u -> v -> D v
The previous behaviour was to rename the universal variables to match
the universal variables of the data constructor. This was undesirable
because the names that end up in interface files end up mattering for
generated Haddock documentation; it's better to preserve the user-written
type variables.
Moreover, the universal variables may not have been user-written at all,
e.g. in an example such as:
type T2T = Type -> Type
data G :: T2T where
MkG :: forall x. D x
Here GHC will invent the type variable name 'a' for the first binder of
the TyCon G. We really don't want to then rename the user-written 'x'
into the generated 'a'.
- - - - -
034b2056 by sheaf at 2025-11-11T11:47:28-05:00
DataCon univ_tvs names: pick TyCon over inferred
This commit changes how we compute the names of universal type variables
in GADT data constructors. This augments the existing logic that chose
which type variable name to use, in GHC.Tc.TyCl.mkGADTVars. We continue
to prefer DataCon tv names for user-written binders, but we now prefer
TyCon tv names for inferred (non-user-written) DataCon binders.
This makes a difference in examples such as:
type (:~~:) :: k1 -> k2 -> Type
data a :~~: b where
HRefl :: a :~~: a
Before this patch, we ended up giving HRefl the type:
forall {k2}. forall (a :: k2). a :~~: a
whereas we now give it the type:
forall {k1}. forall (a :: k1). a :~~: a
The important part isn't really 'k1' or 'k2', but more that the inferred
type variable names of the DataCon can be arbitrary/unpredictable (as
they are chosen by GHC and depend on how unification proceeds), so it's
much better to use the more predictable TyCon type variable names.
- - - - -
95078d00 by sheaf at 2025-11-11T11:47:28-05:00
Backpack Rename: use explicit record construction
This commit updates the Backpack boilerplate in GHC.Iface.Rename to
use explicit record construction rather than record update. This makes
sure that the code stays up to date when the underlying constructors
change (e.g. new fields are added). The rationale is further explained
in Note [Prefer explicit record construction].
- - - - -
2bf36263 by sheaf at 2025-11-11T11:47:28-05:00
Store # eta binders in TyCon and use for Haddock
This commit stores the number of TyCon binders that were introduced by
eta-expansion (by the function GHC.Tc.Gen.HsType.splitTyConKind).
This is then used to pretty-print the TyCon as the user wrote it, e.g.
for
type Effect :: (Type -> Type) -> Type -> Type
data State s :: Effect where {..} -- arity 3
GHC will eta-expand the data declaration to
data State s a b where {..}
but also store in the 'TyCon' that the number of binders introduced by
this eta expansion is 2. This allows us, in
'Haddock.Convert.synifyTyConKindSig', to recover the original user-written
syntax, preserving the user's intent in Haddock documentation.
See Note [Inline kind signatures with GADTSyntax] in Haddock.Convert.
- - - - -
6c91582f by Matthew Pickering at 2025-11-11T11:48:12-05:00
driver: Properly handle errors during LinkNode steps
Previously we were not properly catching errors during the LinkNode step
(see T9930fail test).
This is fixed by wrapping the `LinkNode` action in `wrapAction`, the
same handler which is used for module compilation.
Fixes #26496
- - - - -
e1e1eb32 by Matthew Pickering at 2025-11-11T11:48:54-05:00
driver: Remove unecessary call to hscInsertHPT
This call was left-over from e9445c013fbccf9318739ca3d095a3e0a2e1be8a
If you follow the functions which call `upsweep_mod`, they immediately
add the interface to the HomePackageTable when `upsweep_mod` returns.
- - - - -
b22777d4 by ARATA Mizuki at 2025-11-11T11:49:44-05:00
LLVM backend: Pass the +evex512 attribute to LLVM 18+ if -mavx512f is set
The newer LLVM requires the +evex512 attribute to enable use of ZMM registers.
LLVM exhibits a backward-compatible behavior if the cpu is `x86-64`, but not if `penryn`.
Therefore, on macOS, where the cpu is set to `penryn`, we need to explicitly pass +evex512.
Fixes #26410
- - - - -
6ead7d06 by Vladislav Zavialov at 2025-11-11T11:50:26-05:00
Comments only in GHC.Parser.PostProcess.Haddock
Remove outdated Note [Register keyword location], as the issue it describes
was addressed by commit 05eb50dff2fcc78d025e77b9418ddb369db49b9f.
- - - - -
43fa8be8 by sheaf at 2025-11-11T11:51:18-05:00
localRegistersConflict: account for assignment LHS
This commit fixes a serious oversight in GHC.Cmm.Sink.conflicts,
specifically the code that computes which local registers conflict
between an assignment and a Cmm statement.
If we have:
assignment: <local_reg> = <expr>
node: <local_reg> = <other_expr>
then clearly the two conflict, because we cannot move one statement past
the other, as they assign two different values to the same local
register. (Recall that 'conflicts (local_reg,expr) node' is False if and
only if the assignment 'local_reg = expr' can be safely commuted past
the statement 'node'.)
The fix is to update 'GHC.Cmm.Sink.localRegistersConflict' to take into
account the following two situations:
(1) 'node' defines the LHS local register of the assignment,
(2) 'node' defines a local register used in the RHS of the assignment.
The bug is precisely that we were previously missing condition (1).
Fixes #26550
- - - - -
79dfcfe0 by sheaf at 2025-11-11T11:51:18-05:00
Update assigned register format when spilling
When we come to spilling a register to put new data into it, in
GHC.CmmToAsm.Reg.Linear.allocRegsAndSpill_spill, we need to:
1. Spill the data currently in the register. That is, do a spill
with a format that matches what's currently in the register.
2. Update the register assignment, allocating a virtual register to
this real register, but crucially **updating the format** of this
assignment.
Due to shadowing in the Haskell code for allocRegsAndSpill_spill, we
were mistakenly re-using the old format. This could lead to a situation
where:
a. We were using xmm6 to store a Double#.
b. We want to store a DoubleX2# into xmm6, so we spill the current
content of xmm6 to the stack using a scalar move (correct).
c. We update the register assignment, but we fail to update the format
of the assignment, so we continue to think that xmm6 stores a
Double# and not a DoubleX2#.
d. Later on, we need to spill xmm6 because it is getting clobbered by
another instruction. We then decide to only spill the lower 64 bits
of the register, because we still think that xmm6 only stores a
Double# and not a DoubleX2#.
Fixes #26542
- - - - -
aada5db9 by ARATA Mizuki at 2025-11-11T11:52:07-05:00
Fix the order of spill/reload instructions
The AArch64 NCG could emit multiple instructions for a single spill/reload,
but their order was not consistent between the definition and a use.
Fixes #26537
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
64ec82ff by Andreas Klebinger at 2025-11-11T11:52:48-05:00
Add hpc to release script
- - - - -
741da00c by Ben Gamari at 2025-11-12T03:38:20-05:00
template-haskell: Better describe getQ semantics
Clarify that the state is a type-indexed map, as suggested by #26484.
- - - - -
8b080e04 by ARATA Mizuki at 2025-11-12T03:39:11-05:00
Fix incorrect markups in the User's Guide
* Correct markup for C--: "C-\-" in reST
* Fix internal links
* Fix code highlighting
* Fix inline code: Use ``code`` rather than `code`
* Remove extra backslashes
Fixes #16812
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
a00840ea by Simon Peyton Jones at 2025-11-14T15:23:56+00:00
Make TYPE and CONSTRAINT apart again
This patch finally fixes #24279.
* The story started with #11715
* Then #21623 articulated a plan, which made Type and Constraint
not-apart; a horrible hack but it worked. The main patch was
commit 778c6adca2c995cd8a1b84394d4d5ca26b915dac
Author: Simon Peyton Jones <simonpj(a)microsoft.com>
Date: Wed Nov 9 10:33:22 2022 +0000
Type vs Constraint: finally nailed
* #24279 reported a bug in the above big commit; this small patch fixes it
commit af6932d6c068361c6ae300d52e72fbe13f8e1f18
Author: Simon Peyton Jones <simon.peytonjones(a)gmail.com>
Date: Mon Jan 8 10:49:49 2024 +0000
Make TYPE and CONSTRAINT not-apart
Issue #24279 showed up a bug in the logic in GHC.Core.Unify.unify_ty
which is supposed to make TYPE and CONSTRAINT be not-apart.
* Then !10479 implemented "unary classes".
* That change in turn allows us to make Type and Constraint apart again,
cleaning up the compiler and allowing a little bit more expressiveness.
It fixes the original hope in #24279, namely that `Type` and `Constraint`
should be distinct throughout.
- - - - -
c0a1e574 by Georgios Karachalias at 2025-11-15T05:14:31-05:00
Report all missing modules with -M
We now report all missing modules at once in GHC.Driver.Makefile.processDeps,
as opposed to only reporting a single missing module. Fixes #26551.
- - - - -
c9fa3449 by Sylvain Henry at 2025-11-15T05:15:26-05:00
JS: fix array index for registers
We used to store R32 in h$regs[-1]. While it's correct in JavaScript,
fix this to store R32 in h$regs[0] instead.
- - - - -
9e469909 by Sylvain Henry at 2025-11-15T05:15:26-05:00
JS: support more than 128 registers (#26558)
The JS backend only supported 128 registers (JS variables/array slots
used to pass function arguments). It failed in T26537 when 129
registers were required.
This commit adds support for more than 128 registers: it is now limited to
maxBound :: Int (compiler's Int). If we ever go above this threshold the
compiler now panics with a more descriptive message.
A few built-in JS functions were assuming 128 registers and have been
rewritten to use loops. Note that loops are only used for "high"
registers that are stored in an array: the 31 "low" registers are still
handled with JS global variables and with explicit switch-cases to
maintain good performance in the most common cases (i.e. few registers
used). Adjusting the number of low registers is now easy: just one
constant to adjust (GHC.StgToJS.Regs.lowRegsCount).
No new test added: T26537 is used as a regression test instead.
- - - - -
0a64a78b by Sven Tennie at 2025-11-15T20:31:10-05:00
AArch64: Simplify CmmAssign and CmmStore
The special handling for floats was fake: The general case is always
used. So, the additional code path isn't needed (and only adds
complexity for the reader.)
- - - - -
15b311be by sheaf at 2025-11-15T20:32:02-05:00
SimpleOpt: refactor & push coercions into lambdas
This commit improves the simple optimiser (in GHC.Core.SimpleOpt)
in a couple of ways:
- The logic to push coercion lambdas is shored up.
The function 'pushCoercionIntoLambda' used to be called in 'finish_app',
but this meant we could not continue to optimise the program after
performing this transformation.
Now, we call 'pushCoercionIntoLambda' as part of 'simple_app'.
Doing so can be important when dealing with unlifted newtypes,
as explained in Note [Desugaring unlifted newtypes].
- The code is re-structured to avoid duplication and out-of-sync
code paths.
Now, 'simple_opt_expr' defers to 'simple_app' for the 'App', 'Var',
'Cast' and 'Lam' cases. This means all the logic for those is
centralised in a single place (e.g. the 'go_lam' helper function).
To do this, the general structure is brought a bit closer to the
full-blown simplifier, with a notion of 'continuation'
(see 'SimpleContItem').
This commit also modifies GHC.Core.Opt.Arity.pushCoercionIntoLambda to
apply a substitution (a slight generalisation of its existing implementation).
- - - - -
b33284c7 by sheaf at 2025-11-15T20:32:02-05:00
Improve typechecking of data constructors
This commit changes the way in which we perform typecheck data
constructors, in particular how we make multiplicities line up.
Now, impedance matching occurs as part of the existing subsumption
machinery. See the revamped Note [Typechecking data constructors] in
GHC.Tc.Gen.App, as well as Note [Polymorphisation of linear fields]
in GHC.Core.Multiplicity.
This allows us to get rid of a fair amount of hacky code that was
added with the introduction of LinearTypes; in particular the logic of
GHC.Tc.Gen.Head.tcInferDataCon.
-------------------------
Metric Decrease:
T10421
T14766
T15164
T15703
T19695
T5642
T9630
WWRec
-------------------------
- - - - -
b6faf5d0 by sheaf at 2025-11-15T20:32:02-05:00
Handle unsaturated rep-poly newtypes
This commit allows GHC to handle unsaturated occurrences of unlifted
newtype constructors. The plan is detailed in
Note [Eta-expanding rep-poly unlifted newtypes]
in GHC.Tc.Utils.Concrete: for unsaturated unlifted newtypes, we perform
the appropriate representation-polymorphism check in tcInstFun.
- - - - -
682bf979 by Mike Pilgrem at 2025-11-16T16:44:14+00:00
Fix #26293 Valid stack.yaml for hadrian
- - - - -
acc70c3a by Simon Peyton Jones at 2025-11-18T16:21:20-05:00
Fix a bug in defaulting
Addresses #26582
Defaulting was doing some unification but then failing to
iterate. Silly.
I discovered that the main solver was unnecessarily iterating even
if there was a unification for an /outer/ unification variable, so
I fixed that too.
- - - - -
c12fa73e by Simon Peyton Jones at 2025-11-19T02:55:01-05:00
Make PmLit be in Ord, and use it in Map
This MR addresses #26514, by changing from
data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
to
data PmAltConSet = PACS !(UniqDSet ConLike) !(Map PmLit PmLit)
This matters when doing pattern-match overlap checking, when there
is a very large set of patterns. For most programs it makes
no difference at all.
For the N=5000 case of the repro case in #26514, compiler
mutator time (with `-fno-code`) goes from 1.9s to 0.43s.
All for the price for an Ord instance for PmLit
- - - - -
41b84f40 by sheaf at 2025-11-19T02:55:52-05:00
Add passing tests for #26311 and #26072
This commit adds two tests cases that now pass since landing the changes
to typechecking of data constructors in b33284c7.
Fixes #26072 #26311
- - - - -
1faa758a by sheaf at 2025-11-19T02:55:52-05:00
mkCast: weaken bad cast warning for multiplicity
This commit weakens the warning message emitted when constructing a bad
cast in mkCast to ignore multiplicity.
Justification: since b33284c7, GHC uses sub-multiplicity coercions to
typecheck data constructors. The coercion optimiser is free to discard
these coercions, both for performance reasons, and because GHC's Core
simplifier does not (yet) preserve linearity.
We thus weaken 'mkCast' to use 'eqTypeIgnoringMultiplicity' instead of
'eqType', to avoid getting many spurious warnings about mismatched
multiplicities.
- - - - -
85877603 by Simon Peyton Jones at 2025-11-19T10:13:23+00:00
Tidy up occurs-checking a little
In investigating #26543, I re-discovered the wobbliness around doing an
occurs check when there is a coercion hole in the RHS type. Moreover
I found that the two occurs-checkers, in Unify.simpleOccursCheck and
Unify.checkTyEqRhs didn't even agree about how to handle coersion holes.
This patch doesn't fully solve the issue, but it tidies it up quite a bit:
* Rewrote Note [CoercionHoles and their free variables]
in GHC.Core.TyCo.FVs
* When finding the free vars of a CoHole, always look in the kind of the hole.
(This was inconsistent before.)
See Note [CoercionHoles and their free variables]
* Make Unify.mkOccFolders look in the kind of coercion holes
* In Unify.checkCo, use `mkOccFolders` rather than `tyCoVarsOfCo`. The two
should be the same, but it's more uniform to use the same function as we
do for `simpleOccursCheck`. And maybe more efficient.
* Made the CoVar case of tyCoFVsOfCo use the same auxiliary function as the
TyVar case of tyCoFVsOfTy
* Made the CoHole case of tyCoFVsOfCo look in the kind of the coercion hole.
* Added (UQL5) to Note [QuickLook unification], to stress that the "simple
unification check" has a real effect on what it typeable with QuickLook; it
is not just a fast path.
I added a regression test for #26543. It works in HEAD but we need to be sure
that it stays working.
- - - - -
211 changed files:
- .gitlab/rel_eng/upload_ghc_libs.py
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Builtin/Types/Literals.hs
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Cmm/Sink.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/Reg/Linear.hs
- compiler/GHC/CmmToAsm/Reg/Liveness.hs
- compiler/GHC/Core.hs
- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/DataCon.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Multiplicity.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/RoughMap.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Driver/Config/Core/Lint.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/MakeFile.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Syn/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Utils.hs
- compiler/GHC/Iface/Decl.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/IfaceToCore.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/StgToJS/Apply.hs
- compiler/GHC/StgToJS/Expr.hs
- compiler/GHC/StgToJS/Regs.hs
- compiler/GHC/StgToJS/Rts/Rts.hs
- compiler/GHC/StgToJS/Rts/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Expr.hs-boot
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/Build.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Concrete.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/GHC/Types/SourceText.hs
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/bugs.rst
- docs/users_guide/debug-info.rst
- docs/users_guide/debugging.rst
- docs/users_guide/extending_ghc.rst
- docs/users_guide/exts/arrows.rst
- docs/users_guide/exts/derive_any_class.rst
- docs/users_guide/exts/deriving_extra.rst
- docs/users_guide/exts/deriving_inferred.rst
- docs/users_guide/exts/deriving_strategies.rst
- docs/users_guide/exts/gadt.rst
- docs/users_guide/exts/generics.rst
- docs/users_guide/exts/overloaded_labels.rst
- docs/users_guide/exts/overloaded_strings.rst
- docs/users_guide/exts/pattern_synonyms.rst
- docs/users_guide/exts/poly_kinds.rst
- docs/users_guide/exts/primitives.rst
- docs/users_guide/exts/rank_polymorphism.rst
- docs/users_guide/exts/rebindable_syntax.rst
- docs/users_guide/exts/required_type_arguments.rst
- docs/users_guide/exts/scoped_type_variables.rst
- docs/users_guide/exts/standalone_deriving.rst
- docs/users_guide/exts/template_haskell.rst
- docs/users_guide/exts/tuple_sections.rst
- docs/users_guide/exts/type_data.rst
- docs/users_guide/exts/type_defaulting.rst
- docs/users_guide/gone_wrong.rst
- docs/users_guide/hints.rst
- docs/users_guide/javascript.rst
- docs/users_guide/phases.rst
- docs/users_guide/profiling.rst
- docs/users_guide/separate_compilation.rst
- docs/users_guide/using.rst
- docs/users_guide/wasm.rst
- docs/users_guide/win32-dlls.rst
- hadrian/stack.yaml
- hadrian/stack.yaml.lock
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- testsuite/tests/backpack/should_fail/T19244a.stderr
- + testsuite/tests/codeGen/should_run/T26537.hs
- + testsuite/tests/codeGen/should_run/T26537.stdout
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/dependent/should_fail/T11334b.stderr
- testsuite/tests/diagnostic-codes/codes.stdout
- testsuite/tests/driver/Makefile
- + testsuite/tests/driver/T26551.hs
- + testsuite/tests/driver/T26551.stderr
- testsuite/tests/driver/all.T
- testsuite/tests/generics/T10604/T10604_deriving.stderr
- testsuite/tests/ghc-e/should_fail/T9930fail.stderr
- testsuite/tests/ghc-e/should_fail/all.T
- testsuite/tests/ghci.debugger/scripts/print012.stdout
- testsuite/tests/ghci/scripts/T10321.stdout
- testsuite/tests/ghci/scripts/T24459.stdout
- testsuite/tests/ghci/scripts/T7730.stdout
- testsuite/tests/ghci/scripts/T8959b.stderr
- testsuite/tests/ghci/scripts/ghci051.stderr
- testsuite/tests/ghci/scripts/ghci065.stdout
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- + testsuite/tests/impredicative/T26543.hs
- testsuite/tests/impredicative/all.T
- testsuite/tests/indexed-types/should_compile/T12538.stderr
- testsuite/tests/indexed-types/should_fail/T21092.hs
- − testsuite/tests/indexed-types/should_fail/T21092.stderr
- testsuite/tests/indexed-types/should_fail/all.T
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- + testsuite/tests/linear/should_compile/LinearEtaExpansions.hs
- testsuite/tests/linear/should_compile/all.T
- testsuite/tests/linear/should_fail/TypeClass.hs
- testsuite/tests/linear/should_fail/TypeClass.stderr
- testsuite/tests/linear/should_run/LinearGhci.stdout
- + testsuite/tests/linear/should_run/T26311.hs
- + testsuite/tests/linear/should_run/T26311.stdout
- testsuite/tests/linear/should_run/all.T
- testsuite/tests/numeric/should_compile/T16402.stderr-ws-64
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
- testsuite/tests/rename/should_fail/rnfail055.stderr
- testsuite/tests/rep-poly/RepPolyCase1.stderr
- − testsuite/tests/rep-poly/RepPolyCase2.stderr
- testsuite/tests/rep-poly/RepPolyRule3.stderr
- testsuite/tests/rep-poly/RepPolyTuple4.stderr
- testsuite/tests/rep-poly/T13233.stderr
- − testsuite/tests/rep-poly/T17021.stderr
- testsuite/tests/rep-poly/T20363b.stderr
- − testsuite/tests/rep-poly/T21650_a.stderr
- − testsuite/tests/rep-poly/T21650_b.stderr
- + testsuite/tests/rep-poly/T26072.hs
- + testsuite/tests/rep-poly/T26072b.hs
- testsuite/tests/rep-poly/UnliftedNewtypesLevityBinder.stderr
- testsuite/tests/rep-poly/all.T
- testsuite/tests/saks/should_compile/saks023.stdout
- testsuite/tests/saks/should_compile/saks034.stdout
- testsuite/tests/saks/should_compile/saks035.stdout
- testsuite/tests/showIface/Makefile
- + testsuite/tests/showIface/T26246a.hs
- + testsuite/tests/showIface/T26246a.stdout
- testsuite/tests/showIface/all.T
- + testsuite/tests/simd/should_run/T26410_ffi.hs
- + testsuite/tests/simd/should_run/T26410_ffi.stdout
- + testsuite/tests/simd/should_run/T26410_ffi_c.c
- + testsuite/tests/simd/should_run/T26410_prim.hs
- + testsuite/tests/simd/should_run/T26410_prim.stdout
- + testsuite/tests/simd/should_run/T26542.hs
- + testsuite/tests/simd/should_run/T26542.stdout
- + testsuite/tests/simd/should_run/T26550.hs
- + testsuite/tests/simd/should_run/T26550.stdout
- testsuite/tests/simd/should_run/all.T
- testsuite/tests/typecheck/T16127/T16127.stderr
- testsuite/tests/typecheck/should_compile/T22560d.stdout
- + testsuite/tests/typecheck/should_compile/T26582.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T15629.stderr
- testsuite/tests/typecheck/should_fail/T15883e.stderr
- testsuite/tests/typecheck/should_fail/T2414.stderr
- testsuite/tests/typecheck/should_fail/T24279.hs
- − testsuite/tests/typecheck/should_fail/T24279.stderr
- testsuite/tests/typecheck/should_fail/T2534.stderr
- testsuite/tests/typecheck/should_fail/T7264.stderr
- testsuite/tests/typecheck/should_fail/all.T
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/html-test/ref/Bug1004.html
- utils/haddock/html-test/ref/Bug1050.html
- + utils/haddock/html-test/ref/Bug26246.html
- utils/haddock/html-test/ref/Bug85.html
- utils/haddock/html-test/ref/Bug923.html
- utils/haddock/html-test/ref/BundledPatterns.html
- utils/haddock/html-test/ref/BundledPatterns2.html
- utils/haddock/html-test/ref/ConstructorPatternExport.html
- utils/haddock/html-test/ref/GADTRecords.html
- utils/haddock/html-test/ref/LinearTypes.html
- utils/haddock/html-test/ref/PromotedTypes.html
- + utils/haddock/html-test/src/Bug26246.hs
- utils/haddock/hypsrc-test/ref/src/Classes.html
- utils/haddock/hypsrc-test/ref/src/Quasiquoter.html
- utils/haddock/latex-test/ref/LinearTypes/LinearTypes.tex
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0b32d9c42f641d7b6f79099a7fd13e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0b32d9c42f641d7b6f79099a7fd13e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: Add passing tests for #26311 and #26072
by Marge Bot (@marge-bot) 19 Nov '25
by Marge Bot (@marge-bot) 19 Nov '25
19 Nov '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
41b84f40 by sheaf at 2025-11-19T02:55:52-05:00
Add passing tests for #26311 and #26072
This commit adds two tests cases that now pass since landing the changes
to typechecking of data constructors in b33284c7.
Fixes #26072 #26311
- - - - -
1faa758a by sheaf at 2025-11-19T02:55:52-05:00
mkCast: weaken bad cast warning for multiplicity
This commit weakens the warning message emitted when constructing a bad
cast in mkCast to ignore multiplicity.
Justification: since b33284c7, GHC uses sub-multiplicity coercions to
typecheck data constructors. The coercion optimiser is free to discard
these coercions, both for performance reasons, and because GHC's Core
simplifier does not (yet) preserve linearity.
We thus weaken 'mkCast' to use 'eqTypeIgnoringMultiplicity' instead of
'eqType', to avoid getting many spurious warnings about mismatched
multiplicities.
- - - - -
6 changed files:
- compiler/GHC/Core/Utils.hs
- + testsuite/tests/linear/should_run/T26311.hs
- + testsuite/tests/linear/should_run/T26311.stdout
- testsuite/tests/linear/should_run/all.T
- + testsuite/tests/rep-poly/T26072b.hs
- testsuite/tests/rep-poly/all.T
Changes:
=====================================
compiler/GHC/Core/Utils.hs
=====================================
@@ -78,7 +78,7 @@ import GHC.Core.Type as Type
import GHC.Core.Predicate( isEqPred )
import GHC.Core.Predicate( isUnaryClass )
import GHC.Core.FamInstEnv
-import GHC.Core.TyCo.Compare( eqType, eqTypeX )
+import GHC.Core.TyCo.Compare( eqType, eqTypeX, eqTypeIgnoringMultiplicity )
import GHC.Core.Coercion
import GHC.Core.Reduction
import GHC.Core.TyCon
@@ -275,7 +275,7 @@ mkCast expr co
= assertPpr (coercionRole co == Representational)
(text "coercion" <+> ppr co <+> text "passed to mkCast"
<+> ppr expr <+> text "has wrong role" <+> ppr (coercionRole co)) $
- warnPprTrace (not (coercionLKind co `eqType` exprType expr)) "Bad cast"
+ warnPprTrace (not (coercionLKind co `eqTypeIgnoringMultiplicity` exprType expr)) "Bad cast"
(vcat [ text "Coercion LHS kind does not match enclosed expression type"
, text "co:" <+> ppr co
, text "coercionLKind:" <+> ppr (coercionLKind co)
=====================================
testsuite/tests/linear/should_run/T26311.hs
=====================================
@@ -0,0 +1,23 @@
+{-# LANGUAGE MagicHash #-}
+
+module Main where
+
+import GHC.Exts ( Int# )
+
+expensive :: Int -> Int#
+expensive 0 = 2#
+expensive i = expensive (i-1)
+
+data D = MkD Int# Int
+
+f :: a -> Bool
+f _ = False
+{-# NOINLINE f #-}
+
+{-# RULES "f/MkD" forall x. f (MkD x) = True #-}
+
+bar :: Bool
+bar = f (MkD (expensive 10))
+
+main :: IO ()
+main = print bar
=====================================
testsuite/tests/linear/should_run/T26311.stdout
=====================================
@@ -0,0 +1 @@
+True
=====================================
testsuite/tests/linear/should_run/all.T
=====================================
@@ -1,2 +1,3 @@
test('LinearTypeable', normal, compile_and_run, [''])
+test('T26311', normal, compile_and_run, ['-O1'])
test('LinearGhci', normal, ghci_script, ['LinearGhci.script'])
=====================================
testsuite/tests/rep-poly/T26072b.hs
=====================================
@@ -0,0 +1,78 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+module T26072b where
+
+-- base
+import Data.Kind
+import GHC.TypeNats
+import GHC.Exts
+ ( TYPE, RuntimeRep(..), LiftedRep
+ , proxy#
+ )
+
+--------------------------------------------------------------------------------
+
+-- Stub for functions in 'primitive' (to avoid dependency)
+type PrimArray :: Type -> Type
+data PrimArray a = MkPrimArray
+
+indexPrimArray :: PrimArray a -> Int -> a
+indexPrimArray _ _ = error "unimplemented"
+{-# NOINLINE indexPrimArray #-}
+
+--------------------------------------------------------------------------------
+
+int :: forall n. KnownNat n => Int
+int = fromIntegral ( natVal' @n proxy# )
+
+type Fin :: Nat -> Type
+newtype Fin n = Fin { getFin :: Int }
+
+-- Vector
+type V :: Nat -> Type -> Type
+newtype V n a = V ( PrimArray a )
+
+-- Matrix
+type M :: Nat -> Type -> Type
+newtype M n a = M ( PrimArray a )
+
+type IndexRep :: (Type -> Type) -> RuntimeRep
+type family IndexRep f
+class Ix f where
+ type Index f :: TYPE (IndexRep f)
+ (!) :: f a -> Index f -> a
+ infixl 9 !
+
+type instance IndexRep ( V n ) = LiftedRep
+instance Ix ( V n ) where
+ type Index ( V n ) = Fin n
+ V v ! Fin !i = indexPrimArray v i
+ {-# INLINE (!) #-}
+
+type instance IndexRep ( M m ) = TupleRep [ LiftedRep, LiftedRep ]
+
+instance KnownNat n => Ix ( M n ) where
+ type Index ( M n ) = (# Fin n, Fin n #)
+ M m ! (# Fin !i, Fin !j #) = indexPrimArray m ( i + j * int @n )
+ {-# INLINE (!) #-}
+
+rowCol :: forall n a. ( KnownNat n, Num a ) => Fin n -> M n a -> V n a -> a
+rowCol i m v = go 0 ( Fin 0 )
+ where
+ n = int @n
+ go :: a -> Fin n -> a
+ go !acc j@( Fin !j_ )
+ | j_ >= n
+ = acc
+ | otherwise
+ = go ( acc + m ! (# i , j #) * v ! j ) ( Fin ( j_ + 1 ) )
=====================================
testsuite/tests/rep-poly/all.T
=====================================
@@ -127,6 +127,7 @@ test('T17536b', normal, compile, ['']) ##
test('T21650_a', js_broken(26578), compile, ['-Wno-deprecated-flags']) ##
test('T21650_b', js_broken(26578), compile, ['-Wno-deprecated-flags']) ##
test('T26072', js_broken(26578), compile, ['']) ##
+test('T26072b', js_broken(26578), compile, ['']) ##
test('RepPolyArgument2', normal, compile, ['']) ##
test('RepPolyCase2', js_broken(26578), compile, ['']) ##
test('RepPolyRule3', normal, compile, ['']) ##
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c12fa73e643e2df4428454e2137500…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c12fa73e643e2df4428454e2137500…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
19 Nov '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
c12fa73e by Simon Peyton Jones at 2025-11-19T02:55:01-05:00
Make PmLit be in Ord, and use it in Map
This MR addresses #26514, by changing from
data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
to
data PmAltConSet = PACS !(UniqDSet ConLike) !(Map PmLit PmLit)
This matters when doing pattern-match overlap checking, when there
is a very large set of patterns. For most programs it makes
no difference at all.
For the N=5000 case of the repro case in #26514, compiler
mutator time (with `-fno-code`) goes from 1.9s to 0.43s.
All for the price for an Ord instance for PmLit
- - - - -
3 changed files:
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/Types/SourceText.hs
- testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
Changes:
=====================================
compiler/GHC/HsToCore/Pmc/Solver/Types.hs
=====================================
@@ -2,6 +2,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE TypeFamilies #-}
-- | Domain types used in "GHC.HsToCore.Pmc.Solver".
-- The ultimate goal is to define 'Nabla', which models normalised refinement
@@ -32,7 +33,7 @@ module GHC.HsToCore.Pmc.Solver.Types (
PmEquality(..), eqPmAltCon,
-- *** Operations on 'PmLit'
- literalToPmLit, negatePmLit, overloadPmLit,
+ literalToPmLit, negatePmLit,
pmLitAsStringLit, coreExprAsPmLit
) where
@@ -51,13 +52,12 @@ import GHC.Core.ConLike
import GHC.Utils.Outputable
import GHC.Utils.Panic.Plain
import GHC.Utils.Misc (lastMaybe)
-import GHC.Data.List.SetOps (unionLists)
import GHC.Data.Maybe
import GHC.Core.Type
import GHC.Core.TyCon
import GHC.Types.Literal
import GHC.Core
-import GHC.Core.TyCo.Compare( eqType )
+import GHC.Core.TyCo.Compare( eqType, nonDetCmpType )
import GHC.Core.Map.Expr
import GHC.Core.Utils (exprType)
import GHC.Builtin.Names
@@ -69,15 +69,14 @@ import GHC.Types.CompleteMatch
import GHC.Types.SourceText (SourceText(..), mkFractionalLit, FractionalLit
, fractionalLitFromRational
, FractionalExponentBase(..))
+
import Numeric (fromRat)
-import Data.Foldable (find)
import Data.Ratio
+import Data.List( find )
+import qualified Data.Map as FM
import GHC.Real (Ratio(..))
-import qualified Data.Semigroup as Semi
-
--- import GHC.Driver.Ppr
+import qualified Data.Semigroup as S
---
-- * Normalised refinement types
--
@@ -358,6 +357,13 @@ lookupSolution nabla x = case vi_pos (lookupVarInfo (nabla_tm_st nabla) x) of
| Just sol <- find isDataConSolution pos -> Just sol
| otherwise -> Just x
+
+{- *********************************************************************
+* *
+ PmLit and PmLitValue
+* *
+********************************************************************* -}
+
--------------------------------------------------------------------------------
-- The rest is just providing an IR for (overloaded!) literals and AltCons that
-- sits between Hs and Core. We need a reliable way to detect and determine
@@ -376,13 +382,64 @@ data PmLitValue
= PmLitInt Integer
| PmLitRat Rational
| PmLitChar Char
- -- We won't actually see PmLitString in the oracle since we desugar strings to
- -- lists
| PmLitString FastString
+ -- We won't actually see PmLitString in the oracle
+ -- since we desugar strings to lists
+
+ -- Overloaded literals
| PmLitOverInt Int {- How often Negated? -} Integer
| PmLitOverRat Int {- How often Negated? -} FractionalLit
| PmLitOverString FastString
+-- | Syntactic equality.
+-- We want (Ord PmLit) so that we can use (Map PmLit x) in `PmAltConSet`
+instance Eq PmLit where
+ a == b = (a `compare` b) == EQ
+instance Ord PmLit where
+ compare = cmpPmLit
+
+cmpPmLit :: PmLit -> PmLit -> Ordering
+-- This function does "syntactic comparison":
+-- For overloaded literals, compare the type and value
+-- For non-overloaded literals, just compare the values
+-- But it treats (say)
+-- (PmLit Bool (PmLitOverInt 1))
+-- (PmLit Bool (PmLitOverInt 2))
+-- as un-equal, even through (fromInteger @Bool 1)
+-- could be the same as (fromInteger @Bool 2)
+cmpPmLit (PmLit { pm_lit_ty = t1, pm_lit_val = val1 })
+ (PmLit { pm_lit_ty = t2, pm_lit_val = val2 })
+ = case (val1,val2) of
+ (PmLitInt i1, PmLitInt i2) -> i1 `compare` i2
+ (PmLitRat r1, PmLitRat r2) -> r1 `compare` r2
+ (PmLitChar c1, PmLitChar c2) -> c1 `compare` c2
+ (PmLitString s1, PmLitString s2) -> s1 `uniqCompareFS` s2
+ (PmLitOverInt n1 i1, PmLitOverInt n2 i2) -> (n1 `compare` n2) S.<>
+ (i1 `compare` i2) S.<>
+ (t1 `nonDetCmpType` t2)
+ (PmLitOverRat n1 r1, PmLitOverRat n2 r2) -> (n1 `compare` n2) S.<>
+ (r1 `compare` r2) S.<>
+ (t1 `nonDetCmpType` t2)
+ (PmLitOverString s1, PmLitOverString s2) -> (s1 `uniqCompareFS` s2) S.<>
+ (t1 `nonDetCmpType` t2)
+ (PmLitInt {}, _) -> LT
+ (PmLitRat {}, PmLitInt {}) -> GT
+ (PmLitRat {}, _) -> LT
+ (PmLitChar {}, PmLitInt {}) -> GT
+ (PmLitChar {}, PmLitRat {}) -> GT
+ (PmLitChar {}, _) -> LT
+ (PmLitString {}, PmLitInt {}) -> GT
+ (PmLitString {}, PmLitRat {}) -> GT
+ (PmLitString {}, PmLitChar {}) -> GT
+ (PmLitString {}, _) -> LT
+
+ (PmLitOverString {}, _) -> GT
+ (PmLitOverRat {}, PmLitOverString{}) -> LT
+ (PmLitOverRat {}, _) -> GT
+ (PmLitOverInt {}, PmLitOverString{}) -> LT
+ (PmLitOverInt {}, PmLitOverRat{}) -> LT
+ (PmLitOverInt {}, _) -> GT
+
-- | Undecidable semantic equality result.
-- See Note [Undecidable Equality for PmAltCons]
data PmEquality
@@ -406,7 +463,10 @@ eqPmLit :: PmLit -> PmLit -> PmEquality
eqPmLit (PmLit t1 v1) (PmLit t2 v2)
-- no haddock | pprTrace "eqPmLit" (ppr t1 <+> ppr v1 $$ ppr t2 <+> ppr v2) False = undefined
| not (t1 `eqType` t2) = Disjoint
- | otherwise = go v1 v2
+ | otherwise = eqPmLitValue v1 v2
+
+eqPmLitValue :: PmLitValue -> PmLitValue -> PmEquality
+eqPmLitValue v1 v2 = go v1 v2
where
go (PmLitInt i1) (PmLitInt i2) = decEquality (i1 == i2)
go (PmLitRat r1) (PmLitRat r2) = decEquality (r1 == r2)
@@ -420,10 +480,6 @@ eqPmLit (PmLit t1 v1) (PmLit t2 v2)
| s1 == s2 = Equal
go _ _ = PossiblyOverlap
--- | Syntactic equality.
-instance Eq PmLit where
- a == b = eqPmLit a b == Equal
-
-- | Type of a 'PmLit'
pmLitType :: PmLit -> Type
pmLitType (PmLit ty _) = ty
@@ -445,34 +501,47 @@ eqConLike (PatSynCon psc1) (PatSynCon psc2)
= Equal
eqConLike _ _ = PossiblyOverlap
+
+{- *********************************************************************
+* *
+ PmAltCon and PmAltConSet
+* *
+********************************************************************* -}
+
-- | Represents the head of a match against a 'ConLike' or literal.
-- Really similar to 'GHC.Core.AltCon'.
data PmAltCon = PmAltConLike ConLike
| PmAltLit PmLit
-data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
+data PmAltConSet = PACS !(UniqDSet ConLike)
+ !(FM.Map PmLit PmLit)
+-- We use a (FM.Map PmLit PmLit) here, at the cost of requiring an Ord
+-- instance for PmLit, because in extreme cases the set of PmLits can be
+-- very large. See #26514.
emptyPmAltConSet :: PmAltConSet
-emptyPmAltConSet = PACS emptyUniqDSet []
+emptyPmAltConSet = PACS emptyUniqDSet FM.empty
isEmptyPmAltConSet :: PmAltConSet -> Bool
-isEmptyPmAltConSet (PACS cls lits) = isEmptyUniqDSet cls && null lits
+isEmptyPmAltConSet (PACS cls lits)
+ = isEmptyUniqDSet cls && FM.null lits
-- | Whether there is a 'PmAltCon' in the 'PmAltConSet' that compares 'Equal' to
-- the given 'PmAltCon' according to 'eqPmAltCon'.
elemPmAltConSet :: PmAltCon -> PmAltConSet -> Bool
elemPmAltConSet (PmAltConLike cl) (PACS cls _ ) = elementOfUniqDSet cl cls
-elemPmAltConSet (PmAltLit lit) (PACS _ lits) = elem lit lits
+elemPmAltConSet (PmAltLit lit) (PACS _ lits) = isJust (FM.lookup lit lits)
extendPmAltConSet :: PmAltConSet -> PmAltCon -> PmAltConSet
extendPmAltConSet (PACS cls lits) (PmAltConLike cl)
= PACS (addOneToUniqDSet cls cl) lits
extendPmAltConSet (PACS cls lits) (PmAltLit lit)
- = PACS cls (unionLists lits [lit])
+ = PACS cls (FM.insert lit lit lits)
pmAltConSetElems :: PmAltConSet -> [PmAltCon]
pmAltConSetElems (PACS cls lits)
- = map PmAltConLike (uniqDSetToList cls) ++ map PmAltLit lits
+ = map PmAltConLike (uniqDSetToList cls) ++
+ FM.foldr ((:) . PmAltLit) [] lits
instance Outputable PmAltConSet where
ppr = ppr . pmAltConSetElems
=====================================
compiler/GHC/Types/SourceText.hs
=====================================
@@ -188,6 +188,7 @@ data FractionalLit = FL
}
deriving (Data, Show)
-- The Show instance is required for the derived GHC.Parser.Lexer.Token instance when DEBUG is on
+ -- Eq and Ord instances are done explicitly
-- See Note [FractionalLit representation] in GHC.HsToCore.Match.Literal
data FractionalExponentBase
=====================================
testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
=====================================
@@ -1,4 +1,3 @@
-
pmcOrPats.hs:10:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
Pattern match(es) are non-exhaustive
In an equation for ‘g’: Patterns of type ‘T’, ‘U’ not matched: A W
@@ -18,7 +17,7 @@ pmcOrPats.hs:15:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
pmcOrPats.hs:17:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
Pattern match(es) are non-exhaustive
In an equation for ‘z’:
- Patterns of type ‘a’ not matched: p where p is not one of {3, 1, 2}
+ Patterns of type ‘a’ not matched: p where p is not one of {1, 2, 3}
pmcOrPats.hs:19:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
Pattern match is redundant
@@ -43,3 +42,4 @@ pmcOrPats.hs:21:1: warning: [GHC-61505]
• Patterns reported as unmatched might actually be matched
Suggested fix:
Increase the limit or resolve the warnings to suppress this message.
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c12fa73e643e2df4428454e21375001…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c12fa73e643e2df4428454e21375001…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
Simon Peyton Jones pushed to branch wip/T23162-part2 at Glasgow Haskell Compiler / GHC
Commits:
dd4dc342 by Simon Peyton Jones at 2025-11-19T00:26:12+00:00
Wibbles
Fix to niFixSubst
- - - - -
2 changed files:
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
Changes:
=====================================
compiler/GHC/Core/Unify.hs
=====================================
@@ -844,9 +844,10 @@ tcUnifyTysForInjectivity unif tys1 tys2
-- in-scope set is never looked at, so this free-var stuff
-- should never actually be done
- maybe_fix | unif = niFixSubst in_scope
- | otherwise = mkTvSubst in_scope -- when matching, don't confuse
- -- domain with range
+ maybe_fix tv_subst
+ | unif = niFixSubst in_scope tv_subst
+ | otherwise = mkTvSubst in_scope tv_subst
+ -- When matching, don't confuse domain with range; no fixpoint!
-----------------
tcUnifyTys :: BindTvFun
@@ -1125,10 +1126,10 @@ So, we work as follows:
, rest :-> rest :: G b (z :: b) ]
Note that rest now has the right kind
- 7. Apply this extended substitution (once) to the range of
- the /original/ substitution. (Note that we do the
- extended substitution would go on forever if you tried
- to find its fixpoint, because it maps z to z.)
+ 7. Apply this extended substitution (once) to the range of the
+ /original/ substitution. (Note that the extended substitution
+ would go on forever if you tried to find its fixpoint, because it
+ maps z to z.)
8. And go back to step 1
@@ -1147,8 +1148,10 @@ niFixSubst :: InScopeSet -> TvSubstEnv -> Subst
-- ToDo: use laziness instead of iteration?
niFixSubst in_scope tenv
| not_fixpoint = niFixSubst in_scope (mapVarEnv (substTy subst) tenv)
- | otherwise = subst
+ | otherwise = tenv_subst
where
+ tenv_subst = mkTvSubst in_scope tenv -- This is our starting point
+
range_fvs :: FV
range_fvs = tyCoFVsOfTypes (nonDetEltsUFM tenv)
-- It's OK to use nonDetEltsUFM here because the
@@ -1163,9 +1166,7 @@ niFixSubst in_scope tenv
free_tvs = scopedSort (filterOut in_domain range_tvs)
-- See Note [Finding the substitution fixpoint], Step 6
- subst = foldl' add_free_tv
- (mkTvSubst in_scope tenv)
- free_tvs
+ subst = foldl' add_free_tv tenv_subst free_tvs
add_free_tv :: Subst -> TyVar -> Subst
add_free_tv subst tv
=====================================
compiler/GHC/Tc/Solver/FunDeps.hs
=====================================
@@ -592,13 +592,12 @@ getRelevantBranches ax work_args work_rhs
Nothing -> go (branch:preceding) branches
where
is_relevant (CoAxBranch { cab_tvs = qtvs, cab_lhs = lhs_tys, cab_rhs = rhs_ty })
- | Just subst <- tcUnifyTysForInjectivity True work_tys (rhs_ty:lhs_tys)
+ | Just subst <- tcUnifyTysForInjectivity True (rhs_ty:lhs_tys) work_tys
, let (subst', qtvs') = trim_qtvs subst qtvs
lhs_tys' = substTys subst' lhs_tys
rhs_ty' = substTy subst' rhs_ty
, all (no_match lhs_tys') preceding
- = pprTrace "grb" (ppr qtvs $$ ppr subst $$ ppr qtvs' $$ ppr subst' $$ ppr lhs_tys $$ ppr lhs_tys') $
- Just (FDEqns { fd_qtvs = qtvs'
+ = Just (FDEqns { fd_qtvs = qtvs'
, fd_eqs = zipWith Pair (rhs_ty':lhs_tys') work_tys })
| otherwise
= Nothing
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dd4dc342d7dcc697d7c438250aeba13…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dd4dc342d7dcc697d7c438250aeba13…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Fix a bug in defaulting
by Marge Bot (@marge-bot) 19 Nov '25
by Marge Bot (@marge-bot) 19 Nov '25
19 Nov '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
acc70c3a by Simon Peyton Jones at 2025-11-18T16:21:20-05:00
Fix a bug in defaulting
Addresses #26582
Defaulting was doing some unification but then failing to
iterate. Silly.
I discovered that the main solver was unnecessarily iterating even
if there was a unification for an /outer/ unification variable, so
I fixed that too.
- - - - -
db17306c by Simon Peyton Jones at 2025-11-18T16:54:13-05:00
Make PmLit be in Ord, and use it in Map
This MR addresses #26514, by changing from
data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
to
data PmAltConSet = PACS !(UniqDSet ConLike) !(Map PmLit PmLit)
This matters when doing pattern-match overlap checking, when there
is a very large set of patterns. For most programs it makes
no difference at all.
For the N=5000 case of the repro case in #26514, compiler
mutator time (with `-fno-code`) goes from 1.9s to 0.43s.
All for the price for an Ord instance for PmLit
- - - - -
7d33a35f by sheaf at 2025-11-18T16:54:29-05:00
Add passing tests for #26311 and #26072
This commit adds two tests cases that now pass since landing the changes
to typechecking of data constructors in b33284c7.
Fixes #26072 #26311
- - - - -
d3a65832 by sheaf at 2025-11-18T16:54:29-05:00
mkCast: weaken bad cast warning for multiplicity
This commit weakens the warning message emitted when constructing a bad
cast in mkCast to ignore multiplicity.
Justification: since b33284c7, GHC uses sub-multiplicity coercions to
typecheck data constructors. The coercion optimiser is free to discard
these coercions, both for performance reasons, and because GHC's Core
simplifier does not (yet) preserve linearity.
We thus weaken 'mkCast' to use 'eqTypeIgnoringMultiplicity' instead of
'eqType', to avoid getting many spurious warnings about mismatched
multiplicities.
- - - - -
15 changed files:
- compiler/GHC/Core/Utils.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Types/SourceText.hs
- + testsuite/tests/linear/should_run/T26311.hs
- + testsuite/tests/linear/should_run/T26311.stdout
- testsuite/tests/linear/should_run/all.T
- testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
- + testsuite/tests/rep-poly/T26072b.hs
- testsuite/tests/rep-poly/all.T
- + testsuite/tests/typecheck/should_compile/T26582.hs
- testsuite/tests/typecheck/should_compile/all.T
Changes:
=====================================
compiler/GHC/Core/Utils.hs
=====================================
@@ -78,7 +78,7 @@ import GHC.Core.Type as Type
import GHC.Core.Predicate( isEqPred )
import GHC.Core.Predicate( isUnaryClass )
import GHC.Core.FamInstEnv
-import GHC.Core.TyCo.Compare( eqType, eqTypeX )
+import GHC.Core.TyCo.Compare( eqType, eqTypeX, eqTypeIgnoringMultiplicity )
import GHC.Core.Coercion
import GHC.Core.Reduction
import GHC.Core.TyCon
@@ -275,7 +275,7 @@ mkCast expr co
= assertPpr (coercionRole co == Representational)
(text "coercion" <+> ppr co <+> text "passed to mkCast"
<+> ppr expr <+> text "has wrong role" <+> ppr (coercionRole co)) $
- warnPprTrace (not (coercionLKind co `eqType` exprType expr)) "Bad cast"
+ warnPprTrace (not (coercionLKind co `eqTypeIgnoringMultiplicity` exprType expr)) "Bad cast"
(vcat [ text "Coercion LHS kind does not match enclosed expression type"
, text "co:" <+> ppr co
, text "coercionLKind:" <+> ppr (coercionLKind co)
=====================================
compiler/GHC/HsToCore/Pmc/Solver/Types.hs
=====================================
@@ -2,6 +2,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MultiWayIf #-}
+{-# LANGUAGE TypeFamilies #-}
-- | Domain types used in "GHC.HsToCore.Pmc.Solver".
-- The ultimate goal is to define 'Nabla', which models normalised refinement
@@ -32,7 +33,7 @@ module GHC.HsToCore.Pmc.Solver.Types (
PmEquality(..), eqPmAltCon,
-- *** Operations on 'PmLit'
- literalToPmLit, negatePmLit, overloadPmLit,
+ literalToPmLit, negatePmLit,
pmLitAsStringLit, coreExprAsPmLit
) where
@@ -51,13 +52,12 @@ import GHC.Core.ConLike
import GHC.Utils.Outputable
import GHC.Utils.Panic.Plain
import GHC.Utils.Misc (lastMaybe)
-import GHC.Data.List.SetOps (unionLists)
import GHC.Data.Maybe
import GHC.Core.Type
import GHC.Core.TyCon
import GHC.Types.Literal
import GHC.Core
-import GHC.Core.TyCo.Compare( eqType )
+import GHC.Core.TyCo.Compare( eqType, nonDetCmpType )
import GHC.Core.Map.Expr
import GHC.Core.Utils (exprType)
import GHC.Builtin.Names
@@ -69,15 +69,14 @@ import GHC.Types.CompleteMatch
import GHC.Types.SourceText (SourceText(..), mkFractionalLit, FractionalLit
, fractionalLitFromRational
, FractionalExponentBase(..))
+
import Numeric (fromRat)
-import Data.Foldable (find)
import Data.Ratio
+import Data.List( find )
+import qualified Data.Map as FM
import GHC.Real (Ratio(..))
-import qualified Data.Semigroup as Semi
-
--- import GHC.Driver.Ppr
+import qualified Data.Semigroup as S
---
-- * Normalised refinement types
--
@@ -358,6 +357,13 @@ lookupSolution nabla x = case vi_pos (lookupVarInfo (nabla_tm_st nabla) x) of
| Just sol <- find isDataConSolution pos -> Just sol
| otherwise -> Just x
+
+{- *********************************************************************
+* *
+ PmLit and PmLitValue
+* *
+********************************************************************* -}
+
--------------------------------------------------------------------------------
-- The rest is just providing an IR for (overloaded!) literals and AltCons that
-- sits between Hs and Core. We need a reliable way to detect and determine
@@ -376,13 +382,64 @@ data PmLitValue
= PmLitInt Integer
| PmLitRat Rational
| PmLitChar Char
- -- We won't actually see PmLitString in the oracle since we desugar strings to
- -- lists
| PmLitString FastString
+ -- We won't actually see PmLitString in the oracle
+ -- since we desugar strings to lists
+
+ -- Overloaded literals
| PmLitOverInt Int {- How often Negated? -} Integer
| PmLitOverRat Int {- How often Negated? -} FractionalLit
| PmLitOverString FastString
+-- | Syntactic equality.
+-- We want (Ord PmLit) so that we can use (Map PmLit x) in `PmAltConSet`
+instance Eq PmLit where
+ a == b = (a `compare` b) == EQ
+instance Ord PmLit where
+ compare = cmpPmLit
+
+cmpPmLit :: PmLit -> PmLit -> Ordering
+-- This function does "syntactic comparison":
+-- For overloaded literals, compare the type and value
+-- For non-overloaded literals, just compare the values
+-- But it treats (say)
+-- (PmLit Bool (PmLitOverInt 1))
+-- (PmLit Bool (PmLitOverInt 2))
+-- as un-equal, even through (fromInteger @Bool 1)
+-- could be the same as (fromInteger @Bool 2)
+cmpPmLit (PmLit { pm_lit_ty = t1, pm_lit_val = val1 })
+ (PmLit { pm_lit_ty = t2, pm_lit_val = val2 })
+ = case (val1,val2) of
+ (PmLitInt i1, PmLitInt i2) -> i1 `compare` i2
+ (PmLitRat r1, PmLitRat r2) -> r1 `compare` r2
+ (PmLitChar c1, PmLitChar c2) -> c1 `compare` c2
+ (PmLitString s1, PmLitString s2) -> s1 `uniqCompareFS` s2
+ (PmLitOverInt n1 i1, PmLitOverInt n2 i2) -> (n1 `compare` n2) S.<>
+ (i1 `compare` i2) S.<>
+ (t1 `nonDetCmpType` t2)
+ (PmLitOverRat n1 r1, PmLitOverRat n2 r2) -> (n1 `compare` n2) S.<>
+ (r1 `compare` r2) S.<>
+ (t1 `nonDetCmpType` t2)
+ (PmLitOverString s1, PmLitOverString s2) -> (s1 `uniqCompareFS` s2) S.<>
+ (t1 `nonDetCmpType` t2)
+ (PmLitInt {}, _) -> LT
+ (PmLitRat {}, PmLitInt {}) -> GT
+ (PmLitRat {}, _) -> LT
+ (PmLitChar {}, PmLitInt {}) -> GT
+ (PmLitChar {}, PmLitRat {}) -> GT
+ (PmLitChar {}, _) -> LT
+ (PmLitString {}, PmLitInt {}) -> GT
+ (PmLitString {}, PmLitRat {}) -> GT
+ (PmLitString {}, PmLitChar {}) -> GT
+ (PmLitString {}, _) -> LT
+
+ (PmLitOverString {}, _) -> GT
+ (PmLitOverRat {}, PmLitOverString{}) -> LT
+ (PmLitOverRat {}, _) -> GT
+ (PmLitOverInt {}, PmLitOverString{}) -> LT
+ (PmLitOverInt {}, PmLitOverRat{}) -> LT
+ (PmLitOverInt {}, _) -> GT
+
-- | Undecidable semantic equality result.
-- See Note [Undecidable Equality for PmAltCons]
data PmEquality
@@ -406,7 +463,10 @@ eqPmLit :: PmLit -> PmLit -> PmEquality
eqPmLit (PmLit t1 v1) (PmLit t2 v2)
-- no haddock | pprTrace "eqPmLit" (ppr t1 <+> ppr v1 $$ ppr t2 <+> ppr v2) False = undefined
| not (t1 `eqType` t2) = Disjoint
- | otherwise = go v1 v2
+ | otherwise = eqPmLitValue v1 v2
+
+eqPmLitValue :: PmLitValue -> PmLitValue -> PmEquality
+eqPmLitValue v1 v2 = go v1 v2
where
go (PmLitInt i1) (PmLitInt i2) = decEquality (i1 == i2)
go (PmLitRat r1) (PmLitRat r2) = decEquality (r1 == r2)
@@ -420,10 +480,6 @@ eqPmLit (PmLit t1 v1) (PmLit t2 v2)
| s1 == s2 = Equal
go _ _ = PossiblyOverlap
--- | Syntactic equality.
-instance Eq PmLit where
- a == b = eqPmLit a b == Equal
-
-- | Type of a 'PmLit'
pmLitType :: PmLit -> Type
pmLitType (PmLit ty _) = ty
@@ -445,34 +501,47 @@ eqConLike (PatSynCon psc1) (PatSynCon psc2)
= Equal
eqConLike _ _ = PossiblyOverlap
+
+{- *********************************************************************
+* *
+ PmAltCon and PmAltConSet
+* *
+********************************************************************* -}
+
-- | Represents the head of a match against a 'ConLike' or literal.
-- Really similar to 'GHC.Core.AltCon'.
data PmAltCon = PmAltConLike ConLike
| PmAltLit PmLit
-data PmAltConSet = PACS !(UniqDSet ConLike) ![PmLit]
+data PmAltConSet = PACS !(UniqDSet ConLike)
+ !(FM.Map PmLit PmLit)
+-- We use a (FM.Map PmLit PmLit) here, at the cost of requiring an Ord
+-- instance for PmLit, because in extreme cases the set of PmLits can be
+-- very large. See #26514.
emptyPmAltConSet :: PmAltConSet
-emptyPmAltConSet = PACS emptyUniqDSet []
+emptyPmAltConSet = PACS emptyUniqDSet FM.empty
isEmptyPmAltConSet :: PmAltConSet -> Bool
-isEmptyPmAltConSet (PACS cls lits) = isEmptyUniqDSet cls && null lits
+isEmptyPmAltConSet (PACS cls lits)
+ = isEmptyUniqDSet cls && FM.null lits
-- | Whether there is a 'PmAltCon' in the 'PmAltConSet' that compares 'Equal' to
-- the given 'PmAltCon' according to 'eqPmAltCon'.
elemPmAltConSet :: PmAltCon -> PmAltConSet -> Bool
elemPmAltConSet (PmAltConLike cl) (PACS cls _ ) = elementOfUniqDSet cl cls
-elemPmAltConSet (PmAltLit lit) (PACS _ lits) = elem lit lits
+elemPmAltConSet (PmAltLit lit) (PACS _ lits) = isJust (FM.lookup lit lits)
extendPmAltConSet :: PmAltConSet -> PmAltCon -> PmAltConSet
extendPmAltConSet (PACS cls lits) (PmAltConLike cl)
= PACS (addOneToUniqDSet cls cl) lits
extendPmAltConSet (PACS cls lits) (PmAltLit lit)
- = PACS cls (unionLists lits [lit])
+ = PACS cls (FM.insert lit lit lits)
pmAltConSetElems :: PmAltConSet -> [PmAltCon]
pmAltConSetElems (PACS cls lits)
- = map PmAltConLike (uniqDSetToList cls) ++ map PmAltLit lits
+ = map PmAltConLike (uniqDSetToList cls) ++
+ FM.foldr ((:) . PmAltLit) [] lits
instance Outputable PmAltConSet where
ppr = ppr . pmAltConSetElems
=====================================
compiler/GHC/Tc/Solver/Default.hs
=====================================
@@ -395,9 +395,11 @@ tryConstraintDefaulting wc
| isEmptyWC wc
= return wc
| otherwise
- = do { (unif_happened, better_wc) <- reportCoarseGrainUnifications $
- go_wc False wc
- -- We may have done unifications; so solve again
+ = do { (outermost_unif_lvl, better_wc) <- reportCoarseGrainUnifications $
+ go_wc False wc
+
+ -- We may have done unifications; if so, solve again
+ ; let unif_happened = not (isInfiniteTcLevel outermost_unif_lvl)
; solveAgainIf unif_happened better_wc }
where
go_wc :: Bool -> WantedConstraints -> TcS WantedConstraints
@@ -414,14 +416,17 @@ tryConstraintDefaulting wc
else return (Just ct) }
go_implic :: Bool -> Implication -> TcS Implication
- go_implic encl_eqs implic@(Implic { ic_status = status, ic_wanted = wanteds
- , ic_given_eqs = given_eqs, ic_binds = binds })
+ go_implic encl_eqs implic@(Implic { ic_tclvl = tclvl
+ , ic_status = status, ic_wanted = wanteds
+ , ic_given_eqs = given_eqs, ic_binds = binds })
| isSolvedStatus status
= return implic -- Nothing to solve inside here
| otherwise
= do { let encl_eqs' = encl_eqs || given_eqs /= NoGivenEqs
- ; wanteds' <- setEvBindsTcS binds $
+ ; wanteds' <- setTcLevelTcS tclvl $
+ -- Set the levels so that reportCoarseGrainUnifications works
+ setEvBindsTcS binds $
-- defaultCallStack sets a binding, so
-- we must set the correct binding group
go_wc encl_eqs' wanteds
@@ -660,7 +665,9 @@ Wrinkles:
f x = case x of T1 -> True
Should we infer f :: T a -> Bool, or f :: T a -> a. Both are valid, but
- neither is more general than the other.
+ neither is more general than the other. But by the time defaulting takes
+ place all let-bound variables have got their final types; defaulting won't
+ affect let-generalisation.
(DE2) We still can't unify if there is a skolem-escape check, or an occurs check,
or it it'd mean unifying a TyVarTv with a non-tyvar. It's only the
=====================================
compiler/GHC/Tc/Solver/Monad.hs
=====================================
@@ -1877,18 +1877,18 @@ reportFineGrainUnifications (TcS thing_inside)
; recordUnifications outer_wu unif_tvs
; return (unif_tvs, res) }
-reportCoarseGrainUnifications :: TcS a -> TcS (Bool, a)
+reportCoarseGrainUnifications :: TcS a -> TcS (TcLevel, a)
-- Record whether any useful unifications are done by thing_inside
+-- Specifically: return the TcLevel of the outermost (smallest level)
+-- unification variable that has been unified, or infiniteTcLevel if none
-- Remember to propagate the information to the enclosing context
reportCoarseGrainUnifications (TcS thing_inside)
= TcS $ \ env@(TcSEnv { tcs_what = outer_what }) ->
case outer_what of
- WU_None
- -> do { (unif_happened, _, res) <- report_coarse_grain_unifs env thing_inside
- ; return (unif_happened, res) }
+ WU_None -> report_coarse_grain_unifs env thing_inside
WU_Coarse outer_ul_ref
- -> do { (unif_happened, inner_ul, res) <- report_coarse_grain_unifs env thing_inside
+ -> do { (inner_ul, res) <- report_coarse_grain_unifs env thing_inside
-- Propagate to outer_ul_ref
; outer_ul <- TcM.readTcRef outer_ul_ref
@@ -1897,31 +1897,32 @@ reportCoarseGrainUnifications (TcS thing_inside)
; TcM.traceTc "reportCoarse(Coarse)" $
vcat [ text "outer_ul" <+> ppr outer_ul
- , text "inner_ul" <+> ppr inner_ul
- , text "unif_happened" <+> ppr unif_happened ]
- ; return (unif_happened, res) }
+ , text "inner_ul" <+> ppr inner_ul]
+ ; return (inner_ul, res) }
WU_Fine outer_tvs_ref
-> do { (unif_tvs,res) <- report_fine_grain_unifs env thing_inside
- ; let unif_happened = not (isEmptyVarSet unif_tvs)
- ; when unif_happened $
- TcM.updTcRef outer_tvs_ref (`unionVarSet` unif_tvs)
+
+ -- Propagate to outer_tvs_rev
+ ; TcM.updTcRef outer_tvs_ref (`unionVarSet` unif_tvs)
+
+ ; let outermost_unif_lvl = minTcTyVarSetLevel unif_tvs
; TcM.traceTc "reportCoarse(Fine)" $
vcat [ text "unif_tvs" <+> ppr unif_tvs
- , text "unif_happened" <+> ppr unif_happened ]
- ; return (unif_happened, res) }
+ , text "unif_happened" <+> ppr outermost_unif_lvl ]
+ ; return (outermost_unif_lvl, res) }
report_coarse_grain_unifs :: TcSEnv -> (TcSEnv -> TcM a)
- -> TcM (Bool, TcLevel, a)
--- Returns (unif_happened, coarse_inner_ul, res)
+ -> TcM (TcLevel, a)
+-- Returns the level number of the outermost
+-- unification variable that is unified
report_coarse_grain_unifs env thing_inside
= do { inner_ul_ref <- TcM.newTcRef infiniteTcLevel
; res <- thing_inside (env { tcs_what = WU_Coarse inner_ul_ref })
- ; inner_ul <- TcM.readTcRef inner_ul_ref
- ; ambient_lvl <- TcM.getTcLevel
- ; let unif_happened = ambient_lvl `deeperThanOrSame` inner_ul
- ; return (unif_happened, inner_ul, res) }
-
+ ; inner_ul <- TcM.readTcRef inner_ul_ref
+ ; TcM.traceTc "report_coarse" $
+ text "inner_lvl =" <+> ppr inner_ul
+ ; return (inner_ul, res) }
report_fine_grain_unifs :: TcSEnv -> (TcSEnv -> TcM a)
-> TcM (TcTyVarSet, a)
=====================================
compiler/GHC/Tc/Solver/Solve.hs
=====================================
@@ -118,28 +118,34 @@ simplify_loop n limit definitely_redo_implications
, int (lengthBag simples) <+> text "simples to solve" ])
; traceTcS "simplify_loop: wc =" (ppr wc)
- ; (simple_unif_happened, wc1)
+ ; ambient_lvl <- getTcLevel
+ ; (simple_unif_lvl, wc1)
<- reportCoarseGrainUnifications $ -- See Note [Superclass iteration]
solveSimpleWanteds simples
-- Any insoluble constraints are in 'simples' and so get rewritten
-- See Note [Rewrite insolubles] in GHC.Tc.Solver.InertSet
-- Next, solve implications from wc_impl
- ; (impl_unif_happened, implics')
+ ; let simple_unif_happened = ambient_lvl `deeperThanOrSame` simple_unif_lvl
+ ; (implic_unif_lvl, implics')
<- if not (definitely_redo_implications -- See Note [Superclass iteration]
|| simple_unif_happened) -- for this conditional
- then return (False, implics)
+ then return (infiniteTcLevel, implics)
else reportCoarseGrainUnifications $
solveNestedImplications implics
; let wc' = wc1 { wc_impl = wc_impl wc1 `unionBags` implics' }
- ; csTraceTcS $ text "unif_happened" <+> ppr impl_unif_happened
-
-- We iterate the loop only if the /implications/ did some relevant
- -- unification. Even if the /simples/ did unifications we don't need
- -- to re-do them.
- ; maybe_simplify_again (n+1) limit impl_unif_happened wc' }
+ -- unification, hence looking only at `implic_unif_lvl`. (Even if the
+ -- /simples/ did unifications we don't need to re-do them.)
+ -- Also note that we only iterate if `implic_unify_lvl` is /equal to/
+ -- the current level; if it is less , we'll iterate some outer level,
+ -- which will bring us back here anyway.
+ -- See Note [When to iterate the solver: unifications]
+ ; let implic_unif_happened = implic_unif_lvl `sameDepthAs` ambient_lvl
+ ; csTraceTcS $ text "implic_unif_happened" <+> ppr implic_unif_happened
+ ; maybe_simplify_again (n+1) limit implic_unif_happened wc' }
data NextAction
= NA_Stop -- Just return the WantedConstraints
@@ -148,7 +154,9 @@ data NextAction
Bool -- See `definitely_redo_implications` in the comment
-- for `simplify_loop`
-maybe_simplify_again :: Int -> IntWithInf -> Bool
+maybe_simplify_again :: Int -> IntWithInf
+ -> Bool -- True <=> Solving the implications did some unifications
+ -- at the current level; so iterate
-> WantedConstraints -> TcS WantedConstraints
maybe_simplify_again n limit unif_happened wc@(WC { wc_simple = simples })
= do { -- Look for reasons to stop or continue
@@ -222,10 +230,10 @@ and if so it seems a pity to waste time iterating the implications (forall b. bl
(If we add new Given superclasses it's a different matter: it's really worth looking
at the implications.)
-Hence the definitely_redo_implications flag to simplify_loop. It's usually
-True, but False in the case where the only reason to iterate is new Wanted
-superclasses. In that case we check whether the new Wanteds actually led to
-any new unifications, and iterate the implications only if so.
+Hence the `definitely_redo_implications` flag to `simplify_loop`. It's usually True,
+but False in the case where the only reason to iterate is new Wanted superclasses.
+In that case we check whether the new Wanteds actually led to any new unifications
+(at all), and iterate the implications only if so.
Note [When to iterate the solver: unifications]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Tc/Utils/TcType.hs
=====================================
@@ -45,7 +45,7 @@ module GHC.Tc.Utils.TcType (
TcLevel(..), topTcLevel, pushTcLevel, isTopTcLevel,
strictlyDeeperThan, deeperThanOrSame, sameDepthAs,
tcTypeLevel, tcTyVarLevel, maxTcLevel, minTcLevel,
- infiniteTcLevel,
+ infiniteTcLevel, isInfiniteTcLevel,
--------------------------------
-- MetaDetails
@@ -879,6 +879,10 @@ isTopTcLevel :: TcLevel -> Bool
isTopTcLevel (TcLevel 0) = True
isTopTcLevel _ = False
+isInfiniteTcLevel :: TcLevel -> Bool
+isInfiniteTcLevel QLInstVar = True
+isInfiniteTcLevel _ = False
+
pushTcLevel :: TcLevel -> TcLevel
-- See Note [TcLevel assignment]
pushTcLevel (TcLevel us) = TcLevel (us + 1)
=====================================
compiler/GHC/Types/SourceText.hs
=====================================
@@ -188,6 +188,7 @@ data FractionalLit = FL
}
deriving (Data, Show)
-- The Show instance is required for the derived GHC.Parser.Lexer.Token instance when DEBUG is on
+ -- Eq and Ord instances are done explicitly
-- See Note [FractionalLit representation] in GHC.HsToCore.Match.Literal
data FractionalExponentBase
=====================================
testsuite/tests/linear/should_run/T26311.hs
=====================================
@@ -0,0 +1,23 @@
+{-# LANGUAGE MagicHash #-}
+
+module Main where
+
+import GHC.Exts ( Int# )
+
+expensive :: Int -> Int#
+expensive 0 = 2#
+expensive i = expensive (i-1)
+
+data D = MkD Int# Int
+
+f :: a -> Bool
+f _ = False
+{-# NOINLINE f #-}
+
+{-# RULES "f/MkD" forall x. f (MkD x) = True #-}
+
+bar :: Bool
+bar = f (MkD (expensive 10))
+
+main :: IO ()
+main = print bar
=====================================
testsuite/tests/linear/should_run/T26311.stdout
=====================================
@@ -0,0 +1 @@
+True
=====================================
testsuite/tests/linear/should_run/all.T
=====================================
@@ -1,2 +1,3 @@
test('LinearTypeable', normal, compile_and_run, [''])
+test('T26311', normal, compile_and_run, ['-O1'])
test('LinearGhci', normal, ghci_script, ['LinearGhci.script'])
=====================================
testsuite/tests/pmcheck/should_compile/pmcOrPats.stderr
=====================================
@@ -1,4 +1,3 @@
-
pmcOrPats.hs:10:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
Pattern match(es) are non-exhaustive
In an equation for ‘g’: Patterns of type ‘T’, ‘U’ not matched: A W
@@ -18,7 +17,7 @@ pmcOrPats.hs:15:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
pmcOrPats.hs:17:1: warning: [GHC-62161] [-Wincomplete-patterns (in -Wextra)]
Pattern match(es) are non-exhaustive
In an equation for ‘z’:
- Patterns of type ‘a’ not matched: p where p is not one of {3, 1, 2}
+ Patterns of type ‘a’ not matched: p where p is not one of {1, 2, 3}
pmcOrPats.hs:19:1: warning: [GHC-53633] [-Woverlapping-patterns (in -Wdefault)]
Pattern match is redundant
@@ -43,3 +42,4 @@ pmcOrPats.hs:21:1: warning: [GHC-61505]
• Patterns reported as unmatched might actually be matched
Suggested fix:
Increase the limit or resolve the warnings to suppress this message.
+
=====================================
testsuite/tests/rep-poly/T26072b.hs
=====================================
@@ -0,0 +1,78 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE BangPatterns #-}
+{-# LANGUAGE BlockArguments #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE StandaloneKindSignatures #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UnboxedTuples #-}
+
+module T26072b where
+
+-- base
+import Data.Kind
+import GHC.TypeNats
+import GHC.Exts
+ ( TYPE, RuntimeRep(..), LiftedRep
+ , proxy#
+ )
+
+--------------------------------------------------------------------------------
+
+-- Stub for functions in 'primitive' (to avoid dependency)
+type PrimArray :: Type -> Type
+data PrimArray a = MkPrimArray
+
+indexPrimArray :: PrimArray a -> Int -> a
+indexPrimArray _ _ = error "unimplemented"
+{-# NOINLINE indexPrimArray #-}
+
+--------------------------------------------------------------------------------
+
+int :: forall n. KnownNat n => Int
+int = fromIntegral ( natVal' @n proxy# )
+
+type Fin :: Nat -> Type
+newtype Fin n = Fin { getFin :: Int }
+
+-- Vector
+type V :: Nat -> Type -> Type
+newtype V n a = V ( PrimArray a )
+
+-- Matrix
+type M :: Nat -> Type -> Type
+newtype M n a = M ( PrimArray a )
+
+type IndexRep :: (Type -> Type) -> RuntimeRep
+type family IndexRep f
+class Ix f where
+ type Index f :: TYPE (IndexRep f)
+ (!) :: f a -> Index f -> a
+ infixl 9 !
+
+type instance IndexRep ( V n ) = LiftedRep
+instance Ix ( V n ) where
+ type Index ( V n ) = Fin n
+ V v ! Fin !i = indexPrimArray v i
+ {-# INLINE (!) #-}
+
+type instance IndexRep ( M m ) = TupleRep [ LiftedRep, LiftedRep ]
+
+instance KnownNat n => Ix ( M n ) where
+ type Index ( M n ) = (# Fin n, Fin n #)
+ M m ! (# Fin !i, Fin !j #) = indexPrimArray m ( i + j * int @n )
+ {-# INLINE (!) #-}
+
+rowCol :: forall n a. ( KnownNat n, Num a ) => Fin n -> M n a -> V n a -> a
+rowCol i m v = go 0 ( Fin 0 )
+ where
+ n = int @n
+ go :: a -> Fin n -> a
+ go !acc j@( Fin !j_ )
+ | j_ >= n
+ = acc
+ | otherwise
+ = go ( acc + m ! (# i , j #) * v ! j ) ( Fin ( j_ + 1 ) )
=====================================
testsuite/tests/rep-poly/all.T
=====================================
@@ -127,6 +127,7 @@ test('T17536b', normal, compile, ['']) ##
test('T21650_a', js_broken(26578), compile, ['-Wno-deprecated-flags']) ##
test('T21650_b', js_broken(26578), compile, ['-Wno-deprecated-flags']) ##
test('T26072', js_broken(26578), compile, ['']) ##
+test('T26072b', js_broken(26578), compile, ['']) ##
test('RepPolyArgument2', normal, compile, ['']) ##
test('RepPolyCase2', js_broken(26578), compile, ['']) ##
test('RepPolyRule3', normal, compile, ['']) ##
=====================================
testsuite/tests/typecheck/should_compile/T26582.hs
=====================================
@@ -0,0 +1,35 @@
+{-# LANGUAGE GADTs #-}
+
+module T26582 where
+
+sametype :: a -> a -> Int
+sametype = sametype
+
+f :: Eq a => (a->Int) -> Int
+f = f
+
+data T b where T1 :: T Bool
+
+g1 :: T b -> Int
+g1 v = f (\x -> case v of { T1 -> sametype x True })
+
+g2 :: Eq c => c -> T b -> Int
+g2 c v = f (\x -> case v of { T1 -> sametype x c })
+
+{- The point is that we get something like
+
+ Wanted: [W] d : Eq alpha[1]
+ Implication
+ level: 2
+ Given: b~Bool
+
+ Wanted: [W] alpha[1]~Bool -- For g1
+ Wanted: [W] alpha[1]~c -- For g2
+
+So alpha is untouchable under the (b~Bool) from the GADT.
+And yet in the end it's easy to solve
+via alpha:=Bool, or alpha:=c resp
+
+But having done that defaulting we must then remember to
+solved that `d : Eq alpha`! We forgot to so so in #26582.
+-}
=====================================
testsuite/tests/typecheck/should_compile/all.T
=====================================
@@ -956,3 +956,4 @@ test('T26457', normal, compile, [''])
test('T17705', normal, compile, [''])
test('T14745', normal, compile, [''])
test('T26451', normal, compile, [''])
+test('T26582', normal, compile, [''])
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f4ab5d9e1a1ee58ccec3008b0b785e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f4ab5d9e1a1ee58ccec3008b0b785e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0