Simon Peyton Jones pushed to branch wip/T24464 at Glasgow Haskell Compiler / GHC
Commits:
-
c8978c05
by Simon Peyton Jones at 2025-11-07T00:31:51+00:00
10 changed files:
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types/BasicTypes.hs
- compiler/GHC/Tc/Utils/Env.hs
Changes:
| ... | ... | @@ -38,13 +38,16 @@ import Language.Haskell.Syntax.Expr( LHsExpr ) |
| 38 | 38 | import {-# SOURCE #-} GHC.Hs.Expr ( pprExpr, pprLExpr, pprFunBind, pprPatBind )
|
| 39 | 39 | import {-# SOURCE #-} GHC.Hs.Pat (pprLPat )
|
| 40 | 40 | |
| 41 | -import GHC.Data.BooleanFormula ( LBooleanFormula, pprBooleanFormulaNormal )
|
|
| 42 | -import GHC.Types.Tickish
|
|
| 43 | 41 | import GHC.Hs.Extension
|
| 44 | -import GHC.Parser.Annotation
|
|
| 45 | 42 | import GHC.Hs.Type
|
| 43 | + |
|
| 46 | 44 | import GHC.Tc.Types.Evidence
|
| 45 | + |
|
| 47 | 46 | import GHC.Core.Type
|
| 47 | + |
|
| 48 | +import GHC.Parser.Annotation
|
|
| 49 | + |
|
| 50 | +import GHC.Types.Tickish
|
|
| 48 | 51 | import GHC.Types.Name.Set
|
| 49 | 52 | import GHC.Types.Basic
|
| 50 | 53 | import GHC.Types.SourceText
|
| ... | ... | @@ -52,6 +55,8 @@ import GHC.Types.SrcLoc as SrcLoc |
| 52 | 55 | import GHC.Types.Var
|
| 53 | 56 | import GHC.Types.Name
|
| 54 | 57 | |
| 58 | +import GHC.Data.BooleanFormula ( LBooleanFormula, pprBooleanFormulaNormal )
|
|
| 59 | + |
|
| 55 | 60 | import GHC.Utils.Outputable
|
| 56 | 61 | import GHC.Utils.Panic
|
| 57 | 62 | import GHC.Utils.Misc
|
| ... | ... | @@ -89,7 +94,18 @@ data HsValBindGroups p -- Divided into strongly connected components |
| 89 | 94 | type family HsValBindGroup p
|
| 90 | 95 | type instance HsValBindGroup GhcPs = ()
|
| 91 | 96 | type instance HsValBindGroup GhcRn = (RecFlag, LHsBinds GhcRn)
|
| 92 | -type instance HsValBindGroup GhcTc = (RecFlag, LHsBinds GhcTc, TopLevelFlag)
|
|
| 97 | +type instance HsValBindGroup GhcTc = (RecFlag, LHsBinds GhcTc, StaticFlag)
|
|
| 98 | + |
|
| 99 | +data StaticFlag
|
|
| 100 | + = IsStatic | NotStatic
|
|
| 101 | + deriving( Data )
|
|
| 102 | + -- IsStatic <=> this binding consists only code; all free
|
|
| 103 | + -- vars are top level (or themselves static).
|
|
| 104 | + -- So it can be moved to top level
|
|
| 105 | + |
|
| 106 | +instance Outputable StaticFlag where
|
|
| 107 | + ppr IsStatic = text "static"
|
|
| 108 | + ppr NotStatic = text "not-static"
|
|
| 93 | 109 | |
| 94 | 110 | -- ---------------------------------------------------------------------
|
| 95 | 111 |
| ... | ... | @@ -95,9 +95,9 @@ dsLocalBinds (HsIPBinds _ binds) body = dsIPBinds binds body |
| 95 | 95 | -------------------------
|
| 96 | 96 | -- caller sets location
|
| 97 | 97 | dsValBinds :: HsValBinds GhcTc -> CoreExpr -> DsM CoreExpr
|
| 98 | -dsValBinds (XValBindsLR (NValBinds binds _)) body
|
|
| 98 | +dsValBinds (XValBindsLR (HsVBG grps _)) body
|
|
| 99 | 99 | = do { dflags <- getDynFlags
|
| 100 | - ; foldrM (ds_val_bind dflags) body binds }
|
|
| 100 | + ; foldrM (ds_val_bind dflags) body grps }
|
|
| 101 | 101 | dsValBinds (ValBinds {}) _ = panic "dsValBinds ValBindsIn"
|
| 102 | 102 | |
| 103 | 103 | -------------------------
|
| ... | ... | @@ -119,12 +119,14 @@ dsIPBinds (IPBinds ev_binds ip_binds) body |
| 119 | 119 | |
| 120 | 120 | -------------------------
|
| 121 | 121 | -- caller sets location
|
| 122 | -ds_val_bind :: DynFlags -> (RecFlag, LHsBinds GhcTc) -> CoreExpr -> DsM CoreExpr
|
|
| 122 | +ds_val_bind :: DynFlags
|
|
| 123 | + -> (RecFlag, LHsBinds GhcTc, StaticFlag) -> CoreExpr
|
|
| 124 | + -> DsM CoreExpr
|
|
| 123 | 125 | -- Special case for bindings which bind unlifted variables
|
| 124 | 126 | -- We need to do a case right away, rather than building
|
| 125 | 127 | -- a tuple and doing selections.
|
| 126 | 128 | -- Silently ignore INLINE and SPECIALISE pragmas...
|
| 127 | -ds_val_bind _ (NonRecursive, hsbinds) body
|
|
| 129 | +ds_val_bind _ (NonRecursive, hsbinds, _) body
|
|
| 128 | 130 | | [L loc bind] <- hsbinds
|
| 129 | 131 | -- Non-recursive, non-overloaded bindings only come in ones
|
| 130 | 132 | -- ToDo: in some bizarre case it's conceivable that there
|
| ... | ... | @@ -158,7 +160,7 @@ ds_val_bind _ (NonRecursive, hsbinds) body |
| 158 | 160 | is_polymorphic _ = False
|
| 159 | 161 | |
| 160 | 162 | |
| 161 | -ds_val_bind _ (is_rec, binds) _body
|
|
| 163 | +ds_val_bind _ (is_rec, binds, _) _body
|
|
| 162 | 164 | | any (isUnliftedHsBind . unLoc) binds -- see Note [Strict binds checks] in GHC.HsToCore.Binds
|
| 163 | 165 | = assert (isRec is_rec )
|
| 164 | 166 | errDsCoreExpr $ DsRecBindsNotAllowedForUnliftedTys binds
|
| ... | ... | @@ -168,7 +170,7 @@ ds_val_bind _ (is_rec, binds) _body |
| 168 | 170 | -- linear, but selectors as used in the general case aren't. So the general case
|
| 169 | 171 | -- would transform a linear definition into a non-linear one. See Wrinkle 2
|
| 170 | 172 | -- Note [Desugar Strict binds] in GHC.HsToCore.Binds.
|
| 171 | -ds_val_bind dflags (NonRecursive, hsbinds) body
|
|
| 173 | +ds_val_bind dflags (NonRecursive, hsbinds, _) body
|
|
| 172 | 174 | | [L _loc (PatBind { pat_lhs = pat, pat_rhs = grhss, pat_mult = mult_ann
|
| 173 | 175 | , pat_ext = (ty, (rhs_tick, _var_ticks))})] <- hsbinds
|
| 174 | 176 | -- Non-recursive, non-overloaded bindings only come in ones
|
| ... | ... | @@ -190,21 +192,26 @@ ds_val_bind dflags (NonRecursive, hsbinds) body |
| 190 | 192 | -- problem?
|
| 191 | 193 | |
| 192 | 194 | -- Ordinary case for bindings; none should be unlifted
|
| 193 | -ds_val_bind _ (is_rec, binds) body
|
|
| 195 | +ds_val_bind _ (is_rec, binds, static_flag) body
|
|
| 194 | 196 | = do { massert (isRec is_rec || isSingleton binds)
|
| 195 | - -- we should never produce a non-recursive list of multiple binds
|
|
| 197 | + -- We should never produce a non-recursive list of multiple binds
|
|
| 196 | 198 | |
| 197 | 199 | ; (force_vars,prs) <- dsLHsBinds binds
|
| 198 | - ; let body' = foldr seqVar body force_vars
|
|
| 200 | + |
|
| 199 | 201 | ; assertPpr (not (any (isUnliftedType . idType . fst) prs)) (ppr is_rec $$ ppr binds) $
|
| 200 | 202 | -- NB: bindings have a fixed RuntimeRep, so it's OK to call isUnliftedType
|
| 201 | 203 | case prs of
|
| 202 | 204 | [] -> return body
|
| 203 | - _ -> return (mkLets (mk_binds is_rec prs) body') }
|
|
| 205 | + _ -> case static_flag of
|
|
| 206 | + NotStatic -> return (mkLets (mk_binds is_rec prs) body')
|
|
| 207 | + IsStatic -> do { emitStaticBinds prs; return body' }
|
|
| 208 | + where
|
|
| 209 | + body' = foldr seqVar body force_vars
|
|
| 204 | 210 | -- We can make a non-recursive let because we make sure to return
|
| 205 | 211 | -- the bindings in dependency order in dsLHsBinds,
|
| 206 | 212 | -- see Note [Return non-recursive bindings in dependency order] in
|
| 207 | 213 | -- GHC.HsToCore.Binds
|
| 214 | + }
|
|
| 208 | 215 | |
| 209 | 216 | -- | Helper function. You can use the result of 'mk_binds' with 'mkLets' for
|
| 210 | 217 | -- instance.
|
| ... | ... | @@ -494,7 +501,7 @@ dsExpr (HsStatic (_, whole_ty) expr@(L loc _)) |
| 494 | 501 | |
| 495 | 502 | ; static_id <- newStaticId (mkSpecForAllTys static_fvs whole_ty)
|
| 496 | 503 | |
| 497 | - ; emitStaticBind static_id static_rhs
|
|
| 504 | + ; emitStaticBinds [(static_id, static_rhs)]
|
|
| 498 | 505 | |
| 499 | 506 | ; return (mkVarApps (Var static_id) static_fvs) }
|
| 500 | 507 |
| ... | ... | @@ -34,7 +34,7 @@ module GHC.HsToCore.Monad ( |
| 34 | 34 | DsMetaEnv, DsMetaVal(..), dsGetMetaEnv, dsLookupMetaEnv, dsExtendMetaEnv,
|
| 35 | 35 | |
| 36 | 36 | -- Static bindings
|
| 37 | - emitStaticBind, getStaticBinds,
|
|
| 37 | + emitStaticBinds, getStaticBinds,
|
|
| 38 | 38 | |
| 39 | 39 | -- Getting and setting pattern match oracle states
|
| 40 | 40 | getPmNablas, updPmNablas,
|
| ... | ... | @@ -643,10 +643,10 @@ pprRuntimeTrace str doc expr = do |
| 643 | 643 | getCCIndexDsM :: FastString -> DsM CostCentreIndex
|
| 644 | 644 | getCCIndexDsM = getCCIndexM ds_cc_st
|
| 645 | 645 | |
| 646 | -emitStaticBind :: Id -> CoreExpr -> DsM ()
|
|
| 647 | -emitStaticBind static_id rhs
|
|
| 646 | +emitStaticBinds :: [(Id,CoreExpr)] -> DsM ()
|
|
| 647 | +emitStaticBinds static_binds
|
|
| 648 | 648 | = do { env <- getGblEnv
|
| 649 | - ; liftIO $ modifyIORef' (ds_static_binds env) (`snocOL` (static_id,rhs)) }
|
|
| 649 | + ; liftIO $ modifyIORef' (ds_static_binds env) (`appOL` toOL static_binds) }
|
|
| 650 | 650 | |
| 651 | 651 | getStaticBinds :: DsM (OrdList (Id,CoreExpr))
|
| 652 | 652 | getStaticBinds = do { env <- getGblEnv
|
| ... | ... | @@ -341,8 +341,8 @@ hsScopedTvBinders binds |
| 341 | 341 | = concatMap get_scoped_tvs sigs
|
| 342 | 342 | where
|
| 343 | 343 | sigs = case binds of
|
| 344 | - ValBinds _ _ sigs -> sigs
|
|
| 345 | - XValBindsLR (NValBinds _ sigs) -> sigs
|
|
| 344 | + ValBinds _ _ sigs -> sigs
|
|
| 345 | + XValBindsLR (HsVBG _ sigs) -> sigs
|
|
| 346 | 346 | |
| 347 | 347 | get_scoped_tvs :: LSig GhcRn -> [Name]
|
| 348 | 348 | get_scoped_tvs (L _ signature)
|
| ... | ... | @@ -1987,7 +1987,7 @@ rep_implicit_param_name (HsIPName name) = coreStringLit name |
| 1987 | 1987 | |
| 1988 | 1988 | rep_val_binds :: HsValBinds GhcRn -> MetaM [(SrcSpan, Core (M TH.Dec))]
|
| 1989 | 1989 | -- Assumes: all the binders of the binding are already in the meta-env
|
| 1990 | -rep_val_binds (XValBindsLR (NValBinds binds sigs))
|
|
| 1990 | +rep_val_binds (XValBindsLR (HsVBG binds sigs))
|
|
| 1991 | 1991 | = do { core1 <- rep_binds (concatMap snd binds)
|
| 1992 | 1992 | ; core2 <- rep_sigs sigs
|
| 1993 | 1993 | ; return (core1 ++ core2) }
|
| ... | ... | @@ -260,7 +260,7 @@ tcLocalBinds (HsIPBinds x (IPBinds _ ip_binds)) thing_inside |
| 260 | 260 | tcValBinds :: TopLevelFlag
|
| 261 | 261 | -> [(RecFlag, LHsBinds GhcRn)] -> [LSig GhcRn]
|
| 262 | 262 | -> TcM thing
|
| 263 | - -> TcM ([(RecFlag, LHsBinds GhcTc, TopLevelFlag)], thing)
|
|
| 263 | + -> TcM ([(RecFlag, LHsBinds GhcTc, StaticFlag)], thing)
|
|
| 264 | 264 | |
| 265 | 265 | tcValBinds top_lvl grps sigs thing_inside
|
| 266 | 266 | = do { -- Typecheck the signatures
|
| ... | ... | @@ -285,7 +285,7 @@ tcValBinds top_lvl grps sigs thing_inside |
| 285 | 285 | -- See Note [Pattern synonym builders don't yield dependencies]
|
| 286 | 286 | -- in GHC.Rename.Bind
|
| 287 | 287 | ; patsyn_builders <- mapM (tcPatSynBuilderBind prag_fn) patsyns
|
| 288 | - ; let extra_binds = [ (NonRecursive, builder, TopLevel)
|
|
| 288 | + ; let extra_binds = [ (NonRecursive, builder, IsStatic)
|
|
| 289 | 289 | | builder <- patsyn_builders ]
|
| 290 | 290 | ; return (extra_binds, thing) }
|
| 291 | 291 | ; return (binds' ++ extra_binds', thing) }}
|
| ... | ... | @@ -297,7 +297,7 @@ tcValBinds top_lvl grps sigs thing_inside |
| 297 | 297 | |
| 298 | 298 | tcBindGroups :: TopLevelFlag -> TcSigFun -> TcPragEnv
|
| 299 | 299 | -> [(RecFlag, LHsBinds GhcRn)] -> TcM thing
|
| 300 | - -> TcM ([(RecFlag, LHsBinds GhcTc, TopLevelFlag)], thing)
|
|
| 300 | + -> TcM ([(RecFlag, LHsBinds GhcTc, StaticFlag)], thing)
|
|
| 301 | 301 | -- Typecheck a whole lot of value bindings,
|
| 302 | 302 | -- one strongly-connected component at a time
|
| 303 | 303 | -- Here a "strongly connected component" has the straightforward
|
| ... | ... | @@ -334,7 +334,7 @@ before we sub-divide it based on what type signatures it has. |
| 334 | 334 | tc_group :: forall thing.
|
| 335 | 335 | TopLevelFlag -> TcSigFun -> TcPragEnv
|
| 336 | 336 | -> (RecFlag, LHsBinds GhcRn) -> TcM thing
|
| 337 | - -> TcM ((RecFlag, LHsBinds GhcTc, TopLevelFlag), thing)
|
|
| 337 | + -> TcM ((RecFlag, LHsBinds GhcTc, StaticFlag), thing)
|
|
| 338 | 338 | -- Typecheck one strongly-connected component of the original program.
|
| 339 | 339 | tc_group top_lvl sig_fn prag_fn (rec_flag, binds) thing_inside
|
| 340 | 340 | = case rec_flag of
|
| ... | ... | @@ -345,12 +345,12 @@ tc_group top_lvl sig_fn prag_fn (rec_flag, binds) thing_inside |
| 345 | 345 | tc_nonrec_group :: forall thing.
|
| 346 | 346 | TopLevelFlag -> TcSigFun -> TcPragEnv
|
| 347 | 347 | -> LHsBinds GhcRn -> TcM thing
|
| 348 | - -> TcM ((RecFlag, LHsBinds GhcTc, TopLevelFlag), thing)
|
|
| 348 | + -> TcM ((RecFlag, LHsBinds GhcTc, StaticFlag), thing)
|
|
| 349 | 349 | tc_nonrec_group top_lvl sig_fn prag_fn [lbind] thing_inside
|
| 350 | 350 | | L loc (PatSynBind _ psb) <- lbind
|
| 351 | 351 | = do { (aux_binds, tcg_env) <- tcPatSynDecl (L loc psb) sig_fn prag_fn
|
| 352 | 352 | ; thing <- setGblEnv tcg_env thing_inside
|
| 353 | - ; return ((NonRecursive, aux_binds, TopLevel), thing) }
|
|
| 353 | + ; return ((NonRecursive, aux_binds, IsStatic), thing) }
|
|
| 354 | 354 | |
| 355 | 355 | | otherwise
|
| 356 | 356 | = -- A single non-recursive binding
|
| ... | ... | @@ -375,7 +375,7 @@ tc_nonrec_group _ _ _ binds _ -- Non-rec groups should always be a singleton |
| 375 | 375 | tc_rec_group :: forall thing.
|
| 376 | 376 | TopLevelFlag -> TcSigFun -> TcPragEnv
|
| 377 | 377 | -> LHsBinds GhcRn -> TcM thing
|
| 378 | - -> TcM ((RecFlag, LHsBinds GhcTc, TopLevelFlag), thing)
|
|
| 378 | + -> TcM ((RecFlag, LHsBinds GhcTc, StaticFlag), thing)
|
|
| 379 | 379 | tc_rec_group top_lvl sig_fn prag_fn binds thing_inside
|
| 380 | 380 | = -- For a recursive group, to maximise polymorphism, we do a new
|
| 381 | 381 | -- strongly-connected-component analysis, this time omitting
|
| ... | ... | @@ -1855,7 +1855,7 @@ decideGeneralisationPlan dflags top_lvl closed sig_fn lbinds |
| 1855 | 1855 | |
| 1856 | 1856 | isClosedBndrGroup :: TcTypeEnv -> [LHsBind GhcRn] -> IsGroupClosed
|
| 1857 | 1857 | isClosedBndrGroup type_env binds
|
| 1858 | - = IsGroupClosed is_top fv_env type_closed
|
|
| 1858 | + = IsGroupClosed is_static fv_env type_closed
|
|
| 1859 | 1859 | where
|
| 1860 | 1860 | fv_env :: NameEnv NameSet
|
| 1861 | 1861 | fv_env = mkNameEnv $ [ (b,fvs) | (bs,fvs) <- bind_fvs, b <-bs ]
|
| ... | ... | @@ -1875,16 +1875,20 @@ isClosedBndrGroup type_env binds |
| 1875 | 1875 | `delListFromNameSet` all_bndrs
|
| 1876 | 1876 | -- all_fvs does not include the binders of this group
|
| 1877 | 1877 | |
| 1878 | - is_top | nameSetAll id_is_top all_fvs = TopLevel
|
|
| 1879 | - | otherwise = NotTopLevel
|
|
| 1878 | + is_static | not (any (is_pat_bind . unLoc) binds)
|
|
| 1879 | + , nameSetAll id_is_static all_fvs = IsStatic
|
|
| 1880 | + | otherwise = NotStatic
|
|
| 1880 | 1881 | |
| 1881 | - id_is_top :: Name -> Bool
|
|
| 1882 | - id_is_top name
|
|
| 1882 | + is_pat_bind (PatBind {}) = True
|
|
| 1883 | + is_pat_bind _ = False
|
|
| 1884 | + |
|
| 1885 | + id_is_static :: Name -> Bool
|
|
| 1886 | + id_is_static name
|
|
| 1883 | 1887 | | Just thing <- lookupNameEnv type_env name
|
| 1884 | 1888 | = case thing of
|
| 1885 | - AGlobal {} -> True
|
|
| 1886 | - ATcId { tct_info = LetBound { lb_top = top } } -> isTopLevel top
|
|
| 1887 | - _ -> False
|
|
| 1889 | + AGlobal {} -> True
|
|
| 1890 | + ATcId { tct_info = LetBound { lb_top = IsStatic } } -> True
|
|
| 1891 | + _ -> False
|
|
| 1888 | 1892 | |
| 1889 | 1893 | | otherwise -- Imported Ids
|
| 1890 | 1894 | = True
|
| ... | ... | @@ -1897,10 +1901,12 @@ isClosedBndrGroup type_env binds |
| 1897 | 1901 | is_closed_type_id name
|
| 1898 | 1902 | | Just thing <- lookupNameEnv type_env name
|
| 1899 | 1903 | = case thing of
|
| 1900 | - AGlobal {} -> True
|
|
| 1901 | - ATcId { tct_info = info } -> lb_closed info
|
|
| 1902 | - ATyVar {} -> False
|
|
| 1903 | - -- In-scope type variables are not closed!
|
|
| 1904 | + AGlobal {} -> True
|
|
| 1905 | + ATyVar {} -> False -- In-scope type variables are not closed!
|
|
| 1906 | + ATcId { tct_info = info}
|
|
| 1907 | + -> case info of
|
|
| 1908 | + LetBound { lb_closed = closed } -> closed
|
|
| 1909 | + NotLetBound -> False
|
|
| 1904 | 1910 | _ -> pprPanic "is_closed_id" (ppr name)
|
| 1905 | 1911 | |
| 1906 | 1912 | | otherwise
|
| ... | ... | @@ -1911,13 +1917,13 @@ isClosedBndrGroup type_env binds |
| 1911 | 1917 | |
| 1912 | 1918 | adjustClosedForUnlifted :: IsGroupClosed -> [Scaled TcId] -> IsGroupClosed
|
| 1913 | 1919 | adjustClosedForUnlifted closed@(IsGroupClosed top_lvl fv_env type_closed) ids
|
| 1914 | - | TopLevel <- top_lvl
|
|
| 1920 | + | IsStatic <- top_lvl
|
|
| 1915 | 1921 | , all definitely_lifted ids = closed
|
| 1916 | - | otherwise = IsGroupClosed NotTopLevel fv_env type_closed
|
|
| 1922 | + | otherwise = IsGroupClosed NotStatic fv_env type_closed
|
|
| 1917 | 1923 | where
|
| 1918 | 1924 | definitely_lifted (Scaled _ id) = definitelyLiftedType (idType id)
|
| 1919 | 1925 | |
| 1920 | -sendToTopLevel :: IsGroupClosed -> TopLevelFlag
|
|
| 1926 | +sendToTopLevel :: IsGroupClosed -> StaticFlag
|
|
| 1921 | 1927 | sendToTopLevel (IsGroupClosed top _ _) = top
|
| 1922 | 1928 | |
| 1923 | 1929 | lHsBindFreeVars :: LHsBind GhcRn -> NameSet
|
| ... | ... | @@ -1506,7 +1506,7 @@ expandRecordUpd record_expr possible_parents rbnds res_ty |
| 1506 | 1506 | |
| 1507 | 1507 | let_binds :: HsLocalBindsLR GhcRn GhcRn
|
| 1508 | 1508 | let_binds = HsValBinds noAnn $ XValBindsLR
|
| 1509 | - $ NValBinds upd_ids_lhs (map mk_idSig upd_ids)
|
|
| 1509 | + $ HsVBG upd_ids_lhs (map mk_idSig upd_ids)
|
|
| 1510 | 1510 | upd_ids_lhs :: [(RecFlag, LHsBindsLR GhcRn GhcRn)]
|
| 1511 | 1511 | upd_ids_lhs = [ (NonRecursive, [genSimpleFunBind (idName id) [] rhs])
|
| 1512 | 1512 | | (_, (id, rhs)) <- upd_ids ]
|
| ... | ... | @@ -1821,9 +1821,8 @@ checkClosedInStaticForm name = do |
| 1821 | 1821 | -- visited nodes, so we avoid repeating cycles in the traversal.
|
| 1822 | 1822 | case lookupNameEnv type_env n of
|
| 1823 | 1823 | Just (ATcId { tct_id = tcid, tct_info = info }) -> case info of
|
| 1824 | - ClosedLet -> Nothing
|
|
| 1825 | 1824 | NotLetBound -> Just NotLetBoundReason
|
| 1826 | - NonClosedLet fvs type_closed -> listToMaybe $
|
|
| 1825 | + LetBound { lb_fvs = fvs, lb_closed = type_closed } -> listToMaybe $
|
|
| 1827 | 1826 | -- Look for a non-closed variable in fvs
|
| 1828 | 1827 | [ NotClosed n' reason
|
| 1829 | 1828 | | n' <- nameSetElemsStable fvs
|
| ... | ... | @@ -791,7 +791,7 @@ tcRnHsBootDecls boot_or_sig decls |
| 791 | 791 | , hs_defds = def_decls
|
| 792 | 792 | , hs_ruleds = rule_decls
|
| 793 | 793 | , hs_annds = _
|
| 794 | - , hs_valds = XValBindsLR (NValBinds val_binds val_sigs) })
|
|
| 794 | + , hs_valds = XValBindsLR (HsVBG val_binds val_sigs) })
|
|
| 795 | 795 | <- rnTopSrcDecls first_group
|
| 796 | 796 | |
| 797 | 797 | ; (gbl_env, lie) <- setGblEnv tcg_env $ captureTopConstraints $ do {
|
| ... | ... | @@ -1707,7 +1707,7 @@ tcTopSrcDecls (HsGroup { hs_tyclds = tycl_decls, |
| 1707 | 1707 | hs_annds = annotation_decls,
|
| 1708 | 1708 | hs_ruleds = rule_decls,
|
| 1709 | 1709 | hs_valds = hs_val_binds@(XValBindsLR
|
| 1710 | - (NValBinds val_binds val_sigs)) })
|
|
| 1710 | + (HsVBG val_binds val_sigs)) })
|
|
| 1711 | 1711 | = do { -- Type-check the type and class decls, and all imported decls
|
| 1712 | 1712 | -- The latter come in via tycl_decls
|
| 1713 | 1713 | traceTc "Tc2 (src)" empty ;
|
| ... | ... | @@ -1716,7 +1716,7 @@ tcTopSrcDecls (HsGroup { hs_tyclds = tycl_decls, |
| 1716 | 1716 | -- and import the supporting declarations
|
| 1717 | 1717 | traceTc "Tc3" empty ;
|
| 1718 | 1718 | (tcg_env, inst_infos, th_bndrs,
|
| 1719 | - XValBindsLR (NValBinds deriv_binds deriv_sigs))
|
|
| 1719 | + XValBindsLR (HsVBG deriv_binds deriv_sigs))
|
|
| 1720 | 1720 | <- tcTyClsInstDecls tycl_decls deriv_decls default_decls val_binds ;
|
| 1721 | 1721 | |
| 1722 | 1722 | updLclCtxt (\tcl_env -> tcl_env { tcl_th_bndrs = th_bndrs `plusNameEnv` tcl_th_bndrs tcl_env }) $
|
| ... | ... | @@ -2316,7 +2316,7 @@ tcUserStmt (L loc (BodyStmt _ expr _ _)) |
| 2316 | 2316 | -- [let it = expr]
|
| 2317 | 2317 | let_stmt = L loc $ LetStmt noAnn $ HsValBinds noAnn
|
| 2318 | 2318 | $ XValBindsLR
|
| 2319 | - (NValBinds [(NonRecursive,[the_bind])] [])
|
|
| 2319 | + (HsVBG [(NonRecursive,[the_bind])] [])
|
|
| 2320 | 2320 | |
| 2321 | 2321 | -- [it <- e]
|
| 2322 | 2322 | bind_stmt = L loc $ BindStmt
|
| ... | ... | @@ -846,7 +846,7 @@ tcRecSelBinds sel_bind_prs |
| 846 | 846 | -- See Note [Impredicative record selectors]
|
| 847 | 847 | setXOptM LangExt.ImpredicativeTypes $
|
| 848 | 848 | tcValBinds TopLevel binds sigs getGblEnv
|
| 849 | - ; return (tcg_env `addTypecheckedBinds` map snd rec_sel_binds) }
|
|
| 849 | + ; return (tcg_env `addTypecheckedBinds` map sndOf3 rec_sel_binds) }
|
|
| 850 | 850 | where
|
| 851 | 851 | sigs = [ L (noAnnSrcSpan loc) (XSig $ IdSig sel_id)
|
| 852 | 852 | | (sel_id, _) <- sel_bind_prs
|
| ... | ... | @@ -37,6 +37,7 @@ import GHC.Types.Name.Env |
| 37 | 37 | import GHC.Types.Name.Set
|
| 38 | 38 | |
| 39 | 39 | import GHC.Hs.Extension ( GhcRn )
|
| 40 | +import GHC.Hs.Binds ( StaticFlag )
|
|
| 40 | 41 | |
| 41 | 42 | import Language.Haskell.Syntax.Type ( LHsSigWcType )
|
| 42 | 43 | |
| ... | ... | @@ -309,7 +310,7 @@ data TcTyThing |
| 309 | 310 | |
| 310 | 311 | | ATcId -- Ids defined in this module; may not be fully zonked
|
| 311 | 312 | { tct_id :: Id
|
| 312 | - , tct_info :: IdBindingInfo -- See Note [Meaning of IdBindingInfo]
|
|
| 313 | + , tct_info :: IdBindingInfo
|
|
| 313 | 314 | }
|
| 314 | 315 | |
| 315 | 316 | | ATyVar Name TcTyVar -- See Note [Type variables in the type environment]
|
| ... | ... | @@ -346,16 +347,16 @@ instance Outputable TcTyThing where -- Debugging only |
| 346 | 347 | -- b) to figure out when a nested binding can be generalised,
|
| 347 | 348 | -- in 'GHC.Tc.Gen.Bind.decideGeneralisationPlan'.
|
| 348 | 349 | --
|
| 349 | -data IdBindingInfo -- See Note [Meaning of IdBindingInfo]
|
|
| 350 | +data IdBindingInfo
|
|
| 350 | 351 | = NotLetBound
|
| 351 | 352 | |
| 352 | 353 | | LetBound
|
| 353 | - { lb_top :: TopLevelFlag
|
|
| 354 | - -- TopLevel <=> this binding may safely be moved to top level
|
|
| 354 | + { lb_top :: StaticFlag
|
|
| 355 | + -- IsStatic <=> this binding may safely be moved to top level
|
|
| 355 | 356 | -- E.g f x = let ys = reverse [1,2]
|
| 356 | 357 | -- zs = reverse ys
|
| 357 | 358 | -- in ...
|
| 358 | - -- Both ys and zs count as TopLevel
|
|
| 359 | + -- Both ys and zs count as IsStatic
|
|
| 359 | 360 | |
| 360 | 361 | , lb_fvs :: RhsNames
|
| 361 | 362 | -- Free vars of the RHS that are NotLetBound, or LetBound NotTopLevel
|
| ... | ... | @@ -372,7 +373,7 @@ data IdBindingInfo -- See Note [Meaning of IdBindingInfo] |
| 372 | 373 | -- mutually-recursive /renamed/ (but not yet typechecked) bindings
|
| 373 | 374 | data IsGroupClosed
|
| 374 | 375 | = IsGroupClosed
|
| 375 | - TopLevelFlag -- TopLevel <=> all free vars are themselves TopLevel
|
|
| 376 | + StaticFlag -- IsStatic <=> all free vars of the group are top-level or static
|
|
| 376 | 377 | (NameEnv RhsNames) -- Frees for the RHS of each binding in the group
|
| 377 | 378 | -- (includes free vars of RHS bound in the same group)
|
| 378 | 379 | ClosedTypeId -- True <=> all the free vars of the group have closed types
|
| ... | ... | @@ -383,8 +384,21 @@ type RhsNames = NameSet -- Names of variables, mentioned on the RHS of |
| 383 | 384 | type ClosedTypeId = Bool
|
| 384 | 385 | -- See Note [Meaning of IdBindingInfo]
|
| 385 | 386 | |
| 386 | -{- Note [Meaning of IdBindingInfo]
|
|
| 387 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 387 | +{- Note [Static bindings and StaticFlag]
|
|
| 388 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 389 | +A (possibly-recursive) binding is /static/ iff
|
|
| 390 | + * It is syntactically top-level
|
|
| 391 | +OR
|
|
| 392 | + * It is not a PatBind
|
|
| 393 | + * Its free variables are all static
|
|
| 394 | + * It has a lifted type
|
|
| 395 | + |
|
| 396 | +Static bindings are important for static forms (static e):
|
|
| 397 | + * The free vars of `e` must all be static
|
|
| 398 | + * All static bindings are immediately floated to top level by the desugarer
|
|
| 399 | + * The desugarer also floats `e` to top level, and replaces (static e)
|
|
| 400 | +Static bindings can all float to top level, and the de
|
|
| 401 | + |
|
| 388 | 402 | * NotLetBound means that
|
| 389 | 403 | - the Id is not let-bound (e.g. it is bound in a
|
| 390 | 404 | lambda-abstraction or in a case pattern)
|
| ... | ... | @@ -675,7 +675,7 @@ tcExtendRecIds :: [(Name, TcId)] -> TcM a -> TcM a |
| 675 | 675 | tcExtendRecIds pairs thing_inside
|
| 676 | 676 | = tc_extend_local_env NotTopLevel
|
| 677 | 677 | [ (name, ATcId { tct_id = let_id
|
| 678 | - , tct_info = LetBound { lb_top = NotTopLevel
|
|
| 678 | + , tct_info = LetBound { lb_top = NotStatic
|
|
| 679 | 679 | , lb_fvs = emptyNameSet
|
| 680 | 680 | , lb_closed = False } })
|
| 681 | 681 | | (name, let_id) <- pairs ] $
|
| ... | ... | @@ -691,7 +691,7 @@ tcExtendSigIds top_lvl sig_ids thing_inside |
| 691 | 691 | , tct_info = info })
|
| 692 | 692 | | id <- sig_ids
|
| 693 | 693 | , let closed = isTypeClosedLetBndr id
|
| 694 | - info = LetBound { lb_top = NotTopLevel
|
|
| 694 | + info = LetBound { lb_top = NotStatic
|
|
| 695 | 695 | , lb_fvs = emptyNameSet
|
| 696 | 696 | , lb_closed = closed } ]
|
| 697 | 697 | thing_inside
|
| ... | ... | @@ -703,7 +703,7 @@ tcExtendLetEnv :: TopLevelFlag -> TcSigFun -> IsGroupClosed |
| 703 | 703 | -- Used for both top-level value bindings and nested let/where-bindings
|
| 704 | 704 | -- Used for a single NonRec or a single Rec
|
| 705 | 705 | -- Adds to the TcBinderStack too
|
| 706 | -tcExtendLetEnv top_lvl _sig_fn (IsGroupClosed group_top fv_env _)
|
|
| 706 | +tcExtendLetEnv top_lvl _sig_fn (IsGroupClosed group_static fv_env _)
|
|
| 707 | 707 | ids thing_inside
|
| 708 | 708 | = tcExtendBinderStack [TcIdBndr id top_lvl | Scaled _ id <- ids] $
|
| 709 | 709 | tc_extend_local_env top_lvl
|
| ... | ... | @@ -713,7 +713,7 @@ tcExtendLetEnv top_lvl _sig_fn (IsGroupClosed group_top fv_env _) |
| 713 | 713 | foldr check_usage thing_inside scaled_names
|
| 714 | 714 | where
|
| 715 | 715 | mk_tct_info id
|
| 716 | - = LetBound { lb_top = group_top
|
|
| 716 | + = LetBound { lb_top = group_static
|
|
| 717 | 717 | , lb_fvs = lookupNameEnv fv_env (idName id) `orElse` emptyNameSet
|
| 718 | 718 | , lb_closed = isTypeClosedLetBndr id }
|
| 719 | 719 |