Cheng Shao pushed to branch wip/T24052 at Glasgow Haskell Compiler / GHC Commits: beae879b by Rodrigo Mesquita at 2025-12-03T15:42:37+01:00 task: Substitute some datatypes for newtypes * Substitutes some data type declarations for newtype declarations * Adds comment to `LlvmConfigCache`, which must decidedly not be a newtype. Fixes #23555 - - - - - 3bd7dd44 by mangoiv at 2025-12-04T04:36:45-05:00 Renamer: reinstate the template haskell level check in notFound Out-of-scope names might be caused by a staging error, as is explained by Note [Out of scope might be a staging error] in GHC.Tc.Utils.Env.hs. This logic was assumed to be dead code after 217caad1 and has thus been removed. This commit reintroduces it and thus fixes issue #26099. - - - - - 0318010b by Zubin Duggal at 2025-12-04T04:37:27-05:00 testlib: Optionally include the way name in the expected output file This allows us to have different outputs for different ways. - - - - - 6d945fdd by Zubin Duggal at 2025-12-04T04:37:27-05:00 testsuite: Accept output of tests failing in ext-interp way due to differing compilation requirements Fixes #26552 - - - - - 0ffc5243 by Cheng Shao at 2025-12-04T04:38:09-05:00 devx: minor fixes for compile_flags.txt This patch includes minor fixes for compile_flags.txt to improve developer experience when using clangd as language server to hack on RTS C sources: - Ensure `-fPIC` is passed and `__PIC__` is defined, to be coherent with `-DDYNAMIC` and ensure the `__PIC__` guarded code paths are indexed - Add the missing `-DRtsWay` definition, otherwise a few source files like `RtsUtils.c` and `Trace.c` would produce clangd errors - - - - - 0c92f6d9 by Ben Gamari at 2025-12-05T02:45:50+01:00 testsuite: Fix invalid string literal `"\+"` is not a valid Python string; this should have been `r"\+"`. - - - - - 4682b93d by Ben Gamari at 2025-12-05T02:45:50+01:00 rts/nonmoving: Reflow notes - - - - - 3dea9e1a by Ben Gamari at 2025-12-05T02:45:50+01:00 testsuite: Run some tests unconditionally in nonmoving ways Improve test coverage of the nonmoving collector by running a small subset of tests unconditionally with the nonmoving collector. Fixes #24052. - - - - - 21 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 - rts/sm/NonMoving.c - testsuite/driver/testlib.py - testsuite/tests/array/should_run/all.T - testsuite/tests/concurrent/should_run/all.T - + 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: ===================================== compile_flags.txt ===================================== @@ -1,3 +1,6 @@ +-fPIC +-U__PIC__ +-D__PIC__ -Wimplicit -include rts/include/ghcversion.h @@ -27,3 +30,4 @@ rts/include/ghcversion.h -DDEBUG -DDYNAMIC -DPROFILING +-DRtsWay="rts_thr_debug_p_dyn" ===================================== compiler/GHC/CmmToAsm/AArch64/RegInfo.hs ===================================== @@ -8,7 +8,7 @@ import GHC.Cmm import GHC.Utils.Outputable -data JumpDest = DestBlockId BlockId +newtype JumpDest = DestBlockId BlockId -- Debug Instance instance Outputable JumpDest where ===================================== compiler/GHC/CmmToAsm/PPC/RegInfo.hs ===================================== @@ -27,7 +27,7 @@ import GHC.Cmm.CLabel import GHC.Types.Unique import GHC.Utils.Outputable (ppr, text, Outputable, (<>)) -data JumpDest = DestBlockId BlockId +newtype JumpDest = DestBlockId BlockId -- Debug Instance instance Outputable JumpDest where ===================================== compiler/GHC/Core/Map/Type.hs ===================================== @@ -554,7 +554,7 @@ instance Eq (DeBruijn a) => Eq (DeBruijn (Maybe a)) where -- We also need to do the same for multiplicity! Which, since multiplicities are -- encoded simply as a 'Type', amounts to have a Trie for a pair of types. Tries -- of pairs are composition. -data BndrMap a = BndrMap (TypeMapG (MaybeMap TypeMapG a)) +newtype BndrMap a = BndrMap (TypeMapG (MaybeMap TypeMapG a)) -- TODO(22292): derive instance Functor BndrMap where ===================================== compiler/GHC/Driver/LlvmConfigCache.hs ===================================== @@ -18,6 +18,8 @@ import System.IO.Unsafe -- Currently implemented with unsafe lazy IO. But it could be implemented with -- an IORef as the exposed interface is in IO. data LlvmConfigCache = LlvmConfigCache LlvmConfig +-- NB: It is crucial for this to be a datatype, not a newtype. +-- Allocations can increase across the board over 20% otherwise (see the discussion on !10708 and non-final pipelines) initLlvmConfigCache :: FilePath -> IO LlvmConfigCache initLlvmConfigCache top_dir = pure $ LlvmConfigCache (unsafePerformIO $ initLlvmConfig top_dir) ===================================== compiler/GHC/Driver/Pipeline/Phases.hs ===================================== @@ -52,4 +52,4 @@ data TPhase res where T_MergeForeign :: PipeEnv -> HscEnv -> FilePath -> [FilePath] -> TPhase FilePath -- | A wrapper around the interpretation function for phases. -data PhaseHook = PhaseHook (forall a . TPhase a -> IO a) +newtype PhaseHook = PhaseHook (forall a . TPhase a -> IO a) ===================================== compiler/GHC/Tc/Utils/Env.hs ===================================== @@ -8,6 +8,7 @@ -- in module Language.Haskell.Syntax.Extension {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MultiWayIf #-} module GHC.Tc.Utils.Env( TyThing(..), TcTyThing(..), TcId, @@ -1213,6 +1214,20 @@ pprBinders bndrs = pprWithCommas ppr bndrs notFound :: Name -> TcM TyThing notFound name = do { lcl_env <- getLclEnv + ; lvls <- getCurrentAndBindLevel name + ; if -- See Note [Out of scope might be a staging error] + | isUnboundName name -> failM -- If the name really isn't in scope + -- don't report it again (#11941) + -- the + -- the 'Nothing' case of 'getCurrentAndBindLevel' + -- currently means 'isUnboundName' but to avoid + -- introducing bugs after a refactoring of that + -- function, we check this completely independently + -- before scrutinizing lvls + | Just (_top_lvl_flag, bind_lvls, lvl@Splice {}) <- lvls + -> failWithTc (TcRnBadlyLevelled (LevelCheckSplice name Nothing) bind_lvls (thLevelIndex lvl) Nothing ErrorWithoutFlag) + | otherwise -> pure () + ; if isTermVarOrFieldNameSpace (nameNameSpace name) then -- This code path is only reachable with RequiredTypeArguments enabled @@ -1243,14 +1258,23 @@ wrongThingErr expected thing name = {- Note [Out of scope might be a staging error] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider - x = 3 - data T = MkT $(foo x) + type T = Int + foo = $(1 :: T) + +GHC currently leaves the user some liberty when it comes to using +types in a manner that is theoretically not well-staged. +E.g. if `T` here were to be a value, we would reject the program with +a staging error. Since it is a type though, we allow it for backwards +compatibility reasons. + +However, in this case, we're just in the process of renaming a splice +when trying to type check an expression involving a type, that hasn't +even been added to the (type checking) environment yet. That is, why +it is out of scope. -where 'foo' is imported from somewhere. +The reason why we cannot recognise this issue earlier is, that if we +are not actually type checking the splice, i.e. if we're only using the +name of the type (e.g. ''T), the program should be accepted. -This is really a staging error, because we can't run code involving 'x'. -But in fact the type checker processes types first, so 'x' won't even be -in the type envt when we look for it in $(foo x). So inside splices we -report something missing from the type env as a staging error. -See #5752 and #5795. +We stop and report a staging error. -} ===================================== rts/sm/NonMoving.c ===================================== @@ -151,9 +151,9 @@ static void nonmovingBumpEpoch(void) { * 3. [STW] Root collection: Here we walk over a variety of root sources * and add them to the mark queue (see nonmovingCollect). * - * 4. [CONC] Concurrent marking: Here we do the majority of marking concurrently - * with mutator execution (but with the write barrier enabled; see - * Note [Update remembered set]). + * 4. [CONC] Concurrent marking: Here we do the majority of marking + * concurrently with mutator execution (but with the write barrier enabled; + * see Note [Update remembered set]). * * 5. [STW] Final sync: Here we interrupt the mutators, ask them to * flush their final update remembered sets, and mark any new references @@ -218,9 +218,9 @@ static void nonmovingBumpEpoch(void) { * - Note [Concurrent read barrier on deRefWeak#] (NonMovingMark.c) describes * the read barrier on Weak# objects. * - * - Note [Unintentional marking in resurrectThreads] (NonMovingMark.c) describes - * a tricky interaction between the update remembered set flush and weak - * finalization. + * - Note [Unintentional marking in resurrectThreads] (NonMovingMark.c) + * describes a tricky interaction between the update remembered set flush and + * weak finalization. * * - Note [Origin references in the nonmoving collector] (NonMovingMark.h) * describes how we implement indirection short-cutting and the selector @@ -229,8 +229,8 @@ static void nonmovingBumpEpoch(void) { * - Note [StgStack dirtiness flags and concurrent marking] (TSO.h) describes * the protocol for concurrent marking of stacks. * - * - Note [Nonmoving write barrier in Perform{Put,Take}] (PrimOps.cmm) describes - * a tricky barrier necessary when resuming threads blocked on MVar + * - Note [Nonmoving write barrier in Perform{Put,Take}] (PrimOps.cmm) + * describes a tricky barrier necessary when resuming threads blocked on MVar * operations. * * - Note [Static objects under the nonmoving collector] (Storage.c) describes @@ -240,13 +240,17 @@ static void nonmovingBumpEpoch(void) { * how we use the DIRTY flags associated with MUT_VARs and TVARs to improve * barrier efficiency. * - * - Note [Weak pointer processing and the non-moving GC] (MarkWeak.c) describes - * how weak pointers are handled when the non-moving GC is in use. + * - Note [Weak pointer processing and the non-moving GC] (MarkWeak.c) + * describes how weak pointers are handled when the non-moving GC is in use. * * - Note [Sync phase marking budget] describes how we avoid long mutator * pauses during the sync phase * - * - Note [Allocator sizes] goes into detail about our choice of allocator sizes. + * - Note [Allocator sizes] goes into detail about our choice of allocator + * sizes. + * + * - Note [Testing the nonmoving collector] describes how we test the + * collector. * * - Note [Segment allocation strategy] explains our segment allocation strategy. * @@ -261,15 +265,15 @@ static void nonmovingBumpEpoch(void) { * Concurrency-control of non-moving garbage collection is a bit tricky. There * are a few things to keep in mind: * - * - Only one non-moving collection may be active at a time. This is enforced by the - * concurrent_coll_running flag, which is set when a collection is on-going. If - * we attempt to initiate a new collection while this is set we wait on the - * concurrent_coll_finished condition variable, which signals when the - * active collection finishes. + * - Only one non-moving collection may be active at a time. This is enforced + * by the concurrent_coll_running flag, which is set when a collection is + * on-going. If we attempt to initiate a new collection while this is set we + * wait on the concurrent_coll_finished condition variable, which signals + * when the active collection finishes. * - * - In between the mark and sweep phases the non-moving collector must synchronize - * with mutator threads to collect and mark their final update remembered - * sets. This is accomplished using + * - In between the mark and sweep phases the non-moving collector must + * synchronize with mutator threads to collect and mark their final update + * remembered sets. This is accomplished using * stopAllCapabilitiesWith(SYNC_FLUSH_UPD_REM_SET). Capabilities are held * the final mark has concluded. * @@ -363,9 +367,9 @@ static void nonmovingBumpEpoch(void) { * ╰─────────────────╯ * ┆ * - * In this case we have a TSO blocked on a dead MVar. Because the MVAR_TSO_QUEUE on - * which it is blocked lives in the moving heap, the TSO is necessarily on the - * oldest generation's mut_list. As in Note [Aging under the non-moving + * In this case we have a TSO blocked on a dead MVar. Because the MVAR_TSO_QUEUE + * on which it is blocked lives in the moving heap, the TSO is necessarily on + * the oldest generation's mut_list. As in Note [Aging under the non-moving * collector], the MVAR_TSO_QUEUE will be evacuated. If MVAR_TSO_QUEUE is aged * (e.g. evacuated to the young generation) then the MVAR will be added to the * mark queue. Consequently, we will falsely conclude that the MVAR is still @@ -389,9 +393,9 @@ static void nonmovingBumpEpoch(void) { * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * The nonmoving collector uses an approximate heuristic for reporting live * data quantity. Specifically, during mark we record how much live data we - * find in nonmoving_segment_live_words. At the end of mark this is combined with nonmoving_large_words - * and nonmoving_compact_words, and we declare this amount to - * be how much live data we have on in the nonmoving heap (by setting + * find in nonmoving_segment_live_words. At the end of mark this is combined + * with nonmoving_large_words and nonmoving_compact_words, and we declare this + * amount to be how much live data we have on in the nonmoving heap (by setting * oldest_gen->live_estimate). * * In addition, we update oldest_gen->live_estimate every time we fill a @@ -415,10 +419,10 @@ static void nonmovingBumpEpoch(void) { * - Minor collections assume that all sparks living in the non-moving heap * are reachable. * - * - Major collections prune the spark queue during the final sync. This pruning - * assumes that all sparks in the young generations are reachable (since the - * BF_EVACUATED flag won't be set on the nursery blocks) and will consequently - * only prune dead sparks living in the non-moving heap. + * - Major collections prune the spark queue during the final sync. This + * pruning assumes that all sparks in the young generations are reachable (since + * the BF_EVACUATED flag won't be set on the nursery blocks) and will + * consequently only prune dead sparks living in the non-moving heap. * * * Note [Dirty flags in the non-moving collector] @@ -441,8 +445,8 @@ static void nonmovingBumpEpoch(void) { * In the non-moving collector we use the same dirty flag to implement a * related optimisation on the non-moving write barrier: Specifically, the * snapshot invariant only requires that the non-moving write barrier applies - * to the *first* mutation to an object after collection begins. To achieve this, - * we impose the following invariant: + * to the *first* mutation to an object after collection begins. To achieve + * this, we impose the following invariant: * * An object being marked as dirty implies that all of its fields are on * the mark queue (or, equivalently, update remembered set). @@ -494,8 +498,8 @@ static void nonmovingBumpEpoch(void) { * ┊ * * This is bad. When we resume mutation a mutator may mutate MVAR A; since it's - * already dirty we would fail to add Y to the update remembered set, breaking the - * snapshot invariant and potentially losing track of the liveness of Z. + * already dirty we would fail to add Y to the update remembered set, breaking + * the snapshot invariant and potentially losing track of the liveness of Z. * * To avoid this nonmovingScavengeOne we eagerly pushes the values of the * fields of all objects which it fails to evacuate (e.g. MVAR A) to the update @@ -537,8 +541,9 @@ static void nonmovingBumpEpoch(void) { * Note [Allocator sizes] * ~~~~~~~~~~~~~~~~~~~~~~ * Our choice of allocator sizes has to balance several considerations: - * - Allocator sizes should be available for the most commonly request block sizes, - * in order to avoid excessive waste from rounding up to the next size (internal fragmentation). + * - Allocator sizes should be available for the most commonly request block + * sizes, in order to avoid excessive waste from rounding up to the next size + * (internal fragmentation). * - It should be possible to efficiently determine which allocator services * a certain block size. * - The amount of allocators should be kept down to avoid overheads @@ -550,15 +555,15 @@ static void nonmovingBumpEpoch(void) { * arbitrary allocator sizes, we need to do some precomputation and make * use of the integer division by constants optimisation. * - * We currently try to balance these considerations by adopting the following scheme. - * We have nonmoving_alloca_dense_cnt "dense" allocators starting with size - * NONMOVING_ALLOCA0, and incrementing by NONMOVING_ALLOCA_DENSE_INCREMENT. + * We currently try to balance these considerations by adopting the following + * scheme. We have nonmoving_alloca_dense_cnt "dense" allocators starting with + * size NONMOVING_ALLOCA0, and incrementing by NONMOVING_ALLOCA_DENSE_INCREMENT. * These service the vast majority of allocations. * In practice, Haskell programs tend to allocate a lot of small objects. * - * Other allocations are handled by a family of "sparse" allocators, each providing - * blocks up to a power of 2. This places an upper bound on the waste at half the - * required block size. + * Other allocations are handled by a family of "sparse" allocators, each + * providing blocks up to a power of 2. This places an upper bound on the waste + * at half the required block size. * * See #23340 * @@ -578,6 +583,25 @@ static void nonmovingBumpEpoch(void) { * quick. * * See #24150 + * + * Note [Testing the nonmoving collector] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * The testsuite has four "ways" which test the nonmoving collector: + * + * - nonmoving: runs tests under the nonmoving collector running in + * non-concurrent mode (i.e. using the non-threaded runtime) + * - nonmoving_thr: runs tests under the collector running in concurrent + * mode (with the threaded runtime) + * - nonmoving_thr_sanity: runs tests with concurrent collection and + * sanity checking (i.e. `+RTS -DS`) + * - nonmoving_thr_ghc: compiles tests with `ghc +RTS --nonmoving-gc -RTS` + * as GHC itself tends to be a good smoke test of the collector. + * + * To avoid blowing up validation times, we do not run any of these ways in the + * default "normal" test speed. To ensure that we catch regressions in during + * normal validation we do run a small number of tests in these ways. These + * tests are identified by the `nonmoving_test` test modifier. + * */ memcount nonmoving_segment_live_words = 0; ===================================== testsuite/driver/testlib.py ===================================== @@ -174,6 +174,18 @@ def js_fragile( bug: IssueNumber ): else: return normal; +def nonmoving_test( name, opts ): + """ + Always run the given test with the nonmoving collector, in addition to + the usual ways. + + See Note [Testing the nonmoving collector] in rts/sm/NonMoving.c. + """ + ways = ['nonmoving'] + if config.ghc_with_threaded_rts and config.target_has_smp: + ways += ['nonmoving_thr_sanity', 'nonmoving_thr_ghc'] + return extra_ways(ways)(name, opts) + def expect_fail( name, opts ): # The compiler, testdriver, OS or platform is missing a certain # feature, and we don't plan to or can't fix it now or in the @@ -1382,7 +1394,7 @@ def normalise_win32_io_errors(name, opts): def normalise_version_( *pkgs ): def normalise_version__( str ): # (name)(-version)(-hash)(-components) - return re.sub('(' + '|'.join(map(re.escape,pkgs)) + r')-[0-9.]+(-[0-9a-zA-Z+]+)?(-[0-9a-zA-Z]+)?', + return re.sub('(' + '|'.join(map(re.escape,pkgs)) + r')-[0-9.]+(-[0-9a-zA-Z\+]+)?(-[0-9a-zA-Z]+)?', r'\1-<VERSION>-<HASH>', str) return normalise_version__ @@ -1971,7 +1983,7 @@ async def do_compile(name: TestName, # of whether we expected the compilation to fail or not (successful # compilations may generate warnings). - expected_stderr_file = find_expected_file(name, 'stderr') + expected_stderr_file = find_expected_file(name, 'stderr', way) actual_stderr_file = add_suffix(name, 'comp.stderr') diff_file_name = in_testdir(add_suffix(name, 'comp.diff')) @@ -2012,7 +2024,7 @@ async def compile_cmp_asm(name: TestName, # of whether we expected the compilation to fail or not (successful # compilations may generate warnings). - expected_asm_file = find_expected_file(name, 'asm') + expected_asm_file = find_expected_file(name, 'asm', way) actual_asm_file = add_suffix(name, 's') if not await compare_outputs(way, 'asm', @@ -2036,7 +2048,7 @@ async def compile_grep_asm(name: TestName, if badResult(result): return result - expected_pat_file = find_expected_file(name, 'asm') + expected_pat_file = find_expected_file(name, 'asm', way) actual_asm_file = add_suffix(name, 's') if not grep_output(join_normalisers(normalise_errmsg), @@ -2058,7 +2070,7 @@ async def compile_grep_core(name: TestName, if badResult(result): return result - expected_pat_file = find_expected_file(name, 'substr-simpl') + expected_pat_file = find_expected_file(name, 'substr-simpl', way) actual_core_file = add_suffix(name, 'dump-simpl') if not grep_output(join_normalisers(normalise_errmsg), @@ -2097,7 +2109,7 @@ async def compile_and_run__(name: TestName, return result if compile_stderr: - expected_stderr_file = find_expected_file(name, 'ghc.stderr') + expected_stderr_file = find_expected_file(name, 'ghc.stderr', way) actual_stderr_file = add_suffix(name, 'comp.stderr') diff_file_name = in_testdir(add_suffix(name, 'comp.diff')) @@ -2556,7 +2568,7 @@ def get_compiler_flags() -> List[str]: async def stdout_ok(name: TestName, way: WayName) -> bool: actual_stdout_file = add_suffix(name, 'run.stdout') - expected_stdout_file = find_expected_file(name, 'stdout') + expected_stdout_file = find_expected_file(name, 'stdout', way) extra_norm = join_normalisers(normalise_output, getTestOpts().extra_normaliser) @@ -2583,7 +2595,7 @@ def dump_stdout( name: TestName ) -> None: async def stderr_ok(name: TestName, way: WayName) -> bool: actual_stderr_file = add_suffix(name, 'run.stderr') - expected_stderr_file = find_expected_file(name, 'stderr') + expected_stderr_file = find_expected_file(name, 'stderr', way) return await compare_outputs(way, 'stderr', join_normalisers(normalise_errmsg, getTestOpts().extra_errmsg_normaliser), \ @@ -2688,7 +2700,7 @@ async def check_hp_ok(name: TestName) -> bool: return False async def check_prof_ok(name: TestName, way: WayName) -> bool: - expected_prof_file = find_expected_file(name, 'prof.sample') + expected_prof_file = find_expected_file(name, 'prof.sample', way) expected_prof_path = in_testdir(expected_prof_file) # Check actual prof file only if we have an expected prof file to @@ -3368,18 +3380,19 @@ def in_statsdir(name: Union[Path, str], suffix: str='') -> Path: # Finding the sample output. The filename is of the form # -# <test>.stdout[-ws-<wordsize>][-<platform>|-<os>] +# <test>.stdout[-ws-<wordsize>][-<platform>|-<os>][-<way>] # -def find_expected_file(name: TestName, suff: str) -> Path: +def find_expected_file(name: TestName, suff: str, way: WayName) -> Path: basename = add_suffix(name, suff) # Override the basename if the user has specified one, this will then be # subjected to the same name mangling scheme as normal to allow platform # specific overrides to work. basename = getTestOpts().use_specs.get(suff, basename) - files = [str(basename) + ws + plat + files = [str(basename) + ws + plat + way_ext for plat in ['-' + config.platform, '-' + config.os, ''] - for ws in ['-ws-' + config.wordsize, '']] + for ws in ['-ws-' + config.wordsize, ''] + for way_ext in ['-' + way, '']] for f in files: if in_srcdir(f).exists(): ===================================== testsuite/tests/array/should_run/all.T ===================================== @@ -21,6 +21,6 @@ test('arr014', when(fast(), skip), compile_and_run, ['']) test('arr015', when(fast(), skip), compile_and_run, ['']) test('arr017', when(fast(), skip), compile_and_run, ['']) test('arr018', when(fast(), skip), compile_and_run, ['']) -test('arr019', normal, compile_and_run, ['']) -test('arr020', normal, compile_and_run, ['']) +test('arr019', nonmoving_test, compile_and_run, ['']) +test('arr020', nonmoving_test, compile_and_run, ['']) test('T21962', normal, compile_and_run, ['']) ===================================== testsuite/tests/concurrent/should_run/all.T ===================================== @@ -1,18 +1,18 @@ # ----------------------------------------------------------------------------- # These tests we do even for 'make fast' -test('conc003', normal, compile_and_run, ['']) -test('conc006', normal, compile_and_run, ['']) -test('conc027', normal, compile_and_run, ['']) -test('conc051', normal, compile_and_run, ['']) +test('conc003', nonmoving_test, compile_and_run, ['']) +test('conc006', nonmoving_test, compile_and_run, ['']) +test('conc027', nonmoving_test, compile_and_run, ['']) +test('conc051', nonmoving_test, compile_and_run, ['']) if ('threaded1' in config.run_ways): only_threaded_ways = only_ways(['ghci','threaded1','threaded2', 'nonmoving_thr']) else: only_threaded_ways = skip -test('conc069', only_threaded_ways, compile_and_run, ['']) -test('conc069a', only_threaded_ways, compile_and_run, ['']) +test('conc069', [nonmoving_test, only_threaded_ways], compile_and_run, ['']) +test('conc069a', [nonmoving_test, only_threaded_ways], compile_and_run, ['']) # this test gives slightly different results for non-threaded ways, so omit # those for now. test('conc070', only_threaded_ways, compile_and_run, ['']) @@ -47,8 +47,8 @@ test('T3429', [ extra_run_opts('+RTS -C0.001 -RTS'), # times out with ghci test('T4030', omit_ghci, compile_and_run, ['-O']) -test('throwto002', js_fragile(24259), compile_and_run, ['']) -test('throwto003', normal, compile_and_run, ['']) +test('throwto002', [nonmoving_test, js_fragile(24259)], compile_and_run, ['']) +test('throwto003', nonmoving_test, compile_and_run, ['']) test('mask001', normal, compile_and_run, ['']) test('mask002', js_broken(22261), compile_and_run, ['']) @@ -81,9 +81,9 @@ test('T5611a', fragile(12751), compile_and_run, ['']) test('T5238', normal, compile_and_run, ['']) test('T5866', exit_code(1), compile_and_run, ['']) -test('readMVar1', normal, compile_and_run, ['']) -test('readMVar2', normal, compile_and_run, ['']) -test('readMVar3', normal, compile_and_run, ['']) +test('readMVar1', nonmoving_test, compile_and_run, ['']) +test('readMVar2', nonmoving_test, compile_and_run, ['']) +test('readMVar3', nonmoving_test, compile_and_run, ['']) test('tryReadMVar1', normal, compile_and_run, ['']) test('tryReadMVar2', normal, compile_and_run, ['']) @@ -121,9 +121,9 @@ test('allocLimit4', [ extra_run_opts('+RTS -xq300k -RTS'), setTestOpts(when(fast(), skip)) -test('conc001', normal, compile_and_run, ['']) -test('conc002', normal, compile_and_run, ['']) -test('conc004', normal, compile_and_run, ['']) +test('conc001', nonmoving_test, compile_and_run, ['']) +test('conc002', nonmoving_test, compile_and_run, ['']) +test('conc004', nonmoving_test, compile_and_run, ['']) test('conc007', extra_run_opts('+RTS -H128M -RTS'), compile_and_run, ['']) test('conc008', normal, compile_and_run, ['']) test('conc009', exit_code(1), compile_and_run, ['']) @@ -218,16 +218,17 @@ test('conc039', [omit_ways(ghci_ways + threaded_ways), js_skip], compile_and_run test('conc040', [exit_code(1), omit_ghci, js_skip], compile_and_run, ['']) # STM-related tests. -test('conc041', normal, compile_and_run, ['']) -test('conc042', normal, compile_and_run, ['']) -test('conc043', normal, compile_and_run, ['']) -test('conc044', normal, compile_and_run, ['']) -test('conc045', normal, compile_and_run, ['']) +test('conc041', nonmoving_test, compile_and_run, ['']) +test('conc042', nonmoving_test, compile_and_run, ['']) +test('conc043', nonmoving_test, compile_and_run, ['']) +test('conc044', nonmoving_test, compile_and_run, ['']) +test('conc045', nonmoving_test, compile_and_run, ['']) -test('conc058', normal, compile_and_run, ['']) +test('conc058', nonmoving_test, compile_and_run, ['']) test('conc059', [only_ways(['threaded1', 'threaded2', 'nonmoving_thr']), + nonmoving_test, pre_cmd('$MAKE -s --no-print-directory conc059_setup')], compile_and_run, ['conc059_c.c -no-hs-main']) ===================================== testsuite/tests/driver/T20696/T20696.stderr-ext-interp ===================================== @@ -0,0 +1,3 @@ +[1 of 3] Compiling C ( C.hs, C.o ) +[2 of 3] Compiling B ( B.hs, B.o ) +[3 of 3] Compiling A ( A.hs, A.o ) ===================================== testsuite/tests/driver/T20696/all.T ===================================== @@ -1,5 +1,4 @@ test('T20696', [extra_files(['A.hs', 'B.hs', 'C.hs']) - , expect_broken_for(26552, ['ext-interp']) , unless(ghc_dynamic(), skip)], multimod_compile, ['A', '']) test('T20696-static', [extra_files(['A.hs', 'B.hs', 'C.hs']) , when(ghc_dynamic(), skip)], multimod_compile, ['A', '']) ===================================== testsuite/tests/driver/fat-iface/all.T ===================================== @@ -9,12 +9,12 @@ test('fat010', [req_th,extra_files(['THA.hs', 'THB.hs', 'THC.hs']), copy_files], # Check linking works when using -fbyte-code-and-object-code test('fat011', [req_th, extra_files(['FatMain.hs', 'FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatMain', '-fbyte-code-and-object-code -fprefer-byte-code']) # Check that we use interpreter rather than enable dynamic-too if needed for TH -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']) +test('fat012', [req_th, unless(ghc_dynamic(), skip), extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fprefer-byte-code']) # Check that no objects are generated if using -fno-code and -fprefer-byte-code test('fat013', [req_th, req_bco, extra_files(['FatTH.hs', 'FatQuote.hs'])], multimod_compile, ['FatTH', '-fno-code -fprefer-byte-code']) # When using interpreter should not produce objects test('fat014', [req_th, extra_files(['FatTH.hs', 'FatQuote.hs']), extra_run_opts('-fno-code')], ghci_script, ['fat014.script']) -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']) +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']) test('T22807', [req_th, unless(ghc_dynamic(), skip), extra_files(['T22807A.hs', 'T22807B.hs'])] , makefile_test, ['T22807']) test('T22807_ghci', [req_th, unless(ghc_dynamic(), skip), extra_files(['T22807_ghci.hs'])] ===================================== testsuite/tests/driver/fat-iface/fat012.stderr-ext-interp ===================================== @@ -0,0 +1,2 @@ +[1 of 2] Compiling FatQuote ( FatQuote.hs, FatQuote.o ) +[2 of 2] Compiling FatTH ( FatTH.hs, FatTH.o ) ===================================== testsuite/tests/driver/fat-iface/fat015.stderr-ext-interp ===================================== @@ -0,0 +1,6 @@ +[1 of 6] Compiling FatQuote ( FatQuote.hs, FatQuote.o, interpreted ) +[2 of 6] Compiling FatQuote1 ( FatQuote1.hs, interpreted ) +[3 of 6] Compiling FatQuote2 ( FatQuote2.hs, FatQuote2.o ) +[4 of 6] Compiling FatTH1 ( FatTH1.hs, nothing ) +[5 of 6] Compiling FatTH2 ( FatTH2.hs, nothing ) +[6 of 6] Compiling FatTHTop ( FatTHTop.hs, nothing ) ===================================== testsuite/tests/splice-imports/SI07.stderr-ext-interp ===================================== @@ -0,0 +1,3 @@ +[1 of 3] Compiling SI05A ( SI05A.hs, SI05A.o ) +[2 of 3] Compiling SI07A ( SI07A.hs, nothing ) +[3 of 3] Compiling SI07 ( SI07.hs, nothing ) ===================================== testsuite/tests/splice-imports/all.T ===================================== @@ -9,7 +9,7 @@ test('SI03', [extra_files(["SI01A.hs"])], multimod_compile_fail, ['SI03', '-v0'] test('SI04', [extra_files(["SI01A.hs"])], multimod_compile, ['SI04', '-v0']) test('SI05', [extra_files(["SI01A.hs"])], multimod_compile_fail, ['SI05', '-v0']) test('SI06', [extra_files(["SI01A.hs"])], multimod_compile, ['SI06', '-v0']) -test('SI07', [expect_broken_for(26552, ['ext-interp']), unless(ghc_dynamic(), skip), extra_files(["SI05A.hs"])], multimod_compile, ['SI07', '-fwrite-interface -fno-code']) +test('SI07', [unless(ghc_dynamic(), skip), extra_files(["SI05A.hs"])], multimod_compile, ['SI07', '-fwrite-interface -fno-code']) # Instance tests test('SI08', [extra_files(["ClassA.hs", "InstanceA.hs"])], multimod_compile_fail, ['SI08', '-v0']) test('SI09', [extra_files(["ClassA.hs", "InstanceA.hs"])], multimod_compile, ['SI09', '-v0']) ===================================== testsuite/tests/th/T26099.hs ===================================== @@ -0,0 +1,6 @@ +{-# LANGUAGE TemplateHaskell #-} +module M where + +type T = Int + +a = $(3 :: T) ===================================== testsuite/tests/th/T26099.stderr ===================================== @@ -0,0 +1,6 @@ +T26099.hs:6:12: error: [GHC-28914] + • Level error: ‘T’ is bound at level 0 but used at level -1 + • In an expression type signature: T + In the expression: 3 :: T + In the untyped splice: $(3 :: T) + ===================================== testsuite/tests/th/all.T ===================================== @@ -642,3 +642,4 @@ test('QQInQuote', normal, compile, ['']) test('QQTopError', normal, compile_fail, ['-fdiagnostics-show-caret']) test('GadtConSigs_th_pprint1', normal, compile, ['']) test('GadtConSigs_th_dump1', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) +test('T26099', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/584877a66c36d49cc1f121a1e04aef8... -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/584877a66c36d49cc1f121a1e04aef8... You're receiving this email because of your account on gitlab.haskell.org.
participants (1)
-
Cheng Shao (@TerrorJack)