Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
-
53682431
by Simon Jakobi at 2026-08-14T11:46:25-04:00
-
c08a77ff
by Simon Jakobi at 2026-08-14T11:46:25-04:00
-
8c1a9eab
by Simon Jakobi at 2026-08-14T11:46:25-04:00
-
1a2b95ef
by Simon Jakobi at 2026-08-14T11:46:25-04:00
-
d22fd7ec
by Vladislav Zavialov at 2026-08-14T11:46:27-04:00
17 changed files:
- + changelog.d/T27586
- compiler/GHC/Tc/TyCl/PatSyn.hs
- libraries/base/tests/all.T
- libraries/base/tests/listThreads1.hs
- libraries/base/tests/listThreads1.stdout
- rts/js/thread.js
- + testsuite/tests/concurrent/should_run/T16761.hs
- + testsuite/tests/concurrent/should_run/T16761.stdout
- testsuite/tests/concurrent/should_run/all.T
- testsuite/tests/rts/all.T
- + testsuite/tests/vdq-rta/should_fail/T27586a.hs
- + testsuite/tests/vdq-rta/should_fail/T27586a.stderr
- + testsuite/tests/vdq-rta/should_fail/T27586b.hs
- + testsuite/tests/vdq-rta/should_fail/T27586b.stderr
- + testsuite/tests/vdq-rta/should_fail/T27586c.hs
- + testsuite/tests/vdq-rta/should_fail/T27586c.stderr
- testsuite/tests/vdq-rta/should_fail/all.T
Changes:
| 1 | +section: compiler
|
|
| 2 | +issues: #27586
|
|
| 3 | +mrs: !16440
|
|
| 4 | +synopsis:
|
|
| 5 | + Fix a panic on a required type argument in a pattern synonym RHS
|
|
| 6 | +description:
|
|
| 7 | + An argument of a pattern synonym that is matched against a required type
|
|
| 8 | + argument in the right-hand side no longer causes a panic; it is reported as
|
|
| 9 | + an illegal term-level use of a type variable. |
| ... | ... | @@ -137,7 +137,7 @@ tcInferPatSynDecl (PSB { psb_id = lname@(L _ name), psb_args = details |
| 137 | 137 | ; (tclvl, wanted, ((lpat', args), pat_ty))
|
| 138 | 138 | <- pushLevelAndCaptureConstraints $
|
| 139 | 139 | tcInferPat FRRPatSynArg PatSynCtx lpat $
|
| 140 | - mapM tcLookupId arg_names
|
|
| 140 | + mapM tcLookupPatSynArg arg_names
|
|
| 141 | 141 | |
| 142 | 142 | ; let (ex_tvs, prov_dicts) = tcCollectEx lpat'
|
| 143 | 143 | |
| ... | ... | @@ -472,7 +472,7 @@ tcCheckPatSynDecl psb@PSB{ psb_id = lname@(L _ name), psb_args = details |
| 472 | 472 | -- location to x's binding site in lpat, namely the 'x' in Just (x,True).
|
| 473 | 473 | -- Else the error message location is wherever tcCheckPat finished,
|
| 474 | 474 | -- namely the right-hand corner of the pattern
|
| 475 | - do { arg_id <- tcLookupId arg_name
|
|
| 475 | + do { arg_id <- tcLookupPatSynArg arg_name
|
|
| 476 | 476 | ; wrap <- tcSubTypeSigma (OccurrenceOf (idName arg_id))
|
| 477 | 477 | GenSigCtxt
|
| 478 | 478 | (idType arg_id)
|
| ... | ... | @@ -645,6 +645,19 @@ collectPatSynArgInfo details = |
| 645 | 645 | InfixCon _ name1 name2 -> (map unLoc [name1, name2], True)
|
| 646 | 646 | RecCon _ names -> (map (unLoc . recordPatSynPatVar) names, False)
|
| 647 | 647 | |
| 648 | +-- | Look up the 'Id' bound by the pattern for a declared argument of a pattern
|
|
| 649 | +-- synonym. With @RequiredTypeArguments@ the argument may turn out to be a type
|
|
| 650 | +-- variable, e.g. @pattern P x = MkT x@ where the argument of @MkT@ is a required
|
|
| 651 | +-- type argument; then we report an illegal term-level use of @x@ (#27586).
|
|
| 652 | +tcLookupPatSynArg :: Name -> TcM Id
|
|
| 653 | +tcLookupPatSynArg arg_name
|
|
| 654 | + = do { thing <- tcLookup arg_name
|
|
| 655 | + ; case thing of
|
|
| 656 | + ATcId { tct_id = id } -> return id
|
|
| 657 | + AGlobal (AnId id) -> return id
|
|
| 658 | + ATyVar {} -> failIllegalTyVar (noUserRdr arg_name)
|
|
| 659 | + _ -> pprPanic "tcLookupPatSynArg" (ppr arg_name) }
|
|
| 660 | + |
|
| 648 | 661 | wrongNumberOfParmsErr :: Name -> Arity -> Arity -> TcM a
|
| 649 | 662 | wrongNumberOfParmsErr name decl_arity missing
|
| 650 | 663 | = failWithTc $ TcRnPatSynArityMismatch name decl_arity missing
|
| ... | ... | @@ -80,7 +80,7 @@ test('length001', |
| 80 | 80 | # excessive amounts of stack space. So we specifically set a low
|
| 81 | 81 | # stack limit and mark it as failing under a few conditions.
|
| 82 | 82 | [extra_run_opts('+RTS -K8m -RTS'),
|
| 83 | - expect_fail_for(['normal', 'threaded1', 'llvm', 'nonmoving', 'nonmoving_thr', 'nonmoving_thr_ghc', 'ext-interp']),
|
|
| 83 | + expect_fail_for(['normal', 'threaded1', 'llvm', 'nonmoving', 'nonmoving_thr', 'nonmoving_thr_sanity', 'nonmoving_thr_ghc', 'ext-interp']),
|
|
| 84 | 84 | # JS doesn't support stack limit so the test sometimes passes just fine. Therefore the test is
|
| 85 | 85 | # marked as fragile.
|
| 86 | 86 | when(js_arch(), fragile(22921))],
|
| ... | ... | @@ -2,5 +2,10 @@ module Main where |
| 2 | 2 | |
| 3 | 3 | import GHC.Conc.Sync
|
| 4 | 4 | |
| 5 | +-- Regression test for the JS backend's ListThreadsOp, which used to omit the
|
|
| 6 | +-- running thread. Whatever other threads the RTS has is irrelevant here.
|
|
| 5 | 7 | main :: IO ()
|
| 6 | -main = listThreads >>= print |
|
| 8 | +main = do
|
|
| 9 | + tid <- myThreadId
|
|
| 10 | + ts <- listThreads
|
|
| 11 | + print (tid `elem` ts) |
| 1 | -[ThreadId 1] |
|
| 1 | +True |
| ... | ... | @@ -110,6 +110,10 @@ function h$rts_getThreadId(t) { // returns a CULLong |
| 110 | 110 | RETURN_UBX_TUP2((t.tid / Math.pow(2,32))>>>0, (t.tid & 0xFFFFFFFF)>>>0);
|
| 111 | 111 | }
|
| 112 | 112 | |
| 113 | +function h$eq_thread(t1,t2) {
|
|
| 114 | + return t1 === t2 ? 1 : 0;
|
|
| 115 | +}
|
|
| 116 | + |
|
| 113 | 117 | function h$cmp_thread(t1,t2) {
|
| 114 | 118 | if(t1.tid < t2.tid) return -1;
|
| 115 | 119 | if(t1.tid > t2.tid) return 1;
|
| 1 | +-- Test that Eq ThreadId is based on thread identity (eq_thread),
|
|
| 2 | +-- not on the numeric thread id, which may wrap around (#16761).
|
|
| 3 | +module Main (main) where
|
|
| 4 | + |
|
| 5 | +import Control.Concurrent
|
|
| 6 | +import System.Mem (performGC)
|
|
| 7 | + |
|
| 8 | +main :: IO ()
|
|
| 9 | +main = do
|
|
| 10 | + t0 <- myThreadId
|
|
| 11 | + print (t0 == t0)
|
|
| 12 | + |
|
| 13 | + mv <- newEmptyMVar
|
|
| 14 | + _ <- forkIO (myThreadId >>= putMVar mv)
|
|
| 15 | + tChild <- takeMVar mv
|
|
| 16 | + print (t0 == tChild)
|
|
| 17 | + print (tChild == tChild)
|
|
| 18 | + |
|
| 19 | + -- Equality must be stable even after the GC moves the TSOs.
|
|
| 20 | + performGC
|
|
| 21 | + print (t0 == t0)
|
|
| 22 | + |
|
| 23 | + -- Ord must agree with Eq.
|
|
| 24 | + print (compare t0 tChild /= EQ)
|
|
| 25 | + print (compare t0 t0 == EQ) |
| 1 | +True
|
|
| 2 | +False
|
|
| 3 | +True
|
|
| 4 | +True
|
|
| 5 | +True
|
|
| 6 | +True |
| ... | ... | @@ -310,6 +310,8 @@ test('hs_try_putmvar003', |
| 310 | 310 | # Check forkIO exception determinism under optimization
|
| 311 | 311 | test('T13330', normal, compile_and_run, ['-O'])
|
| 312 | 312 | |
| 313 | +test('T16761', normal, compile_and_run, [''])
|
|
| 314 | + |
|
| 313 | 315 | test('T26341', normal, compile_and_run, [''])
|
| 314 | 316 | |
| 315 | 317 | # Test EINTR for async I/O interrupted by an exception (#26341)
|
| ... | ... | @@ -679,7 +679,7 @@ test('T22859', |
| 679 | 679 | [js_skip,
|
| 680 | 680 | # This test is vulnerable to changes in allocation behaviour, so we disable it in some ways
|
| 681 | 681 | when(arch('wasm32'), skip),
|
| 682 | - omit_ways(llvm_ways)],
|
|
| 682 | + omit_ways(llvm_ways + ['nonmoving_thr', 'nonmoving_thr_sanity'])],
|
|
| 683 | 683 | compile_and_run, ['-with-rtsopts -A8K'])
|
| 684 | 684 | |
| 685 | 685 | # These tests need access to the internal RTS headers.
|
| 1 | +{-# LANGUAGE GADTs, RequiredTypeArguments, PatternSynonyms #-}
|
|
| 2 | + |
|
| 3 | +module T27586a where
|
|
| 4 | + |
|
| 5 | +data T a where
|
|
| 6 | + MkT :: forall a -> T a
|
|
| 7 | + |
|
| 8 | +pattern P :: Int -> T Int
|
|
| 9 | +pattern P x = MkT x |
| 1 | +T27586a.hs:9:19: error: [GHC-01928]
|
|
| 2 | + • Illegal term-level use of the type variable ‘x’
|
|
| 3 | + • bound at T27586a.hs:9:19
|
|
| 4 | + • In the declaration for pattern synonym ‘P’
|
|
| 5 | + |
| 1 | +{-# LANGUAGE GADTs, RequiredTypeArguments, PatternSynonyms #-}
|
|
| 2 | + |
|
| 3 | +module T27586b where
|
|
| 4 | + |
|
| 5 | +data T a where
|
|
| 6 | + MkT :: forall a -> T a
|
|
| 7 | + |
|
| 8 | +pattern P x = MkT x |
| 1 | +T27586b.hs:8:15: error: [GHC-01928]
|
|
| 2 | + • Illegal term-level use of the type variable ‘x’
|
|
| 3 | + • bound at T27586b.hs:8:19
|
|
| 4 | + • In the declaration for pattern synonym ‘P’
|
|
| 5 | + |
| 1 | +{-# LANGUAGE GADTs, RequiredTypeArguments, PatternSynonyms #-}
|
|
| 2 | + |
|
| 3 | +module T27586c where
|
|
| 4 | + |
|
| 5 | +data T a where
|
|
| 6 | + MkT :: forall a -> T a
|
|
| 7 | + |
|
| 8 | +pattern P :: Int -> T Int
|
|
| 9 | +pattern P x <- MkT x |
| 1 | +T27586c.hs:9:20: error: [GHC-01928]
|
|
| 2 | + • Illegal term-level use of the type variable ‘x’
|
|
| 3 | + • bound at T27586c.hs:9:20
|
|
| 4 | + • In the declaration for pattern synonym ‘P’
|
|
| 5 | + |
| ... | ... | @@ -35,3 +35,6 @@ test('T25127_fail_arity', normal, compile_fail, ['']) |
| 35 | 35 | |
| 36 | 36 | test('T27440e', normal, compile_fail, [''])
|
| 37 | 37 | test('T27583f', normal, compile_fail, [''])
|
| 38 | +test('T27586a', normal, compile_fail, [''])
|
|
| 39 | +test('T27586b', normal, compile_fail, [''])
|
|
| 40 | +test('T27586c', normal, compile_fail, ['']) |