Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

13 changed files:

Changes:

  • compiler/GHC/Cmm/Dataflow/Label.hs
    ... ... @@ -83,6 +83,7 @@ import GHC.Data.Word64Map.Strict (Word64Map)
    83 83
     import qualified GHC.Data.Word64Map.Strict as M
    
    84 84
     import GHC.Data.TrieMap
    
    85 85
     
    
    86
    +import Data.Coerce
    
    86 87
     import Data.Word (Word64)
    
    87 88
     
    
    88 89
     
    
    ... ... @@ -164,7 +165,7 @@ setFoldr k z (LS s) = S.foldr (\v a -> k (mkHooplLabel v) a) z s
    164 165
     
    
    165 166
     {-# INLINE setElems #-}
    
    166 167
     setElems :: LabelSet -> [Label]
    
    167
    -setElems (LS s) = map mkHooplLabel (S.elems s)
    
    168
    +setElems (LS s) = coerce $ S.elems s
    
    168 169
     
    
    169 170
     {-# INLINE setFromList #-}
    
    170 171
     setFromList :: [Label] -> LabelSet
    
    ... ... @@ -272,7 +273,7 @@ mapKeys (LM m) = map (mkHooplLabel . fst) (M.toList m)
    272 273
     
    
    273 274
     {-# INLINE mapToList #-}
    
    274 275
     mapToList :: LabelMap b -> [(Label, b)]
    
    275
    -mapToList (LM m) = [(mkHooplLabel k, v) | (k, v) <- M.toList m]
    
    276
    +mapToList (LM m) = coerce $ M.toList m
    
    276 277
     
    
    277 278
     {-# INLINE mapFromList #-}
    
    278 279
     mapFromList :: [(Label, v)] -> LabelMap v
    

  • compiler/GHC/Rename/HsType.hs
    ... ... @@ -547,15 +547,7 @@ rnHsTyKi env tv@(HsTyVar _ ip (L loc rdr_name))
    547 547
            ; this_mod <- getModule
    
    548 548
            ; when (nameIsLocalOrFrom this_mod name) $
    
    549 549
              checkThLocalTyName name
    
    550
    -       ; when (isDataConName name && not (isKindName name)) $
    
    551
    -           -- Any use of a promoted data constructor name (that is not
    
    552
    -           -- specifically exempted by isKindName) is illegal without the use
    
    553
    -           -- of DataKinds. See Note [Checking for DataKinds] in
    
    554
    -           -- GHC.Tc.Validity.
    
    555
    -           checkDataKinds env tv
    
    556
    -       ; when (isDataConName name && not (isPromoted ip)) $
    
    557
    -         -- NB: a prefix symbolic operator such as (:) is represented as HsTyVar.
    
    558
    -            addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Prefix name)
    
    550
    +       ; checkPromotedDataConName env tv Prefix ip name
    
    559 551
            ; return (HsTyVar noAnn ip (L loc $ WithUserRdr rdr_name name), unitFV name) }
    
    560 552
     
    
    561 553
     rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2)
    
    ... ... @@ -567,8 +559,7 @@ rnHsTyKi env ty@(HsOpTy _ prom ty1 l_op ty2)
    567 559
             ; (ty1', fvs2) <- rnLHsTyKi env ty1
    
    568 560
             ; (ty2', fvs3) <- rnLHsTyKi env ty2
    
    569 561
             ; res_ty <- mkHsOpTyRn prom (fmap (WithUserRdr op_rdr) l_op') fix ty1' ty2'
    
    570
    -        ; when (isDataConName op_name && not (isPromoted prom)) $
    
    571
    -            addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor Infix op_name)
    
    562
    +        ; checkPromotedDataConName env ty Infix prom op_name
    
    572 563
             ; return (res_ty, plusFVs [fvs1, fvs2, fvs3]) }
    
    573 564
     
    
    574 565
     rnHsTyKi env (HsParTy _ ty)
    
    ... ... @@ -1670,6 +1661,30 @@ checkDataKinds env thing
    1670 1661
         type_or_kind | isRnKindLevel env = KindLevel
    
    1671 1662
                      | otherwise         = TypeLevel
    
    1672 1663
     
    
    1664
    +-- | If a 'Name' is that of a promoted data constructor, perform various
    
    1665
    +-- validity checks on it.
    
    1666
    +checkPromotedDataConName ::
    
    1667
    +  RnTyKiEnv ->
    
    1668
    +  -- | The type that the 'Name' belongs to. This will always be an 'HsTyVar'
    
    1669
    +  -- (for 'Prefix' names) or an 'HsOpTy' (for 'Infix' names).
    
    1670
    +  HsType GhcPs ->
    
    1671
    +  -- | Whether the type is written 'Prefix' or 'Infix'.
    
    1672
    +  LexicalFixity ->
    
    1673
    +  -- | Whether the name was written with an explicit promotion tick or not.
    
    1674
    +  PromotionFlag ->
    
    1675
    +  -- | The name to check.
    
    1676
    +  Name ->
    
    1677
    +  TcM ()
    
    1678
    +checkPromotedDataConName env ty fixity ip name
    
    1679
    +  = do when (isDataConName name && not (isKindName name)) $
    
    1680
    +         -- Any use of a promoted data constructor name (that is not
    
    1681
    +         -- specifically exempted by isKindName) is illegal without the use
    
    1682
    +         -- of DataKinds. See Note [Checking for DataKinds] in
    
    1683
    +         -- GHC.Tc.Validity.
    
    1684
    +         checkDataKinds env ty
    
    1685
    +       when (isDataConName name && not (isPromoted ip)) $
    
    1686
    +         addDiagnostic (TcRnUntickedPromotedThing $ UntickedConstructor fixity name)
    
    1687
    +
    
    1673 1688
     warnUnusedForAll :: OutputableBndrFlag flag 'Renamed
    
    1674 1689
                      => HsDocContext -> LHsTyVarBndr flag GhcRn -> FreeVars -> TcM ()
    
    1675 1690
     warnUnusedForAll doc (L loc tvb) used_names =
    

  • docs/users_guide/9.16.1-notes.rst
    ... ... @@ -11,6 +11,11 @@ for specific guidance on migrating programs to this release.
    11 11
     Language
    
    12 12
     ~~~~~~~~
    
    13 13
     
    
    14
    +- Fix a bug introduced in GHC 9.10 where GHC would erroneously accept infix uses
    
    15
    +  of promoted data constructors without enabling :extension:`DataKinds`. As a
    
    16
    +  result, you may need to enable :extension:`DataKinds` in code that did not
    
    17
    +  previously require it.
    
    18
    +
    
    14 19
     Compiler
    
    15 20
     ~~~~~~~~
    
    16 21
     
    

  • rts/PrimOps.cmm
    ... ... @@ -1211,27 +1211,16 @@ INFO_TABLE_RET(stg_catch_retry_frame, CATCH_RETRY_FRAME,
    1211 1211
         gcptr trec, outer, arg;
    
    1212 1212
     
    
    1213 1213
         trec = StgTSO_trec(CurrentTSO);
    
    1214
    -    if (running_alt_code != 1) {
    
    1215
    -      // When exiting the lhs code of catchRetry# lhs rhs, we need to cleanup
    
    1216
    -      // the nested transaction.
    
    1217
    -      // See Note [catchRetry# implementation]
    
    1218
    -      outer  = StgTRecHeader_enclosing_trec(trec);
    
    1219
    -      (r) = ccall stmCommitNestedTransaction(MyCapability() "ptr", trec "ptr");
    
    1220
    -      if (r != 0) {
    
    1221
    -          // Succeeded in first branch
    
    1222
    -          StgTSO_trec(CurrentTSO) = outer;
    
    1223
    -          return (ret);
    
    1224
    -      } else {
    
    1225
    -          // Did not commit: abort and restart.
    
    1226
    -          StgTSO_trec(CurrentTSO) = outer;
    
    1227
    -          jump stg_abort();
    
    1228
    -      }
    
    1229
    -    }
    
    1230
    -    else {
    
    1231
    -      // nothing to do in the rhs code of catchRetry# lhs rhs, it's already
    
    1232
    -      // using the parent transaction (not a nested one).
    
    1233
    -      // See Note [catchRetry# implementation]
    
    1234
    -      return (ret);
    
    1214
    +    outer  = StgTRecHeader_enclosing_trec(trec);
    
    1215
    +    (r) = ccall stmCommitNestedTransaction(MyCapability() "ptr", trec "ptr");
    
    1216
    +    if (r != 0) {
    
    1217
    +        // Succeeded (either first branch or second branch)
    
    1218
    +        StgTSO_trec(CurrentTSO) = outer;
    
    1219
    +        return (ret);
    
    1220
    +    } else {
    
    1221
    +        // Did not commit: abort and restart.
    
    1222
    +        StgTSO_trec(CurrentTSO) = outer;
    
    1223
    +        jump stg_abort();
    
    1235 1224
         }
    
    1236 1225
     }
    
    1237 1226
     
    
    ... ... @@ -1464,26 +1453,21 @@ retry_pop_stack:
    1464 1453
         outer  = StgTRecHeader_enclosing_trec(trec);
    
    1465 1454
     
    
    1466 1455
         if (frame_type == CATCH_RETRY_FRAME) {
    
    1467
    -        // The retry reaches a CATCH_RETRY_FRAME before the ATOMICALLY_FRAME
    
    1468
    -
    
    1456
    +        // The retry reaches a CATCH_RETRY_FRAME before the atomic frame
    
    1457
    +        ASSERT(outer != NO_TREC);
    
    1458
    +        // Abort the transaction attempting the current branch
    
    1459
    +        ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr");
    
    1460
    +        ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr");
    
    1469 1461
             if (!StgCatchRetryFrame_running_alt_code(frame) != 0) {
    
    1470
    -            // Retrying in the lhs of catchRetry# lhs rhs, i.e. in a nested
    
    1471
    -            // transaction. See Note [catchRetry# implementation]
    
    1472
    -
    
    1473
    -            // check that we have a parent transaction
    
    1474
    -            ASSERT(outer != NO_TREC);
    
    1475
    -
    
    1476
    -            // Abort the nested transaction
    
    1477
    -            ccall stmAbortTransaction(MyCapability() "ptr", trec "ptr");
    
    1478
    -            ccall stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr");
    
    1479
    -
    
    1480
    -            // As we are retrying in the lhs code, we must now try the rhs code
    
    1481
    -            StgTSO_trec(CurrentTSO) = outer;
    
    1462
    +            // Retry in the first branch: try the alternative
    
    1463
    +            ("ptr" trec) = ccall stmStartTransaction(MyCapability() "ptr", outer "ptr");
    
    1464
    +            StgTSO_trec(CurrentTSO) = trec;
    
    1482 1465
                 StgCatchRetryFrame_running_alt_code(frame) = 1 :: CInt; // true;
    
    1483 1466
                 R1 = StgCatchRetryFrame_alt_code(frame);
    
    1484 1467
                 jump stg_ap_v_fast [R1];
    
    1485 1468
             } else {
    
    1486
    -            // Retry in the rhs code: propagate the retry
    
    1469
    +            // Retry in the alternative code: propagate the retry
    
    1470
    +            StgTSO_trec(CurrentTSO) = outer;
    
    1487 1471
                 Sp = Sp + SIZEOF_StgCatchRetryFrame;
    
    1488 1472
                 goto retry_pop_stack;
    
    1489 1473
             }
    

  • rts/RaiseAsync.c
    ... ... @@ -1043,7 +1043,8 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception,
    1043 1043
                 }
    
    1044 1044
     
    
    1045 1045
             case CATCH_STM_FRAME:
    
    1046
    -            // CATCH_STM frame within an atomically block: abort the
    
    1046
    +        case CATCH_RETRY_FRAME:
    
    1047
    +            // CATCH frames within an atomically block: abort the
    
    1047 1048
                 // inner transaction and continue.  Eventually we will
    
    1048 1049
                 // hit the outer transaction that will get frozen (see
    
    1049 1050
                 // above).
    
    ... ... @@ -1055,40 +1056,14 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception,
    1055 1056
             {
    
    1056 1057
                 StgTRecHeader *trec = tso -> trec;
    
    1057 1058
                 StgTRecHeader *outer = trec -> enclosing_trec;
    
    1058
    -            debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_STM frame");
    
    1059
    +            debugTraceCap(DEBUG_stm, cap,
    
    1060
    +                          "found atomically block delivering async exception");
    
    1059 1061
                 stmAbortTransaction(cap, trec);
    
    1060 1062
                 stmFreeAbortedTRec(cap, trec);
    
    1061 1063
                 tso -> trec = outer;
    
    1062 1064
                 break;
    
    1063 1065
             };
    
    1064 1066
     
    
    1065
    -        case CATCH_RETRY_FRAME:
    
    1066
    -            // CATCH_RETY frame within an atomically block: if we're executing
    
    1067
    -            // the lhs code, abort the inner transaction and continue; if we're
    
    1068
    -            // executing thr rhs, continue (no nested transaction to abort. See
    
    1069
    -            // Note [catchRetry# implementation]). Eventually we will hit the
    
    1070
    -            // outer transaction that will get frozen (see above).
    
    1071
    -            //
    
    1072
    -            // As for the CATCH_STM_FRAME case above, we do not care
    
    1073
    -            // whether the transaction is valid or not because its
    
    1074
    -            // possible validity cannot have caused the exception
    
    1075
    -            // and will not be visible after the abort.
    
    1076
    -        {
    
    1077
    -            if (!((StgCatchRetryFrame *)frame) -> running_alt_code) {
    
    1078
    -                debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_RETRY frame (lhs)");
    
    1079
    -                StgTRecHeader *trec = tso -> trec;
    
    1080
    -                StgTRecHeader *outer = trec -> enclosing_trec;
    
    1081
    -                stmAbortTransaction(cap, trec);
    
    1082
    -                stmFreeAbortedTRec(cap, trec);
    
    1083
    -                tso -> trec = outer;
    
    1084
    -            }
    
    1085
    -            else
    
    1086
    -            {
    
    1087
    -                debugTraceCap(DEBUG_stm, cap, "raiseAsync: traversing CATCH_RETRY frame (rhs)");
    
    1088
    -            }
    
    1089
    -            break;
    
    1090
    -        };
    
    1091
    -
    
    1092 1067
             default:
    
    1093 1068
                 // see Note [Update async masking state on unwind] in Schedule.c
    
    1094 1069
                 if (*frame == (W_)&stg_unmaskAsyncExceptionszh_ret_info) {
    

  • rts/STM.c
    ... ... @@ -1505,30 +1505,3 @@ void stmWriteTVar(Capability *cap,
    1505 1505
     }
    
    1506 1506
     
    
    1507 1507
     /*......................................................................*/
    1508
    -
    
    1509
    -
    
    1510
    -
    
    1511
    -/*
    
    1512
    -
    
    1513
    -Note [catchRetry# implementation]
    
    1514
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1515
    -catchRetry# creates a nested transaction for its lhs:
    
    1516
    -- if the lhs transaction succeeds:
    
    1517
    -    - the lhs transaction is committed
    
    1518
    -    - its read-variables are merged with those of the parent transaction
    
    1519
    -    - the rhs code is ignored
    
    1520
    -- if the lhs transaction retries:
    
    1521
    -    - the lhs transaction is aborted
    
    1522
    -    - its read-variables are merged with those of the parent transaction
    
    1523
    -    - the rhs code is executed directly in the parent transaction (see #26028).
    
    1524
    -
    
    1525
    -So note that:
    
    1526
    -- lhs code uses a nested transaction
    
    1527
    -- rhs code doesn't use a nested transaction
    
    1528
    -
    
    1529
    -We have to take which case we're in into account (using the running_alt_code
    
    1530
    -field of the catchRetry frame) in catchRetry's entry code, in retry#
    
    1531
    -implementation, and also when an async exception is received (to cleanup the
    
    1532
    -right number of transactions).
    
    1533
    -
    
    1534
    -*/

  • testsuite/tests/lib/stm/T26028.hs deleted
    1
    -module Main where
    
    2
    -
    
    3
    -import GHC.Conc
    
    4
    -
    
    5
    -forever :: IO String
    
    6
    -forever = delay 10 >> forever
    
    7
    -
    
    8
    -terminates :: IO String
    
    9
    -terminates = delay 1 >> pure "terminates"
    
    10
    -
    
    11
    -delay s = threadDelay (1000000 * s)
    
    12
    -
    
    13
    -async :: IO a -> IO (STM a)
    
    14
    -async a = do 
    
    15
    -  var <- atomically (newTVar Nothing)
    
    16
    -  forkIO (a >>= atomically . writeTVar var . Just)
    
    17
    -  pure (readTVar var >>= maybe retry pure)
    
    18
    -
    
    19
    -main :: IO ()
    
    20
    -main = do
    
    21
    -  x <- mapM async $ terminates : replicate 50000 forever
    
    22
    -  r <- atomically (foldr1 orElse x)
    
    23
    -  print r

  • testsuite/tests/lib/stm/T26028.stdout deleted
    1
    -"terminates"

  • testsuite/tests/lib/stm/all.T deleted
    1
    -test('T26028', only_ways(['threaded1']), compile_and_run, ['-O2'])

  • testsuite/tests/typecheck/should_fail/T26318.hs
    1
    +{-# LANGUAGE GHC2021 #-}
    
    2
    +{-# LANGUAGE NoDataKinds #-}
    
    3
    +module T26318 where
    
    4
    +
    
    5
    +class C1 l
    
    6
    +instance C1 (x : xs)
    
    7
    +
    
    8
    +class C2 l
    
    9
    +instance C2 (x ': xs)
    
    10
    +
    
    11
    +class C3 l
    
    12
    +instance C3 ((:) x xs)
    
    13
    +
    
    14
    +class C4 l
    
    15
    +instance C4 ('(:) x xs)

  • testsuite/tests/typecheck/should_fail/T26318.stderr
    1
    +T26318.hs:6:16: error: [GHC-68567]
    
    2
    +    Illegal type: ‘x : xs’
    
    3
    +    Suggested fix:
    
    4
    +      Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
    
    5
    +
    
    6
    +T26318.hs:9:16: error: [GHC-68567]
    
    7
    +    Illegal type: ‘x ': xs’
    
    8
    +    Suggested fix:
    
    9
    +      Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
    
    10
    +
    
    11
    +T26318.hs:12:14: error: [GHC-68567]
    
    12
    +    Illegal type: ‘(:)’
    
    13
    +    Suggested fix:
    
    14
    +      Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
    
    15
    +
    
    16
    +T26318.hs:15:14: error: [GHC-68567]
    
    17
    +    Illegal type: ‘'(:)’
    
    18
    +    Suggested fix:
    
    19
    +      Perhaps you intended to use the ‘DataKinds’ extension (implied by ‘UnliftedDatatypes’)
    
    20
    +

  • testsuite/tests/typecheck/should_fail/all.T
    ... ... @@ -741,3 +741,4 @@ test('T25325', normal, compile_fail, [''])
    741 741
     test('T25004', normal, compile_fail, [''])
    
    742 742
     test('T25004k', normal, compile_fail, [''])
    
    743 743
     test('T26004', normal, compile_fail, [''])
    
    744
    +test('T26318', normal, compile_fail, [''])

  • utils/jsffi/dyld.mjs
    ... ... @@ -1105,6 +1105,20 @@ class DyLD {
    1105 1105
           if (/libHSghc-internal-\d+(\.\d+)*/i.test(soname)) {
    
    1106 1106
             this.rts_init();
    
    1107 1107
             delete this.rts_init;
    
    1108
    +
    
    1109
    +        // At this point the RTS symbols in linear memory are fixed
    
    1110
    +        // and constructors are run, especially the one in JSFFI.c
    
    1111
    +        // that does GHC RTS initialization for any code that links
    
    1112
    +        // JSFFI.o. Luckily no Haskell computation or gc has taken
    
    1113
    +        // place yet, so we must set keepCAFs=1 right now! Otherwise,
    
    1114
    +        // any BCO created by later TH splice or ghci expression may
    
    1115
    +        // refer to any CAF that's not reachable from GC roots (here
    
    1116
    +        // our only entry point is defaultServer) and the CAF could
    
    1117
    +        // have been GC'ed! (#26106)
    
    1118
    +        //
    
    1119
    +        // We call it here instead of in RTS C code, since we only
    
    1120
    +        // want keepCAFs=1 for ghci, not user code.
    
    1121
    +        this.exportFuncs.setKeepCAFs();
    
    1108 1122
           }
    
    1109 1123
           init();
    
    1110 1124
         }