Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
beae879b
by Rodrigo Mesquita at 2025-12-03T15:42:37+01:00
-
1b88b0bc
by mangoiv at 2025-12-03T18:15:08-05:00
-
93a4d388
by Zubin Duggal at 2025-12-03T18:15:11-05:00
-
4ed9a10a
by Zubin Duggal at 2025-12-03T18:15:11-05:00
-
420913f9
by Cheng Shao at 2025-12-03T18:15:12-05:00
18 changed files:
- compile_flags.txt
- compiler/GHC/CmmToAsm/AArch64/RegInfo.hs
- compiler/GHC/CmmToAsm/PPC/RegInfo.hs
- compiler/GHC/Core/Map/Type.hs
- compiler/GHC/Driver/LlvmConfigCache.hs
- compiler/GHC/Driver/Pipeline/Phases.hs
- compiler/GHC/Tc/Utils/Env.hs
- testsuite/driver/testlib.py
- + testsuite/tests/driver/T20696/T20696.stderr-ext-interp
- testsuite/tests/driver/T20696/all.T
- testsuite/tests/driver/fat-iface/all.T
- + testsuite/tests/driver/fat-iface/fat012.stderr-ext-interp
- + testsuite/tests/driver/fat-iface/fat015.stderr-ext-interp
- + testsuite/tests/splice-imports/SI07.stderr-ext-interp
- testsuite/tests/splice-imports/all.T
- + testsuite/tests/th/T26099.hs
- + testsuite/tests/th/T26099.stderr
- testsuite/tests/th/all.T
Changes:
| 1 | +-fPIC
|
|
| 2 | +-U__PIC__
|
|
| 3 | +-D__PIC__
|
|
| 1 | 4 | -Wimplicit
|
| 2 | 5 | -include
|
| 3 | 6 | rts/include/ghcversion.h
|
| ... | ... | @@ -27,3 +30,4 @@ rts/include/ghcversion.h |
| 27 | 30 | -DDEBUG
|
| 28 | 31 | -DDYNAMIC
|
| 29 | 32 | -DPROFILING
|
| 33 | +-DRtsWay="rts_thr_debug_p_dyn" |
| ... | ... | @@ -8,7 +8,7 @@ import GHC.Cmm |
| 8 | 8 | |
| 9 | 9 | import GHC.Utils.Outputable
|
| 10 | 10 | |
| 11 | -data JumpDest = DestBlockId BlockId
|
|
| 11 | +newtype JumpDest = DestBlockId BlockId
|
|
| 12 | 12 | |
| 13 | 13 | -- Debug Instance
|
| 14 | 14 | instance Outputable JumpDest where
|
| ... | ... | @@ -27,7 +27,7 @@ import GHC.Cmm.CLabel |
| 27 | 27 | import GHC.Types.Unique
|
| 28 | 28 | import GHC.Utils.Outputable (ppr, text, Outputable, (<>))
|
| 29 | 29 | |
| 30 | -data JumpDest = DestBlockId BlockId
|
|
| 30 | +newtype JumpDest = DestBlockId BlockId
|
|
| 31 | 31 | |
| 32 | 32 | -- Debug Instance
|
| 33 | 33 | instance Outputable JumpDest where
|
| ... | ... | @@ -554,7 +554,7 @@ instance Eq (DeBruijn a) => Eq (DeBruijn (Maybe a)) where |
| 554 | 554 | -- We also need to do the same for multiplicity! Which, since multiplicities are
|
| 555 | 555 | -- encoded simply as a 'Type', amounts to have a Trie for a pair of types. Tries
|
| 556 | 556 | -- of pairs are composition.
|
| 557 | -data BndrMap a = BndrMap (TypeMapG (MaybeMap TypeMapG a))
|
|
| 557 | +newtype BndrMap a = BndrMap (TypeMapG (MaybeMap TypeMapG a))
|
|
| 558 | 558 | |
| 559 | 559 | -- TODO(22292): derive
|
| 560 | 560 | instance Functor BndrMap where
|
| ... | ... | @@ -18,6 +18,8 @@ import System.IO.Unsafe |
| 18 | 18 | -- Currently implemented with unsafe lazy IO. But it could be implemented with
|
| 19 | 19 | -- an IORef as the exposed interface is in IO.
|
| 20 | 20 | data LlvmConfigCache = LlvmConfigCache LlvmConfig
|
| 21 | +-- NB: It is crucial for this to be a datatype, not a newtype.
|
|
| 22 | +-- Allocations can increase across the board over 20% otherwise (see the discussion on !10708 and non-final pipelines)
|
|
| 21 | 23 | |
| 22 | 24 | initLlvmConfigCache :: FilePath -> IO LlvmConfigCache
|
| 23 | 25 | initLlvmConfigCache top_dir = pure $ LlvmConfigCache (unsafePerformIO $ initLlvmConfig top_dir)
|
| ... | ... | @@ -52,4 +52,4 @@ data TPhase res where |
| 52 | 52 | T_MergeForeign :: PipeEnv -> HscEnv -> FilePath -> [FilePath] -> TPhase FilePath
|
| 53 | 53 | |
| 54 | 54 | -- | A wrapper around the interpretation function for phases.
|
| 55 | -data PhaseHook = PhaseHook (forall a . TPhase a -> IO a) |
|
| 55 | +newtype PhaseHook = PhaseHook (forall a . TPhase a -> IO a) |
| ... | ... | @@ -8,6 +8,7 @@ |
| 8 | 8 | -- in module Language.Haskell.Syntax.Extension
|
| 9 | 9 | {-# LANGUAGE TypeFamilies #-}
|
| 10 | 10 | {-# LANGUAGE LambdaCase #-}
|
| 11 | +{-# LANGUAGE MultiWayIf #-}
|
|
| 11 | 12 | |
| 12 | 13 | module GHC.Tc.Utils.Env(
|
| 13 | 14 | TyThing(..), TcTyThing(..), TcId,
|
| ... | ... | @@ -1213,6 +1214,20 @@ pprBinders bndrs = pprWithCommas ppr bndrs |
| 1213 | 1214 | notFound :: Name -> TcM TyThing
|
| 1214 | 1215 | notFound name
|
| 1215 | 1216 | = do { lcl_env <- getLclEnv
|
| 1217 | + ; lvls <- getCurrentAndBindLevel name
|
|
| 1218 | + ; if -- See Note [Out of scope might be a staging error]
|
|
| 1219 | + | isUnboundName name -> failM -- If the name really isn't in scope
|
|
| 1220 | + -- don't report it again (#11941)
|
|
| 1221 | + -- the
|
|
| 1222 | + -- the 'Nothing' case of 'getCurrentAndBindLevel'
|
|
| 1223 | + -- currently means 'isUnboundName' but to avoid
|
|
| 1224 | + -- introducing bugs after a refactoring of that
|
|
| 1225 | + -- function, we check this completely independently
|
|
| 1226 | + -- before scrutinizing lvls
|
|
| 1227 | + | Just (_top_lvl_flag, bind_lvls, lvl@Splice {}) <- lvls
|
|
| 1228 | + -> failWithTc (TcRnBadlyLevelled (LevelCheckSplice name Nothing) bind_lvls (thLevelIndex lvl) Nothing ErrorWithoutFlag)
|
|
| 1229 | + | otherwise -> pure ()
|
|
| 1230 | + |
|
| 1216 | 1231 | ; if isTermVarOrFieldNameSpace (nameNameSpace name)
|
| 1217 | 1232 | then
|
| 1218 | 1233 | -- This code path is only reachable with RequiredTypeArguments enabled
|
| ... | ... | @@ -1243,14 +1258,23 @@ wrongThingErr expected thing name = |
| 1243 | 1258 | {- Note [Out of scope might be a staging error]
|
| 1244 | 1259 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1245 | 1260 | Consider
|
| 1246 | - x = 3
|
|
| 1247 | - data T = MkT $(foo x)
|
|
| 1261 | + type T = Int
|
|
| 1262 | + foo = $(1 :: T)
|
|
| 1263 | + |
|
| 1264 | +GHC currently leaves the user some liberty when it comes to using
|
|
| 1265 | +types in a manner that is theoretically not well-staged.
|
|
| 1266 | +E.g. if `T` here were to be a value, we would reject the program with
|
|
| 1267 | +a staging error. Since it is a type though, we allow it for backwards
|
|
| 1268 | +compatibility reasons.
|
|
| 1269 | + |
|
| 1270 | +However, in this case, we're just in the process of renaming a splice
|
|
| 1271 | +when trying to type check an expression involving a type, that hasn't
|
|
| 1272 | +even been added to the (type checking) environment yet. That is, why
|
|
| 1273 | +it is out of scope.
|
|
| 1248 | 1274 | |
| 1249 | -where 'foo' is imported from somewhere.
|
|
| 1275 | +The reason why we cannot recognise this issue earlier is, that if we
|
|
| 1276 | +are not actually type checking the splice, i.e. if we're only using the
|
|
| 1277 | +name of the type (e.g. ''T), the program should be accepted.
|
|
| 1250 | 1278 | |
| 1251 | -This is really a staging error, because we can't run code involving 'x'.
|
|
| 1252 | -But in fact the type checker processes types first, so 'x' won't even be
|
|
| 1253 | -in the type envt when we look for it in $(foo x). So inside splices we
|
|
| 1254 | -report something missing from the type env as a staging error.
|
|
| 1255 | -See #5752 and #5795.
|
|
| 1279 | +We stop and report a staging error.
|
|
| 1256 | 1280 | -} |
| ... | ... | @@ -1971,7 +1971,7 @@ async def do_compile(name: TestName, |
| 1971 | 1971 | # of whether we expected the compilation to fail or not (successful
|
| 1972 | 1972 | # compilations may generate warnings).
|
| 1973 | 1973 | |
| 1974 | - expected_stderr_file = find_expected_file(name, 'stderr')
|
|
| 1974 | + expected_stderr_file = find_expected_file(name, 'stderr', way)
|
|
| 1975 | 1975 | actual_stderr_file = add_suffix(name, 'comp.stderr')
|
| 1976 | 1976 | diff_file_name = in_testdir(add_suffix(name, 'comp.diff'))
|
| 1977 | 1977 | |
| ... | ... | @@ -2012,7 +2012,7 @@ async def compile_cmp_asm(name: TestName, |
| 2012 | 2012 | # of whether we expected the compilation to fail or not (successful
|
| 2013 | 2013 | # compilations may generate warnings).
|
| 2014 | 2014 | |
| 2015 | - expected_asm_file = find_expected_file(name, 'asm')
|
|
| 2015 | + expected_asm_file = find_expected_file(name, 'asm', way)
|
|
| 2016 | 2016 | actual_asm_file = add_suffix(name, 's')
|
| 2017 | 2017 | |
| 2018 | 2018 | if not await compare_outputs(way, 'asm',
|
| ... | ... | @@ -2036,7 +2036,7 @@ async def compile_grep_asm(name: TestName, |
| 2036 | 2036 | if badResult(result):
|
| 2037 | 2037 | return result
|
| 2038 | 2038 | |
| 2039 | - expected_pat_file = find_expected_file(name, 'asm')
|
|
| 2039 | + expected_pat_file = find_expected_file(name, 'asm', way)
|
|
| 2040 | 2040 | actual_asm_file = add_suffix(name, 's')
|
| 2041 | 2041 | |
| 2042 | 2042 | if not grep_output(join_normalisers(normalise_errmsg),
|
| ... | ... | @@ -2058,7 +2058,7 @@ async def compile_grep_core(name: TestName, |
| 2058 | 2058 | if badResult(result):
|
| 2059 | 2059 | return result
|
| 2060 | 2060 | |
| 2061 | - expected_pat_file = find_expected_file(name, 'substr-simpl')
|
|
| 2061 | + expected_pat_file = find_expected_file(name, 'substr-simpl', way)
|
|
| 2062 | 2062 | actual_core_file = add_suffix(name, 'dump-simpl')
|
| 2063 | 2063 | |
| 2064 | 2064 | if not grep_output(join_normalisers(normalise_errmsg),
|
| ... | ... | @@ -2097,7 +2097,7 @@ async def compile_and_run__(name: TestName, |
| 2097 | 2097 | return result
|
| 2098 | 2098 | |
| 2099 | 2099 | if compile_stderr:
|
| 2100 | - expected_stderr_file = find_expected_file(name, 'ghc.stderr')
|
|
| 2100 | + expected_stderr_file = find_expected_file(name, 'ghc.stderr', way)
|
|
| 2101 | 2101 | actual_stderr_file = add_suffix(name, 'comp.stderr')
|
| 2102 | 2102 | diff_file_name = in_testdir(add_suffix(name, 'comp.diff'))
|
| 2103 | 2103 | |
| ... | ... | @@ -2556,7 +2556,7 @@ def get_compiler_flags() -> List[str]: |
| 2556 | 2556 | |
| 2557 | 2557 | async def stdout_ok(name: TestName, way: WayName) -> bool:
|
| 2558 | 2558 | actual_stdout_file = add_suffix(name, 'run.stdout')
|
| 2559 | - expected_stdout_file = find_expected_file(name, 'stdout')
|
|
| 2559 | + expected_stdout_file = find_expected_file(name, 'stdout', way)
|
|
| 2560 | 2560 | |
| 2561 | 2561 | extra_norm = join_normalisers(normalise_output, getTestOpts().extra_normaliser)
|
| 2562 | 2562 | |
| ... | ... | @@ -2583,7 +2583,7 @@ def dump_stdout( name: TestName ) -> None: |
| 2583 | 2583 | |
| 2584 | 2584 | async def stderr_ok(name: TestName, way: WayName) -> bool:
|
| 2585 | 2585 | actual_stderr_file = add_suffix(name, 'run.stderr')
|
| 2586 | - expected_stderr_file = find_expected_file(name, 'stderr')
|
|
| 2586 | + expected_stderr_file = find_expected_file(name, 'stderr', way)
|
|
| 2587 | 2587 | |
| 2588 | 2588 | return await compare_outputs(way, 'stderr',
|
| 2589 | 2589 | join_normalisers(normalise_errmsg, getTestOpts().extra_errmsg_normaliser), \
|
| ... | ... | @@ -2688,7 +2688,7 @@ async def check_hp_ok(name: TestName) -> bool: |
| 2688 | 2688 | return False
|
| 2689 | 2689 | |
| 2690 | 2690 | async def check_prof_ok(name: TestName, way: WayName) -> bool:
|
| 2691 | - expected_prof_file = find_expected_file(name, 'prof.sample')
|
|
| 2691 | + expected_prof_file = find_expected_file(name, 'prof.sample', way)
|
|
| 2692 | 2692 | expected_prof_path = in_testdir(expected_prof_file)
|
| 2693 | 2693 | |
| 2694 | 2694 | # Check actual prof file only if we have an expected prof file to
|
| ... | ... | @@ -3368,18 +3368,19 @@ def in_statsdir(name: Union[Path, str], suffix: str='') -> Path: |
| 3368 | 3368 | |
| 3369 | 3369 | # Finding the sample output. The filename is of the form
|
| 3370 | 3370 | #
|
| 3371 | -# <test>.stdout[-ws-<wordsize>][-<platform>|-<os>]
|
|
| 3371 | +# <test>.stdout[-ws-<wordsize>][-<platform>|-<os>][-<way>]
|
|
| 3372 | 3372 | #
|
| 3373 | -def find_expected_file(name: TestName, suff: str) -> Path:
|
|
| 3373 | +def find_expected_file(name: TestName, suff: str, way: WayName) -> Path:
|
|
| 3374 | 3374 | basename = add_suffix(name, suff)
|
| 3375 | 3375 | # Override the basename if the user has specified one, this will then be
|
| 3376 | 3376 | # subjected to the same name mangling scheme as normal to allow platform
|
| 3377 | 3377 | # specific overrides to work.
|
| 3378 | 3378 | basename = getTestOpts().use_specs.get(suff, basename)
|
| 3379 | 3379 | |
| 3380 | - files = [str(basename) + ws + plat
|
|
| 3380 | + files = [str(basename) + ws + plat + way_ext
|
|
| 3381 | 3381 | for plat in ['-' + config.platform, '-' + config.os, '']
|
| 3382 | - for ws in ['-ws-' + config.wordsize, '']]
|
|
| 3382 | + for ws in ['-ws-' + config.wordsize, '']
|
|
| 3383 | + for way_ext in ['-' + way, '']]
|
|
| 3383 | 3384 | |
| 3384 | 3385 | for f in files:
|
| 3385 | 3386 | if in_srcdir(f).exists():
|
| 1 | +[1 of 3] Compiling C ( C.hs, C.o )
|
|
| 2 | +[2 of 3] Compiling B ( B.hs, B.o )
|
|
| 3 | +[3 of 3] Compiling A ( A.hs, A.o ) |
| 1 | 1 | test('T20696', [extra_files(['A.hs', 'B.hs', 'C.hs'])
|
| 2 | - , expect_broken_for(26552, ['ext-interp'])
|
|
| 3 | 2 | , unless(ghc_dynamic(), skip)], multimod_compile, ['A', ''])
|
| 4 | 3 | test('T20696-static', [extra_files(['A.hs', 'B.hs', 'C.hs'])
|
| 5 | 4 | , when(ghc_dynamic(), skip)], multimod_compile, ['A', '']) |
| ... | ... | @@ -9,12 +9,12 @@ test('fat010', [req_th,extra_files(['THA.hs', 'THB.hs', 'THC.hs']), copy_files], |
| 9 | 9 | # Check linking works when using -fbyte-code-and-object-code
|
| 10 | 10 | test('fat011', [req_th, extra_files(['FatMain.hs', 'FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatMain', '-fbyte-code-and-object-code -fprefer-byte-code'])
|
| 11 | 11 | # Check that we use interpreter rather than enable dynamic-too if needed for TH
|
| 12 | -test('fat012', [req_th, expect_broken_for(26552, ['ext-interp']), unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fprefer-byte-code'])
|
|
| 12 | +test('fat012', [req_th, unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fprefer-byte-code'])
|
|
| 13 | 13 | # Check that no objects are generated if using -fno-code and -fprefer-byte-code
|
| 14 | 14 | test('fat013', [req_th, req_bco, extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fno-code -fprefer-byte-code'])
|
| 15 | 15 | # When using interpreter should not produce objects
|
| 16 | 16 | test('fat014', [req_th, extra_files(['FatTH.hs', 'FatQuote.hs']), extra_run_opts('-fno-code')], ghci_script, ['fat014.script'])
|
| 17 | -test('fat015', [req_th, expect_broken_for(26552, ['ext-interp']), unless(ghc_dynamic(), skip), extra_files(['FatQuote.hs', 'FatQuote1.hs', 'FatQuote2.hs', 'FatTH1.hs', 'FatTH2.hs', 'FatTHTop.hs'])], multimod_compile, ['FatTHTop', '-fno-code -fwrite-interface'])
|
|
| 17 | +test('fat015', [req_th, unless(ghc_dynamic(), skip), extra_files(['FatQuote.hs', 'FatQuote1.hs', 'FatQuote2.hs', 'FatTH1.hs', 'FatTH2.hs', 'FatTHTop.hs'])], multimod_compile, ['FatTHTop', '-fno-code -fwrite-interface'])
|
|
| 18 | 18 | test('T22807', [req_th, unless(ghc_dynamic(), skip), extra_files(['T22807A.hs', 'T22807B.hs'])]
|
| 19 | 19 | , makefile_test, ['T22807'])
|
| 20 | 20 | test('T22807_ghci', [req_th, unless(ghc_dynamic(), skip), extra_files(['T22807_ghci.hs'])]
|
| 1 | +[1 of 2] Compiling FatQuote ( FatQuote.hs, FatQuote.o )
|
|
| 2 | +[2 of 2] Compiling FatTH ( FatTH.hs, FatTH.o ) |
| 1 | +[1 of 6] Compiling FatQuote ( FatQuote.hs, FatQuote.o, interpreted )
|
|
| 2 | +[2 of 6] Compiling FatQuote1 ( FatQuote1.hs, interpreted )
|
|
| 3 | +[3 of 6] Compiling FatQuote2 ( FatQuote2.hs, FatQuote2.o )
|
|
| 4 | +[4 of 6] Compiling FatTH1 ( FatTH1.hs, nothing )
|
|
| 5 | +[5 of 6] Compiling FatTH2 ( FatTH2.hs, nothing )
|
|
| 6 | +[6 of 6] Compiling FatTHTop ( FatTHTop.hs, nothing ) |
| 1 | +[1 of 3] Compiling SI05A ( SI05A.hs, SI05A.o )
|
|
| 2 | +[2 of 3] Compiling SI07A ( SI07A.hs, nothing )
|
|
| 3 | +[3 of 3] Compiling SI07 ( SI07.hs, nothing ) |
| ... | ... | @@ -9,7 +9,7 @@ test('SI03', [extra_files(["SI01A.hs"])], multimod_compile_fail, ['SI03', '-v0'] |
| 9 | 9 | test('SI04', [extra_files(["SI01A.hs"])], multimod_compile, ['SI04', '-v0'])
|
| 10 | 10 | test('SI05', [extra_files(["SI01A.hs"])], multimod_compile_fail, ['SI05', '-v0'])
|
| 11 | 11 | test('SI06', [extra_files(["SI01A.hs"])], multimod_compile, ['SI06', '-v0'])
|
| 12 | -test('SI07', [expect_broken_for(26552, ['ext-interp']), unless(ghc_dynamic(), skip), extra_files(["SI05A.hs"])], multimod_compile, ['SI07', '-fwrite-interface -fno-code'])
|
|
| 12 | +test('SI07', [unless(ghc_dynamic(), skip), extra_files(["SI05A.hs"])], multimod_compile, ['SI07', '-fwrite-interface -fno-code'])
|
|
| 13 | 13 | # Instance tests
|
| 14 | 14 | test('SI08', [extra_files(["ClassA.hs", "InstanceA.hs"])], multimod_compile_fail, ['SI08', '-v0'])
|
| 15 | 15 | test('SI09', [extra_files(["ClassA.hs", "InstanceA.hs"])], multimod_compile, ['SI09', '-v0'])
|
| 1 | +{-# LANGUAGE TemplateHaskell #-}
|
|
| 2 | +module M where
|
|
| 3 | + |
|
| 4 | +type T = Int
|
|
| 5 | + |
|
| 6 | +a = $(3 :: T) |
| 1 | +T26099.hs:6:12: error: [GHC-28914]
|
|
| 2 | + • Level error: ‘T’ is bound at level 0 but used at level -1
|
|
| 3 | + • In an expression type signature: T
|
|
| 4 | + In the expression: 3 :: T
|
|
| 5 | + In the untyped splice: $(3 :: T)
|
|
| 6 | + |
| ... | ... | @@ -642,3 +642,4 @@ test('QQInQuote', normal, compile, ['']) |
| 642 | 642 | test('QQTopError', normal, compile_fail, ['-fdiagnostics-show-caret'])
|
| 643 | 643 | test('GadtConSigs_th_pprint1', normal, compile, [''])
|
| 644 | 644 | test('GadtConSigs_th_dump1', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques'])
|
| 645 | +test('T26099', normal, compile_fail, ['']) |