summaryrefslogtreecommitdiff
path: root/compiler/basicTypes
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-11-07 17:24:47 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-11-19 11:53:55 -0500
commit08d595c026f0774c51d85cbd790518055970ff2d (patch)
tree706d776534998f69ed8cb62e3befa471bf4fdfdd /compiler/basicTypes
parenta8adb5b4d782b6166160a80adbf6c59452dc964d (diff)
downloadhaskell-08d595c026f0774c51d85cbd790518055970ff2d.tar.gz
Give seq a more precise type and remove magic
`GHC.Prim.seq` previously had the rather plain type: seq :: forall a b. a -> b -> b However, it also had a special typing rule to applications where `b` is not of kind `Type`. Issue #17440 noted that levity polymorphism allows us to rather give it the more precise type: seq :: forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b This allows us to remove the special typing rule that we previously required to allow applications on unlifted arguments. T9404 contains a non-Type application of `seq` which should verify that this works as expected. Closes #17440.
Diffstat (limited to 'compiler/basicTypes')
-rw-r--r--compiler/basicTypes/MkId.hs39
1 files changed, 23 insertions, 16 deletions
diff --git a/compiler/basicTypes/MkId.hs b/compiler/basicTypes/MkId.hs
index d9d23b1235..593f9ac3a9 100644
--- a/compiler/basicTypes/MkId.hs
+++ b/compiler/basicTypes/MkId.hs
@@ -1392,7 +1392,6 @@ seqId = pcMiscPrelId seqName ty info
where
info = noCafIdInfo `setInlinePragInfo` inline_prag
`setUnfoldingInfo` mkCompulsoryUnfolding rhs
- `setNeverLevPoly` ty
inline_prag
= alwaysInlinePragma `setInlinePragmaActivation` ActiveAfter
@@ -1402,11 +1401,15 @@ seqId = pcMiscPrelId seqName ty info
-- LHS of rules. That way we can have rules for 'seq';
-- see Note [seqId magic]
- ty = mkSpecForAllTys [alphaTyVar,betaTyVar]
- (mkVisFunTy alphaTy (mkVisFunTy betaTy betaTy))
+ -- seq :: forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b
+ ty =
+ mkInvForAllTy runtimeRep2TyVar
+ $ mkSpecForAllTys [alphaTyVar, openBetaTyVar]
+ $ mkVisFunTy alphaTy (mkVisFunTy openBetaTy openBetaTy)
- [x,y] = mkTemplateLocals [alphaTy, betaTy]
- rhs = mkLams [alphaTyVar,betaTyVar,x,y] (Case (Var x) x betaTy [(DEFAULT, [], Var y)])
+ [x,y] = mkTemplateLocals [alphaTy, openBetaTy]
+ rhs = mkLams ([runtimeRep2TyVar, alphaTyVar, openBetaTyVar, x, y]) $
+ Case (Var x) x openBetaTy [(DEFAULT, [], Var y)]
------------------------------------------------
lazyId :: Id -- See Note [lazyId magic]
@@ -1492,19 +1495,20 @@ Note [seqId magic]
~~~~~~~~~~~~~~~~~~
'GHC.Prim.seq' is special in several ways.
-a) In source Haskell its second arg can have an unboxed type
- x `seq` (v +# w)
- But see Note [Typing rule for seq] in TcExpr, which
- explains why we give seq itself an ordinary type
- seq :: forall a b. a -> b -> b
- and treat it as a language construct from a typing point of view.
+a) Its fixity is set in LoadIface.ghcPrimIface
-b) Its fixity is set in LoadIface.ghcPrimIface
-
-c) It has quite a bit of desugaring magic.
+b) It has quite a bit of desugaring magic.
See DsUtils.hs Note [Desugaring seq (1)] and (2) and (3)
-d) There is some special rule handing: Note [User-defined RULES for seq]
+c) There is some special rule handing: Note [User-defined RULES for seq]
+
+Historical note:
+ In TcExpr we used to need a special typing rule for 'seq', to handle calls
+ whose second argument had an unboxed type, e.g. x `seq` 3#
+
+ However, with levity polymorphism we can now give seq the type seq ::
+ forall (r :: RuntimeRep) a (b :: TYPE r). a -> b -> b which handles this
+ case without special treatment in the typechecker.
Note [User-defined RULES for seq]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1530,13 +1534,16 @@ If we wrote
RULE "f/seq" forall n e. seq (f n) e = seq n e
with rule arity 2, then two bad things would happen:
- - The magical desugaring done in Note [seqId magic] item (c)
+ - The magical desugaring done in Note [seqId magic] item (b)
for saturated application of 'seq' would turn the LHS into
a case expression!
- The code in Simplify.rebuildCase would need to actually supply
the value argument, which turns out to be awkward.
+See also: Note [User-defined RULES for seq] in Simplify.
+
+
Note [lazyId magic]
~~~~~~~~~~~~~~~~~~~
lazy :: forall a?. a? -> a? (i.e. works for unboxed types too)