diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2016-05-26 14:20:29 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2016-05-26 14:20:29 +0100 |
commit | 0f1e315b9274725c4a2c975f4d06a5c956cf5385 (patch) | |
tree | 16f58f5a0814c01349ebd49ead4e13c13aafd959 /compiler/ghci | |
parent | 5020bc8fd2a99a557f45ea5abf8240ac995cc03d (diff) | |
download | haskell-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.hs | 37 |
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 |