Simon Peyton Jones pushed to branch wip/T26346 at Glasgow Haskell Compiler / GHC

Commits:

17 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/Core/Unify.hs
    ... ... @@ -245,16 +245,21 @@ give up on), but for /substitutivity/. If we have (F x x), we can see that (F x
    245 245
     can reduce to Double. So, it had better be the case that (F blah blah) can
    
    246 246
     reduce to Double, no matter what (blah) is!
    
    247 247
     
    
    248
    -To achieve this, `go_fam` in `uVarOrFam` does this;
    
    248
    +To achieve this, `go` in `uVarOrFam` does this;
    
    249
    +
    
    250
    +* We maintain /two/ substitutions, not just one:
    
    251
    +     * um_tv_env: the regular substitution, mapping TyVar :-> Type
    
    252
    +     * um_fam_env: maps (TyCon,[Type]) :-> Type, where the LHS is a type-fam application
    
    253
    +  In effect, these constitute one substitution mapping
    
    254
    +     CanEqLHS :-> Types
    
    249 255
     
    
    250 256
     * When we attempt to unify (G Float) ~ Int, we return MaybeApart..
    
    251
    -  but we /also/ extend a "family substitution" [G Float :-> Int],
    
    252
    -  in `um_fam_env`, alongside the regular [tyvar :-> type] substitution in
    
    253
    -  `um_tv_env`.  See the `BindMe` case of `go_fam` in `uVarOrFam`.
    
    257
    +  but we /also/ add a "family substitution" [G Float :-> Int],
    
    258
    +  to `um_fam_env`. See the `BindMe` case of `go` in `uVarOrFam`.
    
    254 259
     
    
    255 260
     * When we later encounter (G Float) ~ Bool, we apply the family substitution,
    
    256 261
       very much as we apply the conventional [tyvar :-> type] substitution
    
    257
    -  when we encounter a type variable.  See the `lookupFamEnv` in `go_fam` in
    
    262
    +  when we encounter a type variable.  See the `lookupFamEnv` in `go` in
    
    258 263
       `uVarOrFam`.
    
    259 264
     
    
    260 265
       So (G Float ~ Bool) becomes (Int ~ Bool) which is SurelyApart.  Bingo.
    
    ... ... @@ -329,7 +334,7 @@ Wrinkles
    329 334
        alternative path.  So `noMatchableGivenDicts` must return False;
    
    330 335
        so `mightMatchLater` must return False; so when um_bind_fam_fun returns
    
    331 336
        `DontBindMe`, the unifier must return `SurelyApart`, not `MaybeApart`.  See
    
    332
    -   `go_fam` in `uVarOrFam`
    
    337
    +   `go` in `uVarOrFam`
    
    333 338
     
    
    334 339
     (ATF6) When /matching/ can we ever have a type-family application on the LHS, in
    
    335 340
        the template?  You might think not, because type-class-instance and
    
    ... ... @@ -426,6 +431,26 @@ Wrinkles
    426 431
     (ATF12) There is a horrid exception for the injectivity check. See (UR1) in
    
    427 432
       in Note [Specification of unification].
    
    428 433
     
    
    434
    +(ATF13) Consider unifying
    
    435
    +    [F a, F Int, Int]  ~  [Bool, Char, a]
    
    436
    +  Working left to right you might think we would build the mapping
    
    437
    +    F a   :-> Bool
    
    438
    +    F Int :-> Char
    
    439
    +  Now we discover that `a` unifies with `Int`. So really these two lists are Apart
    
    440
    +  because F Int can't be both Bool and Char.
    
    441
    +
    
    442
    +  But that is very tricky! Perhaps whenever we unify a type variable we should
    
    443
    +  run it over the domain and (maybe range) of the type-family mapping too?
    
    444
    +  Sigh.
    
    445
    +
    
    446
    +  For we make no such attempt.  The um_fam_env has only pre-substituted types.
    
    447
    +  Fortunately, while this may make use say MaybeApart when we could say SurelyApart,
    
    448
    +  it has no effect on the correctness of unification: if we return Unifiable, it
    
    449
    +  really is Unifiable.
    
    450
    +
    
    451
    +(ATF14) We have to be careful about the occurs check.
    
    452
    +  See Note [The occurs check in the Core unifier]
    
    453
    +
    
    429 454
     SIDE NOTE.  The paper "Closed type families with overlapping equations"
    
    430 455
     http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/axioms-extended.pdf
    
    431 456
     tries to achieve the same effect with a standard yes/no unifier, by "flattening"
    
    ... ... @@ -1776,16 +1801,11 @@ uVarOrFam env ty1 ty2 kco
    1776 1801
         -- E.g.    a ~ F p q
    
    1777 1802
         --         Starts with: go a (F p q)
    
    1778 1803
         --         if `a` not bindable, swap to: go (F p q) a
    
    1779
    -    go swapped substs (TyVarLHS tv1) ty2 kco
    
    1780
    -      = go_tv swapped substs tv1 ty2 kco
    
    1781
    -
    
    1782
    -    go swapped substs (TyFamLHS tc tys) ty2 kco
    
    1783
    -      = go_fam swapped substs tc tys ty2 kco
    
    1784 1804
     
    
    1785 1805
         -----------------------------
    
    1786
    -    -- go_tv: LHS is a type variable
    
    1806
    +    -- LHS is a type variable
    
    1787 1807
         -- The sequence of tests is very similar to go_tv
    
    1788
    -    go_tv swapped substs tv1 ty2 kco
    
    1808
    +    go swapped substs lhs@(TyVarLHS tv1) ty2 kco
    
    1789 1809
           | Just ty1' <- lookupVarEnv (um_tv_env substs) tv1'
    
    1790 1810
           = -- We already have a substitution for tv1
    
    1791 1811
             if | um_unif env                          -> unify_ty env ty1' ty2 kco
    
    ... ... @@ -1837,7 +1857,6 @@ uVarOrFam env ty1 ty2 kco
    1837 1857
           where
    
    1838 1858
             tv1'            = umRnOccL env tv1
    
    1839 1859
             ty2_fvs         = tyCoVarsOfType ty2
    
    1840
    -        rhs_fvs         = ty2_fvs `unionVarSet` tyCoVarsOfCo kco
    
    1841 1860
             rhs             = ty2 `mkCastTy` mkSymCo kco
    
    1842 1861
             tv1_is_bindable | not (tv1' `elemVarSet` um_foralls env)
    
    1843 1862
                               -- tv1' is not forall-bound, but tv1 can still differ
    
    ... ... @@ -1848,16 +1867,15 @@ uVarOrFam env ty1 ty2 kco
    1848 1867
                             | otherwise
    
    1849 1868
                             = False
    
    1850 1869
     
    
    1851
    -        occurs_check = um_unif env &&
    
    1852
    -                       occursCheck (um_tv_env substs) tv1 rhs_fvs
    
    1870
    +        occurs_check = um_unif env && uOccursCheck substs lhs rhs
    
    1853 1871
               -- Occurs check, only when unifying
    
    1854 1872
               -- see Note [Infinitary substitutions]
    
    1855
    -          -- Make sure you include `kco` in rhs_tvs #14846
    
    1873
    +          -- Make sure you include `kco` in rhs #14846
    
    1856 1874
     
    
    1857 1875
         -----------------------------
    
    1858
    -    -- go_fam: LHS is a saturated type-family application
    
    1876
    +    -- LHS is a saturated type-family application
    
    1859 1877
         -- Invariant: ty2 is not a TyVarTy
    
    1860
    -    go_fam swapped substs tc1 tys1 ty2 kco
    
    1878
    +    go swapped substs lhs@(TyFamLHS tc1 tys1) ty2 kco
    
    1861 1879
           -- If we are under a forall, just give up and return MaybeApart
    
    1862 1880
           -- see (ATF3) in Note [Apartness and type families]
    
    1863 1881
           | not (isEmptyVarSet (um_foralls env))
    
    ... ... @@ -1883,9 +1901,10 @@ uVarOrFam env ty1 ty2 kco
    1883 1901
           -- Now check if we can bind the (F tys) to the RHS
    
    1884 1902
           -- This can happen even when matching: see (ATF7)
    
    1885 1903
           | BindMe <- um_bind_fam_fun env tc1 tys1 rhs
    
    1886
    -      = -- ToDo: do we need an occurs check here?
    
    1887
    -        do { extendFamEnv tc1 tys1 rhs
    
    1888
    -           ; maybeApart MARTypeFamily }
    
    1904
    +      = if uOccursCheck substs lhs rhs
    
    1905
    +        then maybeApart MARInfinite
    
    1906
    +        else do { extendFamEnv tc1 tys1 rhs  -- We don't substitue tys1; see (ATF13)
    
    1907
    +                ; maybeApart MARTypeFamily }
    
    1889 1908
     
    
    1890 1909
           -- Swap in case of (F a b) ~ (G c d e)
    
    1891 1910
           -- Maybe um_bind_fam_fun is False of (F a b) but true of (G c d e)
    
    ... ... @@ -1939,17 +1958,67 @@ uVarOrFam env ty1 ty2 kco
    1939 1958
            rhs2 = mkTyConApp tc tys1 `mkCastTy` kco
    
    1940 1959
     
    
    1941 1960
     
    
    1942
    -occursCheck :: TvSubstEnv -> TyVar -> TyCoVarSet -> Bool
    
    1943
    -occursCheck env tv1 tvs
    
    1944
    -  = anyVarSet bad tvs
    
    1961
    +uOccursCheck :: UMState -> CanEqLHS -> Type -> Bool
    
    1962
    +-- See Note [The occurs check in the Core unifier] and (ATF13)
    
    1963
    +uOccursCheck (UMState { um_tv_env = tv_env, um_fam_env = fam_env }) lhs ty
    
    1964
    +  = go emptyVarSet ty
    
    1945 1965
       where
    
    1946
    -    bad tv | Just ty <- lookupVarEnv env tv
    
    1947
    -           = anyVarSet bad (tyCoVarsOfType ty)
    
    1948
    -           | otherwise
    
    1949
    -           = tv == tv1
    
    1966
    +    go :: TyCoVarSet   -- Bound by enclosing foralls
    
    1967
    +       -> Type -> Bool
    
    1968
    +    go bvs ty | Just ty' <- coreView ty = go bvs ty'
    
    1969
    +    go bvs (TyVarTy tv) | Just ty' <- lookupVarEnv tv_env tv
    
    1970
    +                        = go bvs ty'
    
    1971
    +                        | TyVarLHS tv' <- lhs, tv==tv'
    
    1972
    +                        = True
    
    1973
    +                        | otherwise
    
    1974
    +                        = go bvs (tyVarKind tv)
    
    1975
    +    go bvs (AppTy ty1 ty2)           = go bvs ty1 || go bvs ty2
    
    1976
    +    go _   (LitTy {})                = False
    
    1977
    +    go bvs (FunTy _ w arg res)       = go bvs w || go bvs arg || go bvs res
    
    1978
    +    go bvs (TyConApp tc tys)         = go_tc bvs tc tys
    
    1979
    +
    
    1980
    +    go bvs (ForAllTy (Bndr tv _) ty)
    
    1981
    +      = go bvs (tyVarKind tv) ||
    
    1982
    +        (case lhs of
    
    1983
    +           TyVarLHS tv' | tv==tv'   -> False  -- Shadowing
    
    1984
    +                        | otherwise -> go (bvs `extendVarSet` tv) ty
    
    1985
    +           TyFamLHS {} -> False)  -- Lookups don't happen under a forall
    
    1986
    +
    
    1987
    +    go bvs (CastTy ty  _co) = go bvs ty  -- ToDo: should we worry about `co`?
    
    1988
    +    go _   (CoercionTy _co) = False      -- ToDo: should we worry about `co`?
    
    1989
    +
    
    1990
    +    go_tc bvs tc tys
    
    1991
    +      | isTypeFamilyTyCon tc
    
    1992
    +      , Just ty' <- lookupFamEnv fam_env tc (take arity tys)
    
    1993
    +      = go bvs ty' || any (go bvs) (drop arity tys)
    
    1994
    +
    
    1995
    +      | TyFamLHS tc' tys' <- lhs
    
    1996
    +      , tc == tc'
    
    1997
    +      , tys `lengthAtLeast` arity  -- Saturated, or over-saturated
    
    1998
    +      , and (zipWith tcEqType tys tys')
    
    1999
    +      = True
    
    2000
    +
    
    2001
    +      | otherwise
    
    2002
    +      = any (go bvs) tys
    
    2003
    +      where
    
    2004
    +        arity = tyConArity tc
    
    1950 2005
     
    
    1951
    -{- Note [Unifying coercion-foralls]
    
    1952
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2006
    +{- Note [The occurs check in the Core unifier]
    
    2007
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    2008
    +The unifier applies both substitutions (um_tv_env and um_fam_env) as it goes,
    
    2009
    +so we'll get an infinite loop if we have, for example
    
    2010
    +    um_tv_env:   a :-> F b      -- (1)
    
    2011
    +    um_fam_env   F b :-> a      -- (2)
    
    2012
    +
    
    2013
    +So (uOccursCheck substs lhs ty) returns True iff extending `substs` with `lhs :-> ty`
    
    2014
    +could lead to a loop. That is, could there by a type `s` such that
    
    2015
    +  applySubsts( (substs + lhs:->ty), s ) is infinite
    
    2016
    +
    
    2017
    +It's vital that we do both at once: we might have (1) already and add (2);
    
    2018
    +or we might have (2) already and add (1).
    
    2019
    +
    
    2020
    +Note [Unifying coercion-foralls]
    
    2021
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1953 2022
     Suppose we try to unify (forall cv. t1) ~ (forall cv. t2).
    
    1954 2023
     See Note [ForAllTy] in GHC.Core.TyCo.Rep.
    
    1955 2024
     
    

  • 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 =
    

  • compiler/GHC/Tc/Utils/Unify.hs
    ... ... @@ -3342,8 +3342,9 @@ mapCheck f xs
    3342 3342
     -- | Options describing how to deal with a type equality
    
    3343 3343
     -- in the eager unifier. See 'checkTyEqRhs'
    
    3344 3344
     data TyEqFlags m a
    
    3345
    -  -- | LHS is a type family application; we are not unifying.
    
    3346
    -  = TEFTyFam
    
    3345
    +  = -- | TFTyFam: LHS is a type family application
    
    3346
    +    -- Invariant: we are not unifying; see `notUnifying_TEFTask`
    
    3347
    +    TEFTyFam
    
    3347 3348
         { tefTyFam_occursCheck :: CheckTyEqProblem
    
    3348 3349
            -- ^ The 'CheckTyEqProblem' to report for occurs-check failures
    
    3349 3350
            -- (soluble or insoluble)
    
    ... ... @@ -3352,7 +3353,8 @@ data TyEqFlags m a
    3352 3353
         , tef_fam_app :: TyEqFamApp m a
    
    3353 3354
             -- ^ How to deal with type family applications
    
    3354 3355
         }
    
    3355
    -  -- | LHS is a 'TyVar'.
    
    3356
    +
    
    3357
    +  -- | TEFTyVar: LHS is a 'TyVar'.
    
    3356 3358
       | TEFTyVar
    
    3357 3359
         -- NB: this constructor does not actually store a 'TyVar', in order to
    
    3358 3360
         -- support being called from 'makeTypeConcrete' (which works as if we
    

  • 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_compile/T26346.hs
    1
    +{-# LANGUAGE GHC2024 #-}
    
    2
    +{-# LANGUAGE TypeFamilies #-}
    
    3
    +{-# LANGUAGE UndecidableInstances #-}
    
    4
    +module T26346 (warble) where
    
    5
    +
    
    6
    +import Data.Kind (Type)
    
    7
    +import Data.Type.Equality ((:~:)(..))
    
    8
    +
    
    9
    +type Nat :: Type
    
    10
    +data Nat = Z | S Nat
    
    11
    +
    
    12
    +type SNat :: Nat -> Type
    
    13
    +data SNat n where
    
    14
    +  SZ :: SNat Z
    
    15
    +  SS :: SNat n -> SNat (S n)
    
    16
    +
    
    17
    +type NatPlus :: Nat -> Nat -> Nat
    
    18
    +type family NatPlus a b where
    
    19
    +  NatPlus Z     b = b
    
    20
    +  NatPlus (S a) b = S (NatPlus a b)
    
    21
    +
    
    22
    +sNatPlus ::
    
    23
    +  forall (a :: Nat) (b :: Nat).
    
    24
    +  SNat a ->
    
    25
    +  SNat b ->
    
    26
    +  SNat (NatPlus a b)
    
    27
    +sNatPlus SZ     b = b
    
    28
    +sNatPlus (SS a) b = SS (sNatPlus a b)
    
    29
    +
    
    30
    +data Bin
    
    31
    +  = Zero
    
    32
    +  | Even Bin
    
    33
    +  | Odd Bin
    
    34
    +
    
    35
    +type SBin :: Bin -> Type
    
    36
    +data SBin b where
    
    37
    +  SZero :: SBin Zero
    
    38
    +  SEven :: SBin n -> SBin (Even n)
    
    39
    +  SOdd  :: SBin n -> SBin (Odd n)
    
    40
    +
    
    41
    +type Incr :: Bin -> Bin
    
    42
    +type family Incr b where
    
    43
    +  Incr Zero     = Odd Zero      -- 0 + 1 = (2*0) + 1
    
    44
    +  Incr (Even n) = Odd n         -- 2n + 1
    
    45
    +  Incr (Odd n)  = Even (Incr n) -- (2n + 1) + 1 = 2*(n + 1)
    
    46
    +
    
    47
    +type BinToNat :: Bin -> Nat
    
    48
    +type family BinToNat b where
    
    49
    +  BinToNat Zero     = Z
    
    50
    +  BinToNat (Even n) = NatPlus (BinToNat n) (BinToNat n)
    
    51
    +  BinToNat (Odd n)  = S (NatPlus (BinToNat n) (BinToNat n))
    
    52
    +
    
    53
    +sBinToNat ::
    
    54
    +  forall (b :: Bin).
    
    55
    +  SBin b ->
    
    56
    +  SNat (BinToNat b)
    
    57
    +sBinToNat SZero     = SZ
    
    58
    +sBinToNat (SEven n) = sNatPlus (sBinToNat n) (sBinToNat n)
    
    59
    +sBinToNat (SOdd n)  = SS (sNatPlus (sBinToNat n) (sBinToNat n))
    
    60
    +
    
    61
    +warble ::
    
    62
    +  forall (b :: Bin).
    
    63
    +  SBin b ->
    
    64
    +  BinToNat (Incr b) :~: S (BinToNat b)
    
    65
    +warble SZero = Refl
    
    66
    +warble (SEven {}) = Refl
    
    67
    +warble (SOdd  sb) | Refl <- warble sb
    
    68
    +                  , Refl <- plusComm sbn (SS sbn)
    
    69
    +                  = Refl
    
    70
    +  where
    
    71
    +    sbn = sBinToNat sb
    
    72
    +
    
    73
    +    plus0R ::
    
    74
    +      forall (n :: Nat).
    
    75
    +      SNat n ->
    
    76
    +      NatPlus n Z :~: n
    
    77
    +    plus0R SZ = Refl
    
    78
    +    plus0R (SS sn)
    
    79
    +      | Refl <- plus0R sn
    
    80
    +      = Refl
    
    81
    +
    
    82
    +    plusSnR ::
    
    83
    +      forall (n :: Nat) (m :: Nat).
    
    84
    +      SNat n ->
    
    85
    +      SNat m ->
    
    86
    +      NatPlus n (S m) :~: S (NatPlus n m)
    
    87
    +    plusSnR SZ _ = Refl
    
    88
    +    plusSnR (SS sn) sm
    
    89
    +      | Refl <- plusSnR sn sm
    
    90
    +      = Refl
    
    91
    +
    
    92
    +    plusComm ::
    
    93
    +      forall (n :: Nat) (m :: Nat).
    
    94
    +      SNat n ->
    
    95
    +      SNat m ->
    
    96
    +      NatPlus n m :~: NatPlus m n
    
    97
    +    plusComm SZ sm
    
    98
    +      | Refl <- plus0R sm
    
    99
    +      = Refl
    
    100
    +    plusComm (SS sn) sm
    
    101
    +      | Refl <- plusComm sn sm
    
    102
    +      , Refl <- plusSnR sm sn
    
    103
    +      = Refl

  • testsuite/tests/typecheck/should_compile/all.T
    ... ... @@ -945,3 +945,4 @@ test('T25992', normal, compile, [''])
    945 945
     test('T14010', normal, compile, [''])
    
    946 946
     test('T26256a', normal, compile, [''])
    
    947 947
     test('T25992a', normal, compile, [''])
    
    948
    +test('T26346', normal, compile, [''])

  • 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
         }