Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
fd45fc02
by Andreas Klebinger at 2026-01-21T07:04:45-05:00
-
1307d1d7
by Torsten Schmits at 2026-01-21T07:04:48-05:00
-
8dd7ff46
by Cheng Shao at 2026-01-21T07:04:49-05:00
-
e306178b
by Cheng Shao at 2026-01-21T07:04:50-05:00
-
176a0d8a
by Cheng Shao at 2026-01-21T07:04:50-05:00
-
9bb921e7
by Simon Peyton Jones at 2026-01-21T07:04:51-05:00
-
852def01
by Cheng Shao at 2026-01-21T07:04:52-05:00
-
9f30c975
by Zubin Duggal at 2026-01-21T07:04:53-05:00
-
1e30763b
by Cheng Shao at 2026-01-21T07:04:54-05:00
29 changed files:
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Unit/State.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.16.1-notes.rst
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Rules/Docspec.hs
- hadrian/src/Rules/Lint.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/RunTest.hs
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Classes.hs
- + libraries/ghc-internal/src/GHC/Internal/Classes/IP.hs
- libraries/ghci/GHCi/Server.hs
- rts/include/Cmm.h
- rts/include/stg/Ticky.h
- rts/sm/Storage.c
- testsuite/driver/runtests.py
- testsuite/driver/testlib.py
- testsuite/driver/testutil.py
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/base-exports.stdout-ws-32
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/th/TH_implicitParams.stdout
- + testsuite/tests/typecheck/should_compile/T26737.hs
- testsuite/tests/typecheck/should_compile/all.T
- utils/ghc-toolchain/exe/Main.hs
Changes:
| ... | ... | @@ -526,7 +526,7 @@ genericTyConNames = [ |
| 526 | 526 | |
| 527 | 527 | gHC_PRIM, gHC_PRIM_PANIC,
|
| 528 | 528 | gHC_TYPES, gHC_INTERNAL_DATA_DATA, gHC_MAGIC, gHC_MAGIC_DICT,
|
| 529 | - gHC_CLASSES, gHC_PRIMOPWRAPPERS :: Module
|
|
| 529 | + gHC_CLASSES, gHC_CLASSES_IP, gHC_PRIMOPWRAPPERS :: Module
|
|
| 530 | 530 | gHC_PRIM = mkGhcInternalModule (fsLit "GHC.Internal.Prim") -- Primitive types and values
|
| 531 | 531 | gHC_PRIM_PANIC = mkGhcInternalModule (fsLit "GHC.Internal.Prim.Panic")
|
| 532 | 532 | gHC_TYPES = mkGhcInternalModule (fsLit "GHC.Internal.Types")
|
| ... | ... | @@ -534,6 +534,7 @@ gHC_MAGIC = mkGhcInternalModule (fsLit "GHC.Internal.Magic") |
| 534 | 534 | gHC_MAGIC_DICT = mkGhcInternalModule (fsLit "GHC.Internal.Magic.Dict")
|
| 535 | 535 | gHC_CSTRING = mkGhcInternalModule (fsLit "GHC.Internal.CString")
|
| 536 | 536 | gHC_CLASSES = mkGhcInternalModule (fsLit "GHC.Internal.Classes")
|
| 537 | +gHC_CLASSES_IP = mkGhcInternalModule (fsLit "GHC.Internal.Classes.IP")
|
|
| 537 | 538 | gHC_PRIMOPWRAPPERS = mkGhcInternalModule (fsLit "GHC.Internal.PrimopWrappers")
|
| 538 | 539 | gHC_INTERNAL_TUPLE = mkGhcInternalModule (fsLit "GHC.Internal.Tuple")
|
| 539 | 540 | |
| ... | ... | @@ -1521,7 +1522,7 @@ fromLabelClassOpName |
| 1521 | 1522 | -- Implicit Parameters
|
| 1522 | 1523 | ipClassName :: Name
|
| 1523 | 1524 | ipClassName
|
| 1524 | - = clsQual gHC_CLASSES (fsLit "IP") ipClassKey
|
|
| 1525 | + = clsQual gHC_CLASSES_IP (fsLit "IP") ipClassKey
|
|
| 1525 | 1526 | |
| 1526 | 1527 | -- Overloaded record fields
|
| 1527 | 1528 | hasFieldClassName :: Name
|
| ... | ... | @@ -215,7 +215,7 @@ instance Outputable ModuleOrigin where |
| 215 | 215 | (if null rhs
|
| 216 | 216 | then []
|
| 217 | 217 | else [text "hidden reexport by" <+>
|
| 218 | - sep (map (ppr . mkUnit) res)]) ++
|
|
| 218 | + sep (map (ppr . mkUnit) rhs)]) ++
|
|
| 219 | 219 | (if f then [text "package flag"] else [])
|
| 220 | 220 | ))
|
| 221 | 221 |
| ... | ... | @@ -149,6 +149,7 @@ Library |
| 149 | 149 | else
|
| 150 | 150 | Build-Depends: unix >= 2.7 && < 2.9
|
| 151 | 151 | |
| 152 | + -- Hadrian further set some warnings in its Settings.Warnings module.
|
|
| 152 | 153 | GHC-Options: -Wall
|
| 153 | 154 | -Wno-name-shadowing
|
| 154 | 155 | -Wnoncanonical-monad-instances
|
| ... | ... | @@ -30,6 +30,18 @@ Language |
| 30 | 30 | - The extension :extension:`ExplicitNamespaces` now allows namespace-specified
|
| 31 | 31 | wildcards ``type ..`` and ``data ..`` in import and export lists.
|
| 32 | 32 | |
| 33 | +- Implicit parameters and ``ImpredicativeTypes``. GHC now knows
|
|
| 34 | + that if ``?foo::S`` is coecible to ``?foo::T`` only if ``S`` is coercible to ``T``.
|
|
| 35 | + Example (from :ghc-ticket:`#26737`)::
|
|
| 36 | + |
|
| 37 | + {-# LANGUAGE ImplicitParams, ImpredicativeTypes #-}
|
|
| 38 | + newtype N = MkN Int
|
|
| 39 | + test :: ((?foo::N) => Bool) -> ((?foo::Int) => Bool)
|
|
| 40 | + test = coerce
|
|
| 41 | + |
|
| 42 | + This is achieved by arranging that ``?foo :: T`` has a representational
|
|
| 43 | + role for ``T``.
|
|
| 44 | + |
|
| 33 | 45 | Compiler
|
| 34 | 46 | ~~~~~~~~
|
| 35 | 47 |
| ... | ... | @@ -19,7 +19,6 @@ module Hadrian.Utilities ( |
| 19 | 19 | copyFile, copyFileUntracked, createFileLink, fixFile,
|
| 20 | 20 | makeExecutable, moveFile, removeFile, createDirectory, copyDirectory,
|
| 21 | 21 | moveDirectory, removeDirectory, removeFile_, writeFileChangedBS,
|
| 22 | - findExecutable,
|
|
| 23 | 22 | |
| 24 | 23 | -- * Diagnostic info
|
| 25 | 24 | Colour (..), ANSIColour (..), putColoured, shouldUseColor,
|
| ... | ... | @@ -691,7 +690,3 @@ renderUnicorn ls = |
| 691 | 690 | ponyPadding = " "
|
| 692 | 691 | boxLines :: [String]
|
| 693 | 692 | boxLines = ["", "", ""] ++ (lines . renderBox $ ls) |
| 694 | - |
|
| 695 | --- Workaround for https://github.com/haskell/directory/issues/180
|
|
| 696 | -findExecutable :: String -> IO (Maybe FilePath)
|
|
| 697 | -findExecutable exe = IO.catch (IO.findExecutable exe) $ \(_ :: IO.IOException) -> pure Nothing |
| ... | ... | @@ -2,6 +2,8 @@ module Rules.Docspec |
| 2 | 2 | ( docspecRules
|
| 3 | 3 | ) where
|
| 4 | 4 | |
| 5 | +import System.Directory (findExecutable)
|
|
| 6 | + |
|
| 5 | 7 | import Base
|
| 6 | 8 | import Context.Path
|
| 7 | 9 | import Settings.Builders.Common
|
| ... | ... | @@ -4,6 +4,7 @@ module Rules.Lint |
| 4 | 4 | |
| 5 | 5 | import Base
|
| 6 | 6 | import Settings.Builders.Common
|
| 7 | +import System.Directory (findExecutable)
|
|
| 7 | 8 | import System.Exit (exitFailure)
|
| 8 | 9 | |
| 9 | 10 | lintRules :: Rules ()
|
| ... | ... | @@ -38,7 +38,6 @@ compileAndLinkHs = (builder (Ghc CompileHs) ||^ builder (Ghc LinkHs)) ? do |
| 38 | 38 | stage <- getStage
|
| 39 | 39 | hie_path <- getHieBuildPath
|
| 40 | 40 | mconcat [ arg "-Wall"
|
| 41 | - , arg "-Wcompat"
|
|
| 42 | 41 | , not useColor ? builder (Ghc CompileHs) ?
|
| 43 | 42 | -- N.B. Target.trackArgument ignores this argument from the
|
| 44 | 43 | -- input hash to avoid superfluous recompilation, avoiding
|
| ... | ... | @@ -16,6 +16,7 @@ import Settings.Builders.Common |
| 16 | 16 | import qualified Data.Set as Set
|
| 17 | 17 | import Flavour
|
| 18 | 18 | import qualified Context.Type as C
|
| 19 | +import System.Directory (findExecutable)
|
|
| 19 | 20 | import Settings.Program
|
| 20 | 21 | import qualified Context.Type
|
| 21 | 22 |
| ... | ... | @@ -343,6 +343,7 @@ Library |
| 343 | 343 | |
| 344 | 344 | GHC.Internal.CString
|
| 345 | 345 | GHC.Internal.Classes
|
| 346 | + GHC.Internal.Classes.IP
|
|
| 346 | 347 | GHC.Internal.Debug
|
| 347 | 348 | GHC.Internal.Magic
|
| 348 | 349 | GHC.Internal.Magic.Dict
|
| 1 | 1 | {-# LANGUAGE Trustworthy #-}
|
| 2 | 2 | {-# LANGUAGE NoImplicitPrelude, MagicHash, StandaloneDeriving, BangPatterns,
|
| 3 | 3 | KindSignatures, DataKinds, ConstraintKinds,
|
| 4 | - MultiParamTypeClasses, FunctionalDependencies #-}
|
|
| 5 | -{-# LANGUAGE UnboxedTuples #-}
|
|
| 6 | -{-# LANGUAGE AllowAmbiguousTypes #-}
|
|
| 7 | - -- ip :: IP x a => a is strictly speaking ambiguous, but IP is magic
|
|
| 4 | + MultiParamTypeClasses, FunctionalDependencies,
|
|
| 5 | + UnboxedTuples #-}
|
|
| 6 | + |
|
| 8 | 7 | {-# LANGUAGE UndecidableSuperClasses #-}
|
| 9 | 8 | -- Because of the type-variable superclasses for tuples
|
| 10 | 9 | |
| ... | ... | @@ -142,6 +141,7 @@ import GHC.Internal.Prim |
| 142 | 141 | import GHC.Internal.Tuple
|
| 143 | 142 | import GHC.Internal.CString (unpackCString#)
|
| 144 | 143 | import GHC.Internal.Types
|
| 144 | +import GHC.Internal.Classes.IP
|
|
| 145 | 145 | |
| 146 | 146 | infix 4 ==, /=, <, <=, >=, >
|
| 147 | 147 | infixr 3 &&
|
| ... | ... | @@ -149,12 +149,6 @@ infixr 2 || |
| 149 | 149 | |
| 150 | 150 | default () -- Double isn't available yet
|
| 151 | 151 | |
| 152 | --- | The syntax @?x :: a@ is desugared into @IP "x" a@
|
|
| 153 | --- IP is declared very early, so that libraries can take
|
|
| 154 | --- advantage of the implicit-call-stack feature
|
|
| 155 | -class IP (x :: Symbol) a | x -> a where
|
|
| 156 | - ip :: a
|
|
| 157 | - |
|
| 158 | 152 | {- $matching_overloaded_methods_in_rules
|
| 159 | 153 | |
| 160 | 154 | Matching on class methods (e.g. @(==)@) in rewrite rules tends to be a bit
|
| 1 | +{-# LANGUAGE Trustworthy #-}
|
|
| 2 | +{-# LANGUAGE NoImplicitPrelude, MagicHash, StandaloneDeriving, BangPatterns,
|
|
| 3 | + KindSignatures, DataKinds, ConstraintKinds,
|
|
| 4 | + MultiParamTypeClasses, FunctionalDependencies #-}
|
|
| 5 | + |
|
| 6 | +{-# LANGUAGE AllowAmbiguousTypes, RoleAnnotations, IncoherentInstances #-}
|
|
| 7 | + -- LANGUAGE pragmas: see Note [IP: implicit parameter class]
|
|
| 8 | + |
|
| 9 | +{-# OPTIONS_HADDOCK not-home #-}
|
|
| 10 | +-----------------------------------------------------------------------------
|
|
| 11 | +-- |
|
|
| 12 | +-- Module : GHC.Internal.Classes.IP
|
|
| 13 | +-- Copyright : (c) The University of Glasgow, 1992-2002
|
|
| 14 | +-- License : see libraries/base/LICENSE
|
|
| 15 | +--
|
|
| 16 | +-- Maintainer : ghc-devs@haskell.org
|
|
| 17 | +-- Stability : internal
|
|
| 18 | +-- Portability : non-portable (GHC extensions)
|
|
| 19 | +--
|
|
| 20 | +-- Basic classes.
|
|
| 21 | +-- Do not import this module directly. It is an GHC internal only
|
|
| 22 | +-- module. Some of its contents are instead available from @Prelude@
|
|
| 23 | +-- and @GHC.Int@.
|
|
| 24 | +--
|
|
| 25 | +-----------------------------------------------------------------------------
|
|
| 26 | + |
|
| 27 | +module GHC.Internal.Classes.IP( IP(..)) where
|
|
| 28 | + |
|
| 29 | +import GHC.Internal.Types
|
|
| 30 | + |
|
| 31 | + |
|
| 32 | +default () -- Double isn't available yet
|
|
| 33 | + |
|
| 34 | +-- | The syntax @?x :: a@ is desugared into @IP "x" a@
|
|
| 35 | +-- IP is declared very early, so that libraries can take
|
|
| 36 | +-- advantage of the implicit-call-stack feature
|
|
| 37 | +type role IP nominal representational -- See (IPRoles)
|
|
| 38 | +class IP (x :: Symbol) a | x -> a where
|
|
| 39 | + ip :: a
|
|
| 40 | + |
|
| 41 | +{- Note [IP: implicit parameter class]
|
|
| 42 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 43 | +An implicit parameter constraint (?foo::ty) is just short for
|
|
| 44 | + |
|
| 45 | + IP "foo" ty
|
|
| 46 | + |
|
| 47 | +where ghc-internal:GHC.Internal.Classes.IP is a special class that
|
|
| 48 | +GHC knows about, defined in this module.
|
|
| 49 | + |
|
| 50 | +* It is a unary type class, with one method `ip`, so it has no cost.
|
|
| 51 | + For example, (?foo::Int) is represented just by an Int.
|
|
| 52 | + |
|
| 53 | +* Criticially, it has a functional dependency:
|
|
| 54 | + class IP (x :: Symbol) a | x -> a where ...
|
|
| 55 | + So if we have
|
|
| 56 | + [G] IP "foo" Int
|
|
| 57 | + [W] IP "foo" alpha
|
|
| 58 | + the fundep wil lgive us alpha ~ Int, as desired.
|
|
| 59 | + |
|
| 60 | +* The solver has a number of special cases for implicit parameters,
|
|
| 61 | + mainly because a binding (let ?foo::Int = rhs in body)
|
|
| 62 | + is like a local instance declaration for IP. Search for uses
|
|
| 63 | + of `isIPClass`.
|
|
| 64 | + |
|
| 65 | +Wrinkles
|
|
| 66 | + |
|
| 67 | +(IPAmbiguity) The single method of IP has an ambiguous type
|
|
| 68 | + ip :: forall a. IP s a => a
|
|
| 69 | + Hence the LANGUAGE pragama AllowAmbiguousTypes.
|
|
| 70 | + The method `ip` is never called by the user, so ambiguity doesn't matter.
|
|
| 71 | + |
|
| 72 | +(IPRoles) IP has a role annotation. Why? See #26737. We want
|
|
| 73 | + [W] IP "foo" t1 ~R# IP "foo" t2
|
|
| 74 | + to decompose to give [W] IP t1 ~R# t2, using /representational/
|
|
| 75 | + equality for (t1 ~R# t2) not nominal.
|
|
| 76 | + |
|
| 77 | + This usually gives a complaint about incoherence, because in general
|
|
| 78 | + (t1 ~R# t2) does NOT imply (C t1) ~R# (C t2) for any normal class.
|
|
| 79 | + But it does for IP, because instance selection is controlled by the Symbol,
|
|
| 80 | + not the type of the payload. Hence LANGUAGE pragma IncoherentInstances.
|
|
| 81 | + (It is unfortunate that we need a module-wide IncoherentInstances here;
|
|
| 82 | + see #17167.)
|
|
| 83 | + |
|
| 84 | + Side note: arguably this treatment could be applied to any class
|
|
| 85 | + with a functional dependency; but for now we restrict it to IP.
|
|
| 86 | +-}
|
|
| 87 | + |
| ... | ... | @@ -32,11 +32,12 @@ import Data.Binary |
| 32 | 32 | import Text.Printf
|
| 33 | 33 | import System.Environment (getProgName, getArgs)
|
| 34 | 34 | import System.Exit
|
| 35 | +import System.IO
|
|
| 35 | 36 | |
| 36 | 37 | type MessageHook = Msg -> IO Msg
|
| 37 | 38 | |
| 38 | 39 | trace :: String -> IO ()
|
| 39 | -trace s = getProgName >>= \name -> printf "[%20s] %s\n" name s
|
|
| 40 | +trace s = getProgName >>= \name -> hPrintf stderr "[%20s] %s\n" name s
|
|
| 40 | 41 | |
| 41 | 42 | serv :: Bool -> MessageHook -> Pipe -> (forall a .IO a -> IO a) -> IO ()
|
| 42 | 43 | serv verbose hook pipe restore = loop
|
| ... | ... | @@ -441,12 +441,6 @@ |
| 441 | 441 | #define HP_CHK_P(bytes, fun, arg) \
|
| 442 | 442 | HEAP_CHECK(bytes, GC_PRIM_P(fun,arg))
|
| 443 | 443 | |
| 444 | -// TODO I'm not seeing where ALLOC_P_TICKY is used; can it be removed?
|
|
| 445 | -// -NSF March 2013
|
|
| 446 | -#define ALLOC_P_TICKY(bytes, fun, arg) \
|
|
| 447 | - HP_CHK_P(bytes); \
|
|
| 448 | - TICK_ALLOC_RTS(bytes);
|
|
| 449 | - |
|
| 450 | 444 | // Load a field out of structure with relaxed ordering.
|
| 451 | 445 | #define RELAXED_LOAD_FIELD(fld, ptr) \
|
| 452 | 446 | REP_##fld![(ptr) + OFFSET_##fld]
|
| ... | ... | @@ -246,7 +246,7 @@ EXTERN StgInt RET_UNBOXED_TUP_hst[TICKY_BIN_COUNT] INIT({0}); |
| 246 | 246 | TICK_BUMP_BY(ALLOC_THK_gds,g);\
|
| 247 | 247 | TICK_BUMP_BY(ALLOC_THK_slp,s);\
|
| 248 | 248 | |
| 249 | -#define TICK_ALLOC_RTS(bytes)\
|
|
| 249 | +#define TICK_ALLOC_RTS(n)\
|
|
| 250 | 250 | TICK_BUMP(ALLOC_RTS_ctr);\
|
| 251 | 251 | TICK_BUMP_BY(ALLOC_RTS_tot,n);
|
| 252 | 252 | #endif |
| ... | ... | @@ -990,7 +990,7 @@ move_STACK (StgStack *src, StgStack *dest) |
| 990 | 990 | void
|
| 991 | 991 | accountAllocation(Capability *cap, W_ n)
|
| 992 | 992 | {
|
| 993 | - TICK_ALLOC_RTS(WDS(n));
|
|
| 993 | + TICK_ALLOC_RTS(n*sizeof(W_));
|
|
| 994 | 994 | CCS_ALLOC(cap->r.rCCCS,n);
|
| 995 | 995 | if (cap->r.rCurrentTSO != NULL) {
|
| 996 | 996 | // cap->r.rCurrentTSO->alloc_limit -= n*sizeof(W_)
|
| ... | ... | @@ -28,7 +28,7 @@ import subprocess |
| 28 | 28 | |
| 29 | 29 | import asyncio
|
| 30 | 30 | |
| 31 | -from testutil import getStdout, str_warn, str_info, print_table, shorten_metric_name
|
|
| 31 | +from testutil import getStdout, str_warn, str_info, print_table, shorten_metric_name, str_removeprefix
|
|
| 32 | 32 | from testglobals import getConfig, ghc_env, TestConfig, t, \
|
| 33 | 33 | TestOptions, brokens, PerfMetric
|
| 34 | 34 | from my_typing import TestName
|
| ... | ... | @@ -291,7 +291,7 @@ if windows: |
| 291 | 291 | for line in pkginfo.split('\n'):
|
| 292 | 292 | if line.startswith('library-dirs:'):
|
| 293 | 293 | path = line.rstrip()
|
| 294 | - path = re.sub('^library-dirs: ', '', path)
|
|
| 294 | + path = str_removeprefix(path, 'library-dirs: ')
|
|
| 295 | 295 | # Use string.replace instead of re.sub, because re.sub
|
| 296 | 296 | # interprets backslashes in the replacement string as
|
| 297 | 297 | # escape sequences.
|
| ... | ... | @@ -25,7 +25,7 @@ from testglobals import config, ghc_env, default_testopts, brokens, t, \ |
| 25 | 25 | from testutil import strip_quotes, lndir, link_or_copy_file, passed, \
|
| 26 | 26 | failBecause, testing_metrics, residency_testing_metrics, \
|
| 27 | 27 | stable_perf_counters, \
|
| 28 | - PassFail, badResult, memoize
|
|
| 28 | + PassFail, badResult, memoize, str_removeprefix
|
|
| 29 | 29 | from term_color import Color, colored
|
| 30 | 30 | import testutil
|
| 31 | 31 | from cpu_features import have_cpu_feature
|
| ... | ... | @@ -1792,7 +1792,7 @@ async def do_test(name: TestName, |
| 1792 | 1792 | if opts.expect not in ['pass', 'fail', 'missing-lib']:
|
| 1793 | 1793 | framework_fail(name, way, 'bad expected ' + opts.expect)
|
| 1794 | 1794 | |
| 1795 | - directory = re.sub(r'^\.[/\\]', '', str(opts.testdir))
|
|
| 1795 | + directory = str_removeprefix(str_removeprefix(str(opts.testdir), './'), '.\\')
|
|
| 1796 | 1796 | |
| 1797 | 1797 | if way in opts.fragile_ways:
|
| 1798 | 1798 | if_verbose(1, '*** fragile test %s resulted in %s' % (full_name, 'pass' if result.passed else 'fail'))
|
| ... | ... | @@ -1830,7 +1830,7 @@ async def do_test(name: TestName, |
| 1830 | 1830 | # if found and instead have the testsuite decide on what to do
|
| 1831 | 1831 | # with the output.
|
| 1832 | 1832 | def override_options(pre_cmd):
|
| 1833 | - if config.verbose >= 5 and bool(re.match(r'\$make', pre_cmd, re.I)):
|
|
| 1833 | + if config.verbose >= 5 and pre_cmd.lower().startswith('$make'):
|
|
| 1834 | 1834 | return pre_cmd.replace(' -s' , '') \
|
| 1835 | 1835 | .replace('--silent', '') \
|
| 1836 | 1836 | .replace('--quiet' , '')
|
| ... | ... | @@ -1843,7 +1843,7 @@ def framework_fail(name: Optional[TestName], way: Optional[WayName], reason: str |
| 1843 | 1843 | # so we need to take care not to blow up with the wrong way
|
| 1844 | 1844 | # and report the actual reason for the failure.
|
| 1845 | 1845 | try:
|
| 1846 | - directory = re.sub(r'^\.[/\\]', '', str(opts.testdir))
|
|
| 1846 | + directory = str_removeprefix(str_removeprefix(str(opts.testdir), './'), '.\\')
|
|
| 1847 | 1847 | except:
|
| 1848 | 1848 | directory = ''
|
| 1849 | 1849 | full_name = '%s(%s)' % (name, way)
|
| ... | ... | @@ -1856,7 +1856,7 @@ def framework_fail(name: Optional[TestName], way: Optional[WayName], reason: str |
| 1856 | 1856 | |
| 1857 | 1857 | def framework_warn(name: TestName, way: WayName, reason: str) -> None:
|
| 1858 | 1858 | opts = getTestOpts()
|
| 1859 | - directory = re.sub(r'^\.[/\\]', '', str(opts.testdir))
|
|
| 1859 | + directory = str_removeprefix(str_removeprefix(str(opts.testdir), './'), '.\\')
|
|
| 1860 | 1860 | full_name = name + '(' + way + ')'
|
| 1861 | 1861 | if_verbose(1, '*** framework warning for %s %s ' % (full_name, reason))
|
| 1862 | 1862 | t.framework_warnings.append(TestResult(directory, name, reason, way))
|
| ... | ... | @@ -2550,7 +2550,7 @@ def split_file(in_fn: Path, delimiter: str, out1_fn: Path, out2_fn: Path): |
| 2550 | 2550 | with out1_fn.open('w', encoding='utf8', newline='') as out1:
|
| 2551 | 2551 | with out2_fn.open('w', encoding='utf8', newline='') as out2:
|
| 2552 | 2552 | line = infile.readline()
|
| 2553 | - while re.sub(r'^\s*','',line) != delimiter and line != '':
|
|
| 2553 | + while line.lstrip() != delimiter and line != '':
|
|
| 2554 | 2554 | out1.write(line)
|
| 2555 | 2555 | line = infile.readline()
|
| 2556 | 2556 | |
| ... | ... | @@ -2933,6 +2933,14 @@ def normalise_callstacks(s: str) -> str: |
| 2933 | 2933 | |
| 2934 | 2934 | tyCon_re = re.compile(r'TyCon\s*\d+\#\#\d?\d?\s*\d+\#\#\d?\d?\s*', flags=re.MULTILINE)
|
| 2935 | 2935 | |
| 2936 | +def drop_lines_containing(s: str, needle: str) -> str:
|
|
| 2937 | + """
|
|
| 2938 | + Drop lines from `s` which contain `needle`.
|
|
| 2939 | + """
|
|
| 2940 | + if needle not in s:
|
|
| 2941 | + return s
|
|
| 2942 | + return ''.join(line for line in s.splitlines(keepends=True) if needle not in line)
|
|
| 2943 | + |
|
| 2936 | 2944 | def normalise_type_reps(s: str) -> str:
|
| 2937 | 2945 | """ Normalise out fingerprints from Typeable TyCon representations """
|
| 2938 | 2946 | return re.sub(tyCon_re, 'TyCon FINGERPRINT FINGERPRINT ', s)
|
| ... | ... | @@ -2944,8 +2952,8 @@ def normalise_errmsg(s: str) -> str: |
| 2944 | 2952 | s = s.replace('ld: 0706-027 The -x flag is ignored.\n', '')
|
| 2945 | 2953 | # remove " error:" and lower-case " Warning:" to make patch for
|
| 2946 | 2954 | # trac issue #10021 smaller
|
| 2947 | - s = modify_lines(s, lambda l: re.sub(' error:', '', l))
|
|
| 2948 | - s = modify_lines(s, lambda l: re.sub(' Warning:', ' warning:', l))
|
|
| 2955 | + s = modify_lines(s, lambda l: l.replace(' error:', ''))
|
|
| 2956 | + s = modify_lines(s, lambda l: l.replace(' Warning:', ' warning:'))
|
|
| 2949 | 2957 | s = normalise_callstacks(s)
|
| 2950 | 2958 | s = normalise_type_reps(s)
|
| 2951 | 2959 | |
| ... | ... | @@ -2960,7 +2968,7 @@ def normalise_errmsg(s: str) -> str: |
| 2960 | 2968 | # a target prefix (e.g. `aarch64-linux-gnu-ghc`)
|
| 2961 | 2969 | # * On Windows the executable name may mention the
|
| 2962 | 2970 | # versioned name (e.g. `ghc-9.2.1`)
|
| 2963 | - s = re.sub(Path(config.compiler).name + ':', 'ghc:', s)
|
|
| 2971 | + s = s.replace(Path(config.compiler).name + ':', 'ghc:')
|
|
| 2964 | 2972 | |
| 2965 | 2973 | # If somefile ends in ".exe" or ".exe:", zap ".exe" (for Windows)
|
| 2966 | 2974 | # the colon is there because it appears in error messages; this
|
| ... | ... | @@ -2973,11 +2981,13 @@ def normalise_errmsg(s: str) -> str: |
| 2973 | 2981 | s = re.sub(r'([^\s])\.jsexe', r'\1', s)
|
| 2974 | 2982 | |
| 2975 | 2983 | # hpc executable is given ghc suffix
|
| 2976 | - s = re.sub('hpc-ghc', 'hpc', s)
|
|
| 2984 | + s = s.replace('hpc-ghc', 'hpc')
|
|
| 2977 | 2985 | |
| 2978 | 2986 | # The inplace ghc's are called ghc-stage[123] to avoid filename
|
| 2979 | 2987 | # collisions, so we need to normalise that to just "ghc"
|
| 2980 | - s = re.sub('ghc-stage[123]', 'ghc', s)
|
|
| 2988 | + s = (s.replace('ghc-stage1', 'ghc')
|
|
| 2989 | + .replace('ghc-stage2', 'ghc')
|
|
| 2990 | + .replace('ghc-stage3', 'ghc'))
|
|
| 2981 | 2991 | # Remove platform prefix (e.g. javascript-unknown-ghcjs) for cross-compiled tools
|
| 2982 | 2992 | # (ghc, ghc-pkg, unlit, etc.)
|
| 2983 | 2993 | s = re.sub(r'\w+(-\w+)*-ghc', 'ghc', s)
|
| ... | ... | @@ -3000,7 +3010,7 @@ def normalise_errmsg(s: str) -> str: |
| 3000 | 3010 | # Also filter out bullet characters. This is because bullets are used to
|
| 3001 | 3011 | # separate error sections, and tests shouldn't be sensitive to how the
|
| 3002 | 3012 | # the division happens.
|
| 3003 | - bullet = '•'.encode('utf8') if isinstance(s, bytes) else '•'
|
|
| 3013 | + bullet = '•'
|
|
| 3004 | 3014 | s = s.replace(bullet, '')
|
| 3005 | 3015 | |
| 3006 | 3016 | # Windows only, this is a bug in hsc2hs but it is preventing
|
| ... | ... | @@ -3015,19 +3025,19 @@ def normalise_errmsg(s: str) -> str: |
| 3015 | 3025 | s = modify_lines(s, lambda l: re.sub(r'^(.+)warning: (.+): unsupported GNU_PROPERTY_TYPE (?:\(5\) )?type: 0xc000000(.*)$', '', l))
|
| 3016 | 3026 | |
| 3017 | 3027 | s = re.sub(r'ld: warning: passed .* min versions \(.*\) for platform macOS. Using [\.0-9]+.','',s)
|
| 3018 | - s = re.sub('ld: warning: -sdk_version and -platform_version are not compatible, ignoring -sdk_version','',s)
|
|
| 3028 | + s = s.replace('ld: warning: -sdk_version and -platform_version are not compatible, ignoring -sdk_version', '')
|
|
| 3019 | 3029 | # ignore superfluous dylibs passed to the linker.
|
| 3020 | - s = re.sub('ld: warning: .*, ignoring unexpected dylib file\n','',s)
|
|
| 3030 | + s = drop_lines_containing(s, 'ignoring unexpected dylib file')
|
|
| 3021 | 3031 | # ignore LLVM Version mismatch garbage; this will just break tests.
|
| 3022 | - s = re.sub('You are using an unsupported version of LLVM!.*\n','',s)
|
|
| 3023 | - s = re.sub('Currently only [\\.0-9]+ is supported. System LLVM version: [\\.0-9]+.*\n','',s)
|
|
| 3024 | - s = re.sub('We will try though\\.\\.\\..*\n','',s)
|
|
| 3032 | + s = drop_lines_containing(s, 'You are using an unsupported version of LLVM!')
|
|
| 3033 | + s = drop_lines_containing(s, 'System LLVM version:')
|
|
| 3034 | + s = drop_lines_containing(s, 'We will try though...')
|
|
| 3025 | 3035 | # ignore warning about strip invalidating signatures
|
| 3026 | - s = re.sub('.*strip: changes being made to the file will invalidate the code signature in.*\n','',s)
|
|
| 3036 | + s = drop_lines_containing(s, 'strip: changes being made to the file will invalidate the code signature in')
|
|
| 3027 | 3037 | # clang may warn about unused argument when used as assembler
|
| 3028 | - s = re.sub('.*warning: argument unused during compilation:.*\n', '', s)
|
|
| 3038 | + s = drop_lines_containing(s, 'warning: argument unused during compilation:')
|
|
| 3029 | 3039 | # Emscripten displays cache info and old emcc doesn't support EMCC_LOGGING=0
|
| 3030 | - s = re.sub('cache:INFO: .*\n', '', s)
|
|
| 3040 | + s = drop_lines_containing(s, 'cache:INFO:')
|
|
| 3031 | 3041 | # Old emcc warns when we export HEAP8 but new one requires it (see #26290)
|
| 3032 | 3042 | s = s.replace('warning: invalid item in EXPORTED_RUNTIME_METHODS: HEAP8\nwarning: invalid item in EXPORTED_RUNTIME_METHODS: HEAPU8\nemcc: warning: warnings in JS library compilation [-Wjs-compiler]\n','')
|
| 3033 | 3043 | |
| ... | ... | @@ -3050,7 +3060,7 @@ def normalise_prof (s: str) -> str: |
| 3050 | 3060 | |
| 3051 | 3061 | # The next step assumes none of the fields have no spaces in, which is broke
|
| 3052 | 3062 | # when the src = <no location info>
|
| 3053 | - s = re.sub('no location info','no-location-info', s)
|
|
| 3063 | + s = s.replace('no location info', 'no-location-info')
|
|
| 3054 | 3064 | |
| 3055 | 3065 | # Source locations from internal libraries, remove the source location
|
| 3056 | 3066 | # > libraries/ghc-internal/src/path/Foo.hs:204:1-18
|
| ... | ... | @@ -3103,21 +3113,21 @@ def normalise_prof (s: str) -> str: |
| 3103 | 3113 | return s
|
| 3104 | 3114 | |
| 3105 | 3115 | def normalise_slashes_( s: str ) -> str:
|
| 3106 | - s = re.sub(r'\\', '/', s)
|
|
| 3107 | - s = re.sub(r'//', '/', s)
|
|
| 3116 | + s = s.replace('\\', '/')
|
|
| 3117 | + s = s.replace('//', '/')
|
|
| 3108 | 3118 | return s
|
| 3109 | 3119 | |
| 3110 | 3120 | def normalise_exe_( s: str ) -> str:
|
| 3111 | - s = re.sub(r'\.exe', '', s)
|
|
| 3112 | - s = re.sub(r'\.wasm', '', s)
|
|
| 3113 | - s = re.sub(r'\.jsexe', '', s)
|
|
| 3121 | + s = s.replace('.exe', '')
|
|
| 3122 | + s = s.replace('.wasm', '')
|
|
| 3123 | + s = s.replace('.jsexe', '')
|
|
| 3114 | 3124 | return s
|
| 3115 | 3125 | |
| 3116 | 3126 | def normalise_output( s: str ) -> str:
|
| 3117 | 3127 | # remove " error:" and lower-case " Warning:" to make patch for
|
| 3118 | 3128 | # trac issue #10021 smaller
|
| 3119 | - s = modify_lines(s, lambda l: re.sub(' error:', '', l))
|
|
| 3120 | - s = modify_lines(s, lambda l: re.sub(' Warning:', ' warning:', l))
|
|
| 3129 | + s = modify_lines(s, lambda l: l.replace(' error:', ''))
|
|
| 3130 | + s = modify_lines(s, lambda l: l.replace(' Warning:', ' warning:'))
|
|
| 3121 | 3131 | # Remove a .exe extension (for Windows)
|
| 3122 | 3132 | # and .wasm extension (for the Wasm backend)
|
| 3123 | 3133 | # and .jsexe extension (for the JS backend)
|
| ... | ... | @@ -3129,19 +3139,19 @@ def normalise_output( s: str ) -> str: |
| 3129 | 3139 | s = normalise_type_reps(s)
|
| 3130 | 3140 | # ghci outputs are pretty unstable with -fexternal-dynamic-refs, which is
|
| 3131 | 3141 | # requires for -fPIC
|
| 3132 | - s = re.sub(' -fexternal-dynamic-refs\n','',s)
|
|
| 3142 | + s = s.replace(' -fexternal-dynamic-refs\n', '')
|
|
| 3133 | 3143 | s = re.sub(r'ld: warning: passed .* min versions \(.*\) for platform macOS. Using [\.0-9]+.','',s)
|
| 3134 | - s = re.sub('ld: warning: -sdk_version and -platform_version are not compatible, ignoring -sdk_version','',s)
|
|
| 3144 | + s = s.replace('ld: warning: -sdk_version and -platform_version are not compatible, ignoring -sdk_version', '')
|
|
| 3135 | 3145 | # ignore superfluous dylibs passed to the linker.
|
| 3136 | - s = re.sub('ld: warning: .*, ignoring unexpected dylib file\n','',s)
|
|
| 3146 | + s = drop_lines_containing(s, 'ignoring unexpected dylib file')
|
|
| 3137 | 3147 | # ignore LLVM Version mismatch garbage; this will just break tests.
|
| 3138 | - s = re.sub('You are using an unsupported version of LLVM!.*\n','',s)
|
|
| 3139 | - s = re.sub('Currently only [\\.0-9]+ is supported. System LLVM version: [\\.0-9]+.*\n','',s)
|
|
| 3140 | - s = re.sub('We will try though\\.\\.\\..*\n','',s)
|
|
| 3148 | + s = drop_lines_containing(s, 'You are using an unsupported version of LLVM!')
|
|
| 3149 | + s = drop_lines_containing(s, 'System LLVM version:')
|
|
| 3150 | + s = drop_lines_containing(s, 'We will try though...')
|
|
| 3141 | 3151 | # ignore warning about strip invalidating signatures
|
| 3142 | - s = re.sub('.*strip: changes being made to the file will invalidate the code signature in.*\n','',s)
|
|
| 3152 | + s = drop_lines_containing(s, 'strip: changes being made to the file will invalidate the code signature in')
|
|
| 3143 | 3153 | # clang may warn about unused argument when used as assembler
|
| 3144 | - s = re.sub('.*warning: argument unused during compilation:.*\n', '', s)
|
|
| 3154 | + s = drop_lines_containing(s, 'warning: argument unused during compilation:')
|
|
| 3145 | 3155 | |
| 3146 | 3156 | # strip the cross prefix if any
|
| 3147 | 3157 | s = re.sub(r'\w+(-\w+)*-ghc', 'ghc', s)
|
| ... | ... | @@ -40,6 +40,12 @@ def strip_quotes(s: str) -> str: |
| 40 | 40 | # Don't wrap commands to subprocess.call/Popen in quotes.
|
| 41 | 41 | return s.strip('\'"')
|
| 42 | 42 | |
| 43 | +# Python 3.7 compatibility shim for str.removeprefix (added in Python 3.9).
|
|
| 44 | +def str_removeprefix(s: str, prefix: str) -> str:
|
|
| 45 | + if s.startswith(prefix):
|
|
| 46 | + return s.replace(prefix, '', 1)
|
|
| 47 | + return s
|
|
| 48 | + |
|
| 43 | 49 | def str_warn(s: str) -> str:
|
| 44 | 50 | return colored(Color.YELLOW, s)
|
| 45 | 51 |
| ... | ... | @@ -3293,6 +3293,7 @@ module GHC.Base where |
| 3293 | 3293 | {-# MINIMAL fmap #-}
|
| 3294 | 3294 | type IO :: * -> *
|
| 3295 | 3295 | newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
|
| 3296 | + type role IP nominal representational
|
|
| 3296 | 3297 | type IP :: Symbol -> * -> Constraint
|
| 3297 | 3298 | class IP x a | x -> a where
|
| 3298 | 3299 | ip :: a
|
| ... | ... | @@ -3293,6 +3293,7 @@ module GHC.Base where |
| 3293 | 3293 | {-# MINIMAL fmap #-}
|
| 3294 | 3294 | type IO :: * -> *
|
| 3295 | 3295 | newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
|
| 3296 | + type role IP nominal representational
|
|
| 3296 | 3297 | type IP :: Symbol -> * -> Constraint
|
| 3297 | 3298 | class IP x a | x -> a where
|
| 3298 | 3299 | ip :: a
|
| ... | ... | @@ -3293,6 +3293,7 @@ module GHC.Base where |
| 3293 | 3293 | {-# MINIMAL fmap #-}
|
| 3294 | 3294 | type IO :: * -> *
|
| 3295 | 3295 | newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
|
| 3296 | + type role IP nominal representational
|
|
| 3296 | 3297 | type IP :: Symbol -> * -> Constraint
|
| 3297 | 3298 | class IP x a | x -> a where
|
| 3298 | 3299 | ip :: a
|
| ... | ... | @@ -3293,6 +3293,7 @@ module GHC.Base where |
| 3293 | 3293 | {-# MINIMAL fmap #-}
|
| 3294 | 3294 | type IO :: * -> *
|
| 3295 | 3295 | newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
|
| 3296 | + type role IP nominal representational
|
|
| 3296 | 3297 | type IP :: Symbol -> * -> Constraint
|
| 3297 | 3298 | class IP x a | x -> a where
|
| 3298 | 3299 | ip :: a
|
| ... | ... | @@ -1171,6 +1171,7 @@ module GHC.Classes where |
| 1171 | 1171 | (==) :: a -> a -> GHC.Internal.Types.Bool
|
| 1172 | 1172 | (/=) :: a -> a -> GHC.Internal.Types.Bool
|
| 1173 | 1173 | {-# MINIMAL (==) | (/=) #-}
|
| 1174 | + type role IP nominal representational
|
|
| 1174 | 1175 | type IP :: GHC.Internal.Types.Symbol -> * -> Constraint
|
| 1175 | 1176 | class IP x a | x -> a where
|
| 1176 | 1177 | ip :: a
|
| ... | ... | @@ -1171,6 +1171,7 @@ module GHC.Classes where |
| 1171 | 1171 | (==) :: a -> a -> GHC.Internal.Types.Bool
|
| 1172 | 1172 | (/=) :: a -> a -> GHC.Internal.Types.Bool
|
| 1173 | 1173 | {-# MINIMAL (==) | (/=) #-}
|
| 1174 | + type role IP nominal representational
|
|
| 1174 | 1175 | type IP :: GHC.Internal.Types.Symbol -> * -> Constraint
|
| 1175 | 1176 | class IP x a | x -> a where
|
| 1176 | 1177 | ip :: a
|
| 1 | -Main.funcToReify :: GHC.Internal.Classes.IP "z"
|
|
| 2 | - GHC.Internal.Types.Int =>
|
|
| 1 | +Main.funcToReify :: GHC.Internal.Classes.IP.IP "z"
|
|
| 2 | + GHC.Internal.Types.Int =>
|
|
| 3 | 3 | GHC.Internal.Types.Int
|
| 4 | 4 | 5
|
| 5 | 5 | 1
|
| 1 | +{-# LANGUAGE ImpredicativeTypes, ImplicitParams #-}
|
|
| 2 | + |
|
| 3 | +module T26737 where
|
|
| 4 | + |
|
| 5 | +import Data.Coerce
|
|
| 6 | + |
|
| 7 | +newtype Foo = MkFoo Int
|
|
| 8 | + |
|
| 9 | +b :: ((?foo :: Foo) => Int) -> ((?foo :: Int) => Int)
|
|
| 10 | +b = coerce @(((?foo :: Foo) => Int)) @(((?foo :: Int) => Int)) |
| ... | ... | @@ -958,3 +958,4 @@ test('T14745', normal, compile, ['']) |
| 958 | 958 | test('T26451', normal, compile, [''])
|
| 959 | 959 | test('T26582', normal, compile, [''])
|
| 960 | 960 | test('T26746', normal, compile, [''])
|
| 961 | +test('T26737', normal, compile, ['']) |
| ... | ... | @@ -480,13 +480,8 @@ mkTarget opts = do |
| 480 | 480 | opt <- optional $ findProgram "opt" (optOpt opts) ["opt"]
|
| 481 | 481 | llvmAs <- optional $ findProgram "llvm assembler" (optLlvmAs opts) ["clang"]
|
| 482 | 482 | |
| 483 | - -- Windows-specific utilities
|
|
| 484 | - windres <-
|
|
| 485 | - case archOS_OS archOs of
|
|
| 486 | - OSMinGW32 -> do
|
|
| 487 | - windres <- findProgram "windres" (optWindres opts) ["windres"]
|
|
| 488 | - return (Just windres)
|
|
| 489 | - _ -> return Nothing
|
|
| 483 | + -- for windows, also used for cross compiling
|
|
| 484 | + windres <- optional $ findProgram "windres" (optWindres opts) ["windres"]
|
|
| 490 | 485 | |
| 491 | 486 | -- Darwin-specific utilities
|
| 492 | 487 | (otool, installNameTool) <-
|