summaryrefslogtreecommitdiff
path: root/compiler/deSugar/DsExpr.hs
diff options
context:
space:
mode:
authorAdam Sandberg Eriksson <adam@sandbergericsson.se>2015-11-14 22:06:16 +0100
committerBen Gamari <ben@smart-cactus.org>2015-11-14 22:06:29 +0100
commit46a03fbec6a02761db079d1746532565f34c340f (patch)
tree04dfc1739f2e0612b3be99049d6f4202a5e53d0a /compiler/deSugar/DsExpr.hs
parent54884220cd8f68bcb4291cc3689d69258b835f6f (diff)
downloadhaskell-46a03fbec6a02761db079d1746532565f34c340f.tar.gz
Implement the Strict language extension
Add a new language extension `-XStrict` which turns all bindings strict as if the programmer had written a `!` before it. This also upgrades ordinary Haskell to allow recursive and polymorphic strict bindings. See the wiki[1] and the Note [Desugar Strict binds] in DsBinds for specification and implementation details. [1] https://ghc.haskell.org/trac/ghc/wiki/StrictPragma Reviewers: austin, tibbe, simonpj, bgamari Reviewed By: tibbe, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1142 GHC Trac Issues: #8347
Diffstat (limited to 'compiler/deSugar/DsExpr.hs')
-rw-r--r--compiler/deSugar/DsExpr.hs45
1 files changed, 24 insertions, 21 deletions
diff --git a/compiler/deSugar/DsExpr.hs b/compiler/deSugar/DsExpr.hs
index dc6be9cddd..886961c4d0 100644
--- a/compiler/deSugar/DsExpr.hs
+++ b/compiler/deSugar/DsExpr.hs
@@ -109,16 +109,17 @@ ds_val_bind (NonRecursive, hsbinds) body
-- ToDo: in some bizarre case it's conceivable that there
-- could be dict binds in the 'binds'. (See the notes
-- below. Then pattern-match would fail. Urk.)
- strictMatchOnly bind
- = putSrcSpanDs loc (dsStrictBind bind body)
+ unliftedMatchOnly bind
+ = putSrcSpanDs loc (dsUnliftedBind bind body)
-- Ordinary case for bindings; none should be unlifted
ds_val_bind (_is_rec, binds) body
- = do { prs <- dsLHsBinds binds
+ = do { (force_vars,prs) <- dsLHsBinds binds
+ ; let body' = foldr seqVar body force_vars
; ASSERT2( not (any (isUnLiftedType . idType . fst) prs), ppr _is_rec $$ ppr binds )
case prs of
[] -> return body
- _ -> return (Let (Rec prs) body) }
+ _ -> return (Let (Rec prs) body') }
-- Use a Rec regardless of is_rec.
-- Why? Because it allows the binds to be all
-- mixed up, which is what happens in one rare case
@@ -131,29 +132,31 @@ ds_val_bind (_is_rec, binds) body
-- only have to deal with lifted ones now; so Rec is ok
------------------
-dsStrictBind :: HsBind Id -> CoreExpr -> DsM CoreExpr
-dsStrictBind (AbsBinds { abs_tvs = [], abs_ev_vars = []
+dsUnliftedBind :: HsBind Id -> CoreExpr -> DsM CoreExpr
+dsUnliftedBind (AbsBinds { abs_tvs = [], abs_ev_vars = []
, abs_exports = exports
, abs_ev_binds = ev_binds
, abs_binds = lbinds }) body
= do { let body1 = foldr bind_export body exports
bind_export export b = bindNonRec (abe_poly export) (Var (abe_mono export)) b
- ; body2 <- foldlBagM (\body lbind -> dsStrictBind (unLoc lbind) body)
+ ; body2 <- foldlBagM (\body lbind -> dsUnliftedBind (unLoc lbind) body)
body1 lbinds
; ds_binds <- dsTcEvBinds_s ev_binds
; return (mkCoreLets ds_binds body2) }
-dsStrictBind (FunBind { fun_id = L _ fun, fun_matches = matches, fun_co_fn = co_fn
- , fun_tick = tick }) body
- -- Can't be a bang pattern (that looks like a PatBind)
- -- so must be simply unboxed
- = do { (args, rhs) <- matchWrapper (FunRhs (idName fun )) matches
+dsUnliftedBind (FunBind { fun_id = L _ fun
+ , fun_matches = matches
+ , fun_co_fn = co_fn
+ , fun_tick = tick }) body
+ -- Can't be a bang pattern (that looks like a PatBind)
+ -- so must be simply unboxed
+ = do { (args, rhs) <- matchWrapper (FunRhs (idName fun)) matches
; MASSERT( null args ) -- Functions aren't lifted
; MASSERT( isIdHsWrapper co_fn )
; let rhs' = mkOptTickBox tick rhs
; return (bindNonRec fun rhs' body) }
-dsStrictBind (PatBind {pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty }) body
+dsUnliftedBind (PatBind {pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty }) body
= -- let C x# y# = rhs in body
-- ==> case rhs of C x# y# -> body
do { rhs <- dsGuarded grhss ty
@@ -164,19 +167,19 @@ dsStrictBind (PatBind {pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty }) body
; result <- matchEquations PatBindRhs [var] [eqn] (exprType body)
; return (bindNonRec var rhs result) }
-dsStrictBind bind body = pprPanic "dsLet: unlifted" (ppr bind $$ ppr body)
+dsUnliftedBind bind body = pprPanic "dsLet: unlifted" (ppr bind $$ ppr body)
----------------------
-strictMatchOnly :: HsBind Id -> Bool
-strictMatchOnly (AbsBinds { abs_binds = lbinds })
- = anyBag (strictMatchOnly . unLoc) lbinds
-strictMatchOnly (PatBind { pat_lhs = lpat, pat_rhs_ty = rhs_ty })
+unliftedMatchOnly :: HsBind Id -> Bool
+unliftedMatchOnly (AbsBinds { abs_binds = lbinds })
+ = anyBag (unliftedMatchOnly . unLoc) lbinds
+unliftedMatchOnly (PatBind { pat_lhs = lpat, pat_rhs_ty = rhs_ty })
= isUnLiftedType rhs_ty
- || isStrictLPat lpat
+ || isUnliftedLPat lpat
|| any (isUnLiftedType . idType) (collectPatBinders lpat)
-strictMatchOnly (FunBind { fun_id = L _ id })
+unliftedMatchOnly (FunBind { fun_id = L _ id })
= isUnLiftedType (idType id)
-strictMatchOnly _ = False -- I hope! Checked immediately by caller in fact
+unliftedMatchOnly _ = False -- I hope! Checked immediately by caller in fact
{-
************************************************************************