summaryrefslogtreecommitdiff
path: root/compiler/ghci
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2016-05-26 14:20:29 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2016-05-26 14:20:29 +0100
commit0f1e315b9274725c4a2c975f4d06a5c956cf5385 (patch)
tree16f58f5a0814c01349ebd49ead4e13c13aafd959 /compiler/ghci
parent5020bc8fd2a99a557f45ea5abf8240ac995cc03d (diff)
downloadhaskell-0f1e315b9274725c4a2c975f4d06a5c956cf5385.tar.gz
Fix bytecode gen to deal with rep-polymorphism
When faced runtime-rep-polymorphic code from a pattern-synonym matcher, the bytecode generator was treating the result as lifted, which it isn't. The fix is just to treat those rep-polymorphic continuations like unlifted types, and add a dummy arg. Trac #12007 is a case in point.
Diffstat (limited to 'compiler/ghci')
-rw-r--r--compiler/ghci/ByteCodeGen.hs37
1 files changed, 25 insertions, 12 deletions
diff --git a/compiler/ghci/ByteCodeGen.hs b/compiler/ghci/ByteCodeGen.hs
index f1d0670b19..e752fc28bc 100644
--- a/compiler/ghci/ByteCodeGen.hs
+++ b/compiler/ghci/ByteCodeGen.hs
@@ -31,6 +31,7 @@ import Literal
import PrimOp
import CoreFVs
import Type
+import Kind ( isLiftedTypeKind )
import DataCon
import TyCon
import Util
@@ -482,35 +483,47 @@ schemeE d s p (AnnLet binds (_,body)) = do
thunk_codes <- sequence compile_binds
return (alloc_code `appOL` concatOL thunk_codes `appOL` body_code)
--- introduce a let binding for a ticked case expression. This rule
+-- Introduce a let binding for a ticked case expression. This rule
-- *should* only fire when the expression was not already let-bound
-- (the code gen for let bindings should take care of that). Todo: we
-- call exprFreeVars on a deAnnotated expression, this may not be the
-- best way to calculate the free vars but it seemed like the least
-- intrusive thing to do
schemeE d s p exp@(AnnTick (Breakpoint _id _fvs) _rhs)
- = if isUnliftedType ty
- then do
- -- If the result type is unlifted, then we must generate
+ | isLiftedTypeKind (typeKind ty)
+ = do id <- newId ty
+ -- Todo: is emptyVarSet correct on the next line?
+ let letExp = AnnLet (AnnNonRec id (fvs, exp)) (emptyDVarSet, AnnVar id)
+ schemeE d s p letExp
+
+ | otherwise
+ = do -- If the result type is not definitely lifted, then we must generate
-- let f = \s . tick<n> e
-- in f realWorld#
-- When we stop at the breakpoint, _result will have an unlifted
-- type and hence won't be bound in the environment, but the
-- breakpoint will otherwise work fine.
+ --
+ -- NB (Trac #12007) this /also/ applies for if (ty :: TYPE r), where
+ -- r :: RuntimeRep is a variable. This can happen in the
+ -- continuations for a pattern-synonym matcher
+ -- match = /\(r::RuntimeRep) /\(a::TYPE r).
+ -- \(k :: Int -> a) \(v::T).
+ -- case v of MkV n -> k n
+ -- Here (k n) :: a :: Type r, so we don't know if it's lifted
+ -- or not; but that should be fine provided we add that void arg.
+
id <- newId (mkFunTy realWorldStatePrimTy ty)
st <- newId realWorldStatePrimTy
let letExp = AnnLet (AnnNonRec id (fvs, AnnLam st (emptyDVarSet, exp)))
(emptyDVarSet, (AnnApp (emptyDVarSet, AnnVar id)
(emptyDVarSet, AnnVar realWorldPrimId)))
schemeE d s p letExp
- else do
- id <- newId ty
- -- Todo: is emptyVarSet correct on the next line?
- let letExp = AnnLet (AnnNonRec id (fvs, exp)) (emptyDVarSet, AnnVar id)
- schemeE d s p letExp
- where exp' = deAnnotate' exp
- fvs = exprFreeVarsDSet exp'
- ty = exprType exp'
+
+ where
+ exp' = deAnnotate' exp
+ fvs = exprFreeVarsDSet exp'
+ ty = exprType exp'
-- ignore other kinds of tick
schemeE d s p (AnnTick _ (_, rhs)) = schemeE d s p rhs