summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Lint.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Core/Lint.hs')
-rw-r--r--compiler/GHC/Core/Lint.hs31
1 files changed, 17 insertions, 14 deletions
diff --git a/compiler/GHC/Core/Lint.hs b/compiler/GHC/Core/Lint.hs
index 40de306802..cf6f8292be 100644
--- a/compiler/GHC/Core/Lint.hs
+++ b/compiler/GHC/Core/Lint.hs
@@ -476,14 +476,13 @@ lintCoreBindings dflags pass local_in_scope binds
addLoc TopLevelBindings $
do { checkL (null dups) (dupVars dups)
; checkL (null ext_dups) (dupExtVars ext_dups)
- ; lintRecBindings TopLevel all_pairs $ \_ ->
+ ; lintBindings TopLevel binds $ \_ ->
return () }
where
- all_pairs = flattenBinds binds
-- Put all the top-level binders in scope at the start
-- This is because rewrite rules can bring something
-- into use 'unexpectedly'; see Note [Glomming] in "GHC.Core.Opt.OccurAnal"
- binders = map fst all_pairs
+ binders = bindersOfBinds binds
flags = (defaultLintFlags dflags)
{ lf_check_global_ids = check_globals
@@ -596,19 +595,23 @@ Check a core binding, returning the list of variables bound.
-- Returns a UsageEnv because this function is called in lintCoreExpr for
-- Let
-lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)]
+lintBindings :: TopLevelFlag -> [CoreBind]
-> ([LintedId] -> LintM a) -> LintM (a, [UsageEnv])
-lintRecBindings top_lvl pairs thing_inside
- = lintIdBndrs top_lvl bndrs $ \ bndrs' ->
- do { ues <- zipWithM lint_pair bndrs' rhss
- ; a <- thing_inside bndrs'
- ; return (a, ues) }
+lintBindings top_lvl binds thing_inside = lint_binds [] [] binds
where
- (bndrs, rhss) = unzip pairs
- lint_pair bndr' rhs
+ lint_binds lbndrs ues binds = case binds of
+ [] -> do { a <- thing_inside lbndrs
+ ; return (a, ues) }
+ bind:binds' -> do { let (rec_flag, pairs) = decomposeBind bind
+ ; let (bndrs, rhss) = unzip pairs
+ ; lintIdBndrs top_lvl bndrs $ \lbndrs' -> do
+ do { ues' <- zipWithM (lint_pair rec_flag) lbndrs' rhss
+ ; lint_binds (lbndrs'++lbndrs) (ues'++ues) binds' } }
+ lint_pair :: RecFlag -> LintedId -> CoreExpr -> LintM UsageEnv
+ lint_pair rec_flag bndr' rhs
= addLoc (RhsOf bndr') $
do { (rhs_ty, ue) <- lintRhs bndr' rhs -- Check the rhs
- ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty
+ ; lintLetBind top_lvl rec_flag bndr' rhs rhs_ty
; return ue }
lintLetBody :: [LintedId] -> CoreExpr -> LintM (LintedType, UsageEnv)
@@ -634,7 +637,7 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty
-- See Note [Core let/app invariant] in GHC.Core
; checkL ( isJoinId binder
|| not (isUnliftedType binder_ty)
- || (isNonRec rec_flag && exprOkForSpeculation rhs)
+ || (isNotTopLevel top_lvl && isNonRec rec_flag && exprOkForSpeculation rhs)
|| exprIsTickedString rhs)
(badBndrTyMsg binder (text "unlifted"))
@@ -909,7 +912,7 @@ lintCoreExpr e@(Let (Rec pairs) body)
-- See Note [Multiplicity of let binders] in Var
; ((body_type, body_ue), ues) <-
- lintRecBindings NotTopLevel pairs $ \ bndrs' ->
+ lintBindings NotTopLevel [Rec pairs] $ \ bndrs' ->
lintLetBody bndrs' body
; return (body_type, body_ue `addUE` scaleUE Many (foldr1 addUE ues)) }
where