Commit ac10f840 authored by simonpj@microsoft.com's avatar simonpj@microsoft.com

Simon's big boxy-type commit

This very large commit adds impredicativity to GHC, plus
numerous other small things.
  
*** WARNING: I have compiled all the libraries, and
***	     a stage-2 compiler, and everything seems
***	     fine.  But don't grab this patch if you 
***	     can't tolerate a hiccup if something is
***	     broken.
  
The big picture is this:

a) GHC handles impredicative polymorphism, as described in the
   "Boxy types: type inference for higher-rank types and
   impredicativity" paper

b) GHC handles GADTs in the new simplified (and very sligtly less
   epxrssive) way described in the
   "Simple unification-based type inference for GADTs" paper

  
But there are lots of smaller changes, and since it was pre-Darcs
they are not individually recorded.
  
Some things to watch out for:
  
c)   The story on lexically-scoped type variables has changed, as per
     my email.  I append the story below for completeness, but I 
     am still not happy with it, and it may change again.  In particular,
     the new story does not allow a pattern-bound scoped type variable
     to be wobbly, so (\(x::[a]) -> ...) is usually rejected.  This is
     more restrictive than before, and we might loosen up again.
  
d)   A consequence of adding impredicativity is that GHC is a bit less
     gung ho about converting automatically between
  	(ty1 -> forall a. ty2)    and    (forall a. ty1 -> ty2)
     In particular, you may need to eta-expand some functions to make
     typechecking work again.
   
     Furthermore, functions are now invariant in their argument types,
     rather than being contravariant.  Again, the main consequence is
     that you may occasionally need to eta-expand function arguments when
     using higher-rank polymorphism.
  

Please test, and let me know of any hiccups


Scoped type variables in GHC
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	January 2006

0) Terminology.
   
   A *pattern binding* is of the form
	pat = rhs

   A *function binding* is of the form
	f pat1 .. patn = rhs

   A binding of the formm
	var = rhs
   is treated as a (degenerate) *function binding*.


   A *declaration type signature* is a separate type signature for a
   let-bound or where-bound variable:
	f :: Int -> Int

   A *pattern type signature* is a signature in a pattern: 
	\(x::a) -> x
	f (x::a) = x

   A *result type signature* is a signature on the result of a
   function definition:
	f :: forall a. [a] -> a
	head (x:xs) :: a = x

   The form
	x :: a = rhs
   is treated as a (degnerate) function binding with a result
   type signature, not as a pattern binding.

1) The main invariants:

     A) A lexically-scoped type variable always names a (rigid)
 	type variable (not an arbitrary type).  THIS IS A CHANGE.
        Previously, a scoped type variable named an arbitrary *type*.

     B) A type signature always describes a rigid type (since
	its free (scoped) type variables name rigid type variables).
	This is also a change, a consequence of (A).

     C) Distinct lexically-scoped type variables name distinct
	rigid type variables.  This choice is open; 

2) Scoping

2(a) If a declaration type signature has an explicit forall, those type
   variables are brought into scope in the right hand side of the 
   corresponding binding (plus, for function bindings, the patterns on
   the LHS).  
	f :: forall a. a -> [a]
	f (x::a) = [x :: a, x]
   Both occurences of 'a' in the second line are bound by 
   the 'forall a' in the first line

   A declaration type signature *without* an explicit top-level forall
   is implicitly quantified over all the type variables that are
   mentioned in the type but not already in scope.  GHC's current
   rule is that this implicit quantification does *not* bring into scope
   any new scoped type variables.
	f :: a -> a
	f x = ...('a' is not in scope here)...
   This gives compatibility with Haskell 98

2(b) A pattern type signature implicitly brings into scope any type
   variables mentioned in the type that are not already into scope.
   These are called *pattern-bound type variables*.
	g :: a -> a -> [a]
	g (x::a) (y::a) = [y :: a, x]
   The pattern type signature (x::a) brings 'a' into scope.
   The 'a' in the pattern (y::a) is bound, as is the occurrence on 
   the RHS.  

   A pattern type siganture is the only way you can bring existentials 
   into scope.
	data T where
	  MkT :: forall a. a -> (a->Int) -> T

	f x = case x of
		MkT (x::a) f -> f (x::a)

2a) QUESTION
	class C a where
	  op :: forall b. b->a->a

	instance C (T p q) where
	  op = <rhs>
    Clearly p,q are in scope in <rhs>, but is 'b'?  Not at the moment.
    Nor can you add a type signature for op in the instance decl.
    You'd have to say this:
	instance C (T p q) where
	  op = let op' :: forall b. ...
	           op' = <rhs>
	       in op'

3) A pattern-bound type variable is allowed only if the pattern's
   expected type is rigid.  Otherwise we don't know exactly *which*
   skolem the scoped type variable should be bound to, and that means
   we can't do GADT refinement.  This is invariant (A), and it is a 
   big change from the current situation.

	f (x::a) = x	-- NO; pattern type is wobbly
	
	g1 :: b -> b
	g1 (x::b) = x	-- YES, because the pattern type is rigid

	g2 :: b -> b
	g2 (x::c) = x	-- YES, same reason

	h :: forall b. b -> b
	h (x::b) = x	-- YES, but the inner b is bound

	k :: forall b. b -> b
	k (x::c) = x	-- NO, it can't be both b and c

3a) You cannot give different names for the same type variable in the same scope
    (Invariant (C)):

	f1 :: p -> p -> p		-- NO; because 'a' and 'b' would be
	f1 (x::a) (y::b) = (x::a)	--     bound to the same type variable

	f2 :: p -> p -> p		-- OK; 'a' is bound to the type variable
	f2 (x::a) (y::a) = (x::a)	--     over which f2 is quantified
					-- NB: 'p' is not lexically scoped

	f3 :: forall p. p -> p -> p	-- NO: 'p' is now scoped, and is bound to
	f3 (x::a) (y::a) = (x::a)	--     to the same type varialble as 'a'

	f4 :: forall p. p -> p -> p	-- OK: 'p' is now scoped, and its occurences
	f4 (x::p) (y::p) = (x::p)	--     in the patterns are bound by the forall


3b) You can give a different name to the same type variable in different
    disjoint scopes, just as you can (if you want) give diferent names to 
    the same value parameter

	g :: a -> Bool -> Maybe a
	g (x::p) True  = Just x  :: Maybe p
	g (y::q) False = Nothing :: Maybe q

3c) Scoped type variables respect alpha renaming. For example, 
    function f2 from (3a) above could also be written:
	f2' :: p -> p -> p
	f2' (x::b) (y::b) = x::b
   where the scoped type variable is called 'b' instead of 'a'.


4) Result type signatures obey the same rules as pattern types signatures.
   In particular, they can bind a type variable only if the result type is rigid

	f x :: a = x	-- NO

	g :: b -> b
	g x :: b = x	-- YES; binds b in rhs

5) A *pattern type signature* in a *pattern binding* cannot bind a 
   scoped type variable

	(x::a, y) = ...		-- Legal only if 'a' is already in scope

   Reason: in type checking, the "expected type" of the LHS pattern is
   always wobbly, so we can't bind a rigid type variable.  (The exception
   would be for an existential type variable, but existentials are not
   allowed in pattern bindings either.)
 
   Even this is illegal
	f :: forall a. a -> a
	f x = let ((y::b)::a, z) = ... 
	      in 
   Here it looks as if 'b' might get a rigid binding; but you can't bind
   it to the same skolem as a.

6) Explicitly-forall'd type variables in the *declaration type signature(s)*
   for a *pattern binding* do not scope AT ALL.

	x :: forall a. a->a	  -- NO; the forall a does 
	Just (x::a->a) = Just id  --     not scope at all

	y :: forall a. a->a
	Just y = Just (id :: a->a)  -- NO; same reason

   THIS IS A CHANGE, but one I bet that very few people will notice.
   Here's why:

	strange :: forall b. (b->b,b->b)
	strange = (id,id)

	x1 :: forall a. a->a
	y1 :: forall b. b->b
	(x1,y1) = strange

    This is legal Haskell 98 (modulo the forall). If both 'a' and 'b'
    both scoped over the RHS, they'd get unified and so cannot stand
    for distinct type variables. One could *imagine* allowing this:
   
	x2 :: forall a. a->a
	y2 :: forall a. a->a
	(x2,y2) = strange

    using the very same type variable 'a' in both signatures, so that
    a single 'a' scopes over the RHS.  That seems defensible, but odd,
    because though there are two type signatures, they introduce just
    *one* scoped type variable, a.

7) Possible extension.  We might consider allowing
	\(x :: [ _ ]) -> <expr>
    where "_" is a wild card, to mean "x has type list of something", without
    naming the something.
parent 479cc248
......@@ -36,7 +36,7 @@ module BasicTypes(
TupCon(..), tupleParens,
OccInfo(..), seqOccInfo, isFragileOcc, isOneOcc,
isDeadOcc, isLoopBreaker,
isDeadOcc, isLoopBreaker, isNoOcc,
InsideLam, insideLam, notInsideLam,
OneBranch, oneBranch, notOneBranch,
......@@ -340,6 +340,10 @@ data OccInfo
| IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
-- in a group of recursive definitions
isNoOcc :: OccInfo -> Bool
isNoOcc NoOccInfo = True
isNoOcc other = False
seqOccInfo :: OccInfo -> ()
seqOccInfo occ = occ `seq` ()
......
......@@ -30,7 +30,7 @@ module Id (
isClassOpId_maybe,
isPrimOpId, isPrimOpId_maybe,
isFCallId, isFCallId_maybe,
isDataConWorkId, isDataConWorkId_maybe, idDataCon,
isDataConWorkId, isDataConWorkId_maybe, isDataConId_maybe, idDataCon,
isBottomingId, idIsFrom,
hasNoBinding,
......@@ -264,8 +264,11 @@ isDataConWorkId_maybe id = case globalIdDetails id of
DataConWorkId con -> Just con
other -> Nothing
isDictId :: Id -> Bool
isDictId id = isDictTy (idType id)
isDataConId_maybe :: Id -> Maybe DataCon
isDataConId_maybe id = case globalIdDetails id of
DataConWorkId con -> Just con
DataConWrapId con -> Just con
other -> Nothing
idDataCon :: Id -> DataCon
-- Get from either the worker or the wrapper to the DataCon
......@@ -278,6 +281,9 @@ idDataCon id = case globalIdDetails id of
other -> pprPanic "idDataCon" (ppr id)
isDictId :: Id -> Bool
isDictId id = isDictTy (idType id)
-- hasNoBinding returns True of an Id which may not have a
-- binding, even though it is defined in this module.
-- Data constructor workers used to be things of this kind, but
......
......@@ -35,7 +35,6 @@ module Module
) where
#include "HsVersions.h"
import OccName
import Outputable
import Unique ( Uniquable(..) )
import UniqFM
......
......@@ -18,7 +18,7 @@ module Name (
nameUnique, setNameUnique,
nameOccName, nameModule, nameModule_maybe,
setNameOcc,
tidyNameOcc,
hashName, localiseName,
nameSrcLoc, nameParent, nameParent_maybe, isImplicitName,
......@@ -241,8 +241,12 @@ mkIPName uniq occ
-- one in the thing it's the name of. If you know what I mean.
setNameUnique name uniq = name {n_uniq = uniq}
setNameOcc :: Name -> OccName -> Name
setNameOcc name occ = name {n_occ = occ}
tidyNameOcc :: Name -> OccName -> Name
-- We set the OccName of a Name when tidying
-- In doing so, we change System --> Internal, so that when we print
-- it we don't get the unique by default. It's tidy now!
tidyNameOcc name@(Name { n_sort = System }) occ = name { n_occ = occ, n_sort = Internal}
tidyNameOcc name occ = name { n_occ = occ }
localiseName :: Name -> Name
localiseName n = n { n_sort = Internal }
......
......@@ -381,6 +381,6 @@ instance Functor Located where
fmap f (L l e) = L l (f e)
instance Outputable e => Outputable (Located e) where
ppr (L span e) = ppr e
ppr (L span e) = ppr e
-- do we want to dump the span in debugSty mode?
\end{code}
......@@ -7,7 +7,7 @@
module Var (
Var,
varName, varUnique,
setVarName, setVarUnique, setVarOcc,
setVarName, setVarUnique,
-- TyVars
TyVar, mkTyVar, mkTcTyVar,
......@@ -33,11 +33,11 @@ module Var (
#include "HsVersions.h"
import {-# SOURCE #-} TypeRep( Type )
import {-# SOURCE #-} TcType( TcTyVarDetails )
import {-# SOURCE #-} TcType( TcTyVarDetails, pprTcTyVarDetails )
import {-# SOURCE #-} IdInfo( GlobalIdDetails, notGlobalId, IdInfo, seqIdInfo )
import Name ( Name, OccName, NamedThing(..),
setNameUnique, setNameOcc, nameUnique
import Name ( Name, NamedThing(..),
setNameUnique, nameUnique
)
import Kind ( Kind )
import Unique ( Unique, Uniquable(..), mkUniqueGrimily, getKey# )
......@@ -111,7 +111,13 @@ After CoreTidy, top-level LocalIds are turned into GlobalIds
\begin{code}
instance Outputable Var where
ppr var = ppr (varName var)
ppr var = ppr (varName var) <+> ifPprDebug (brackets extra)
where
extra = case var of
GlobalId {} -> ptext SLIT("gid")
LocalId {} -> ptext SLIT("lid")
TyVar {} -> ptext SLIT("tv")
TcTyVar {tcTyVarDetails = details} -> pprTcTyVarDetails details
instance Show Var where
showsPrec p var = showsPrecSDoc p (ppr var)
......@@ -147,10 +153,6 @@ setVarName :: Var -> Name -> Var
setVarName var new_name
= var { realUnique = getKey# (getUnique new_name),
varName = new_name }
setVarOcc :: Var -> OccName -> Var
setVarOcc var new_occ
= var { varName = setNameOcc (varName var) new_occ }
\end{code}
......
......@@ -15,7 +15,7 @@ module VarEnv (
mapVarEnv, zipVarEnv,
modifyVarEnv, modifyVarEnv_Directly,
isEmptyVarEnv, foldVarEnv,
lookupVarEnv_Directly,
elemVarEnvByKey, lookupVarEnv_Directly,
filterVarEnv_Directly,
-- InScopeSet
......@@ -297,11 +297,13 @@ lookupVarEnv :: VarEnv a -> Var -> Maybe a
lookupVarEnv_NF :: VarEnv a -> Var -> a
lookupWithDefaultVarEnv :: VarEnv a -> a -> Var -> a
elemVarEnv :: Var -> VarEnv a -> Bool
elemVarEnvByKey :: Unique -> VarEnv a -> Bool
foldVarEnv :: (a -> b -> b) -> b -> VarEnv a -> b
\end{code}
\begin{code}
elemVarEnv = elemUFM
elemVarEnvByKey = elemUFM_Directly
extendVarEnv = addToUFM
extendVarEnv_C = addToUFM_C
extendVarEnvList = addListToUFM
......
......@@ -19,19 +19,19 @@ module PprCore (
import CoreSyn
import CostCentre ( pprCostCentreCore )
import Var ( Var )
import Id ( Id, idType, isDataConWorkId_maybe, idLBVarInfo, idArity,
idInfo, idInlinePragma, idOccInfo,
globalIdDetails, isGlobalId, isExportedId,
idNewDemandInfo
import Id ( Id, idType, isDataConWorkId_maybe, idArity,
idInfo, globalIdDetails, isGlobalId, isExportedId
)
import Var ( TyVar, isTyVar, tyVarKind )
import IdInfo ( IdInfo, megaSeqIdInfo,
inlinePragInfo, occInfo, newDemandInfo,
lbvarInfo, hasNoLBVarInfo,
arityInfo, ppArityInfo,
specInfo, pprNewStrictness,
workerInfo, ppWorkerInfo,
newStrictnessInfo, cafInfo, ppCafInfo, specInfoRules
)
import NewDemand ( isTop )
#ifdef OLD_STRICTNESS
import Id ( idDemandInfo )
import IdInfo ( cprInfo, ppCprInfo, strictnessInfo, ppStrictnessInfo )
......@@ -40,7 +40,7 @@ import IdInfo ( cprInfo, ppCprInfo, strictnessInfo, ppStrictnessInfo )
import DataCon ( dataConTyCon )
import TyCon ( tupleTyConBoxity, isTupleTyCon )
import Type ( pprParendType, pprType, pprParendKind )
import BasicTypes ( tupleParens )
import BasicTypes ( tupleParens, isNoOcc, isAlwaysActive )
import Util ( lengthIs )
import Outputable
import FastString ( mkFastString )
......@@ -301,15 +301,28 @@ pprTyVarBndr tyvar
-- pprIdBndr does *not* print the type
-- When printing any Id binder in debug mode, we print its inline pragma and one-shot-ness
pprIdBndr id = ppr id <+>
(megaSeqIdInfo (idInfo id) `seq`
-- Useful for poking on black holes
brackets (ppr (idInlinePragma id) <+> ppr (idOccInfo id) <+>
pprIdBndr id = ppr id <+> pprIdBndrInfo (idInfo id)
pprIdBndrInfo info
= megaSeqIdInfo `seq` doc -- The seq is useful for poking on black holes
where
prag_info = inlinePragInfo info
occ_info = occInfo info
dmd_info = newDemandInfo info
lbv_info = lbvarInfo info
no_info = isAlwaysActive prag_info && isNoOcc occ_info &&
(case dmd_info of { Nothing -> True; Just d -> isTop d }) &&
hasNoLBVarInfo lbv_info
doc | no_info = empty
| otherwise
= brackets $ hcat [ppr prag_info, ppr occ_info,
ppr dmd_info, ppr lbv_info
#ifdef OLD_STRICTNESS
ppr (idDemandInfo id) <+>
, ppr (demandInfo id)
#endif
ppr (idNewDemandInfo id) <+>
ppr (idLBVarInfo id)))
]
\end{code}
......
......@@ -147,7 +147,7 @@ untidy b (L loc p) = L loc (untidy' b p)
untidy' _ (ListPat pats ty) = ListPat (map untidy_no_pars pats) ty
untidy' _ (TuplePat pats boxed) = TuplePat (map untidy_no_pars pats) boxed
untidy' _ (PArrPat _ _) = panic "Check.untidy: Shouldn't get a parallel array here!"
untidy' _ (SigPatIn _ _) = panic "Check.untidy: SigPat"
untidy' _ (SigPatIn _ _) = panic "Check.untidy: SigPat"
untidy_con (PrefixCon pats) = PrefixCon (map untidy_pars pats)
untidy_con (InfixCon p1 p2) = InfixCon (untidy_pars p1) (untidy_pars p2)
......
......@@ -8,7 +8,10 @@ in that the @Rec@/@NonRec@/etc structure is thrown away (whereas at
lower levels it is preserved with @let@/@letrec@s).
\begin{code}
module DsBinds ( dsTopLHsBinds, dsLHsBinds, decomposeRuleLhs, AutoScc(..) ) where
module DsBinds ( dsTopLHsBinds, dsLHsBinds, decomposeRuleLhs,
dsCoercion,
AutoScc(..)
) where
#include "HsVersions.h"
......@@ -84,12 +87,13 @@ dsHsBind auto_scc rest (VarBind var expr)
addDictScc var core_expr `thenDs` \ core_expr' ->
returnDs ((var, core_expr') : rest)
dsHsBind auto_scc rest (FunBind (L _ fun) _ matches _)
dsHsBind auto_scc rest (FunBind { fun_id = L _ fun, fun_matches = matches, fun_co_fn = co_fn })
= matchWrapper (FunRhs (idName fun)) matches `thenDs` \ (args, body) ->
addAutoScc auto_scc (fun, mkLams args body) `thenDs` \ pair ->
dsCoercion co_fn (return (mkLams args body)) `thenDs` \ rhs ->
addAutoScc auto_scc (fun, rhs) `thenDs` \ pair ->
returnDs (pair : rest)
dsHsBind auto_scc rest (PatBind pat grhss ty _)
dsHsBind auto_scc rest (PatBind { pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty })
= dsGuarded grhss ty `thenDs` \ body_expr ->
mkSelectorBinds pat body_expr `thenDs` \ sel_binds ->
mappM (addAutoScc auto_scc) sel_binds `thenDs` \ sel_binds ->
......@@ -384,3 +388,30 @@ addDictScc var rhs = returnDs rhs
returnDs (Note (SCC (mkAllDictsCC mod grp False)) rhs)
-}
\end{code}
%************************************************************************
%* *
Desugaring coercions
%* *
%************************************************************************
\begin{code}
dsCoercion :: ExprCoFn -> DsM CoreExpr -> DsM CoreExpr
dsCoercion CoHole thing_inside = thing_inside
dsCoercion (CoCompose c1 c2) thing_inside = dsCoercion c1 (dsCoercion c2 thing_inside)
dsCoercion (CoLams ids c) thing_inside = do { expr <- dsCoercion c thing_inside
; return (mkLams ids expr) }
dsCoercion (CoTyLams tvs c) thing_inside = do { expr <- dsCoercion c thing_inside
; return (mkLams tvs expr) }
dsCoercion (CoApps c ids) thing_inside = do { expr <- dsCoercion c thing_inside
; return (mkVarApps expr ids) }
dsCoercion (CoTyApps c tys) thing_inside = do { expr <- dsCoercion c thing_inside
; return (mkTyApps expr tys) }
dsCoercion (CoLet bs c) thing_inside = do { prs <- dsLHsBinds bs
; expr <- dsCoercion c thing_inside
; return (Let (Rec prs) expr) }
\end{code}
......@@ -11,7 +11,7 @@ module DsExpr ( dsExpr, dsLExpr, dsLocalBinds, dsValBinds, dsLit ) where
import Match ( matchWrapper, matchSimply, matchSinglePat )
import MatchLit ( dsLit, dsOverLit )
import DsBinds ( dsLHsBinds )
import DsBinds ( dsLHsBinds, dsCoercion )
import DsGRHSs ( dsGuarded )
import DsListComp ( dsListComp, dsPArrComp )
import DsUtils ( mkErrorAppDs, mkStringExpr, mkConsExpr, mkNilExpr,
......@@ -121,13 +121,14 @@ ds_val_bind (is_rec, hsbinds) body
(showSDoc (ppr pat))
in
case bagToList binds of
[L loc (FunBind (L _ fun) _ matches _)]
[L loc (FunBind { fun_id = L _ fun, fun_matches = matches, fun_co_fn = co_fn })]
-> putSrcSpanDs loc $
matchWrapper (FunRhs (idName fun)) matches `thenDs` \ (args, rhs) ->
ASSERT( null args ) -- Functions aren't lifted
ASSERT( isIdCoercion co_fn )
returnDs (bindNonRec fun rhs body_w_exports)
[L loc (PatBind pat grhss ty _)]
[L loc (PatBind {pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty })]
-> putSrcSpanDs loc $
dsGuarded grhss ty `thenDs` \ rhs ->
mk_error_app pat `thenDs` \ error_expr ->
......@@ -563,6 +564,8 @@ dsExpr (DictLam dictvars expr)
dsExpr (DictApp expr dicts) -- becomes a curried application
= dsLExpr expr `thenDs` \ core_expr ->
returnDs (foldl (\f d -> f `App` (Var d)) core_expr dicts)
dsExpr (HsCoerce co_fn e) = dsCoercion co_fn (dsExpr e)
\end{code}
Here is where we desugar the Template Haskell brackets and escapes
......
......@@ -43,7 +43,7 @@ import OccName ( mkOccNameFS )
import Name ( Name, mkExternalName, localiseName, nameOccName, nameModule,
isExternalName, getSrcLoc )
import NameEnv
import Type ( Type, mkGenTyConApp )
import Type ( Type, mkTyConApp )
import TcType ( tcTyConAppArgs )
import TyCon ( tyConName )
import TysWiredIn ( parrTyCon )
......@@ -715,7 +715,8 @@ rep_bind :: LHsBind Name -> DsM (SrcSpan, Core TH.DecQ)
-- Note GHC treats declarations of a variable (not a pattern)
-- e.g. x = g 5 as a Fun MonoBinds. This is indicated by a single match
-- with an empty list of patterns
rep_bind (L loc (FunBind fn infx (MatchGroup [L _ (Match [] ty (GRHSs guards wheres))] _) _))
rep_bind (L loc (FunBind { fun_id = fn,
fun_matches = MatchGroup [L _ (Match [] ty (GRHSs guards wheres))] _ }))
= do { (ss,wherecore) <- repBinds wheres
; guardcore <- addBinds ss (repGuards guards)
; fn' <- lookupLBinder fn
......@@ -724,13 +725,13 @@ rep_bind (L loc (FunBind fn infx (MatchGroup [L _ (Match [] ty (GRHSs guards whe
; ans' <- wrapGenSyns ss ans
; return (loc, ans') }
rep_bind (L loc (FunBind fn infx (MatchGroup ms _) _))
rep_bind (L loc (FunBind { fun_id = fn, fun_matches = MatchGroup ms _ }))
= do { ms1 <- mapM repClauseTup ms
; fn' <- lookupLBinder fn
; ans <- repFun fn' (nonEmptyCoreList ms1)
; return (loc, ans) }
rep_bind (L loc (PatBind pat (GRHSs guards wheres) ty2 _))
rep_bind (L loc (PatBind { pat_lhs = pat, pat_rhs = GRHSs guards wheres }))
= do { patcore <- repLP pat
; (ss,wherecore) <- repBinds wheres
; guardcore <- addBinds ss (repGuards guards)
......@@ -738,7 +739,7 @@ rep_bind (L loc (PatBind pat (GRHSs guards wheres) ty2 _))
; ans' <- wrapGenSyns ss ans
; return (loc, ans') }
rep_bind (L loc (VarBind v e))
rep_bind (L loc (VarBind { var_id = v, var_rhs = e}))
= do { v' <- lookupBinder v
; e2 <- repLE e
; x <- repNormal e2
......@@ -921,7 +922,7 @@ globalVar name
lookupType :: Name -- Name of type constructor (e.g. TH.ExpQ)
-> DsM Type -- The type
lookupType tc_name = do { tc <- dsLookupTyCon tc_name ;
return (mkGenTyConApp tc []) }
return (mkTyConApp tc []) }
wrapGenSyns :: [GenSymBind]
-> Core (TH.Q a) -> DsM (Core (TH.Q a))
......
......@@ -9,7 +9,7 @@ This module exports some utility functions of no great interest.
module DsUtils (
EquationInfo(..),
firstPat, shiftEqns,
mkDsLet, mkDsLets,
MatchResult(..), CanItFail(..),
......@@ -70,11 +70,14 @@ import PrelNames ( unpackCStringName, unpackCStringUtf8Name,
lengthPName, indexPName )
import Outputable
import SrcLoc ( Located(..), unLoc )
import Util ( isSingleton, notNull, zipEqual, sortWith )
import Util ( isSingleton, zipEqual, sortWith )
import ListSetOps ( assocDefault )
import FastString
import Data.Char ( ord )
#ifdef DEBUG
import Util ( notNull ) -- Used in an assertion
#endif
\end{code}
......
......@@ -292,24 +292,24 @@ cvtBind :: TH.Dec -> CvtM (LHsBind RdrName)
cvtBind (TH.ValD (TH.VarP s) body ds)
= do { s' <- vNameL s
; cl' <- cvtClause (Clause [] body ds)
; returnL $ FunBind s' False (mkMatchGroup [cl']) placeHolderNames }
; returnL $ mkFunBind s' [cl'] }
cvtBind (TH.FunD nm cls)
= do { nm' <- vNameL nm
; cls' <- mapM cvtClause cls
; returnL $ FunBind nm' False (mkMatchGroup cls') placeHolderNames }
; returnL $ mkFunBind nm' cls' }
cvtBind (TH.ValD p body ds)
= do { p' <- cvtPat p
; g' <- cvtGuard body
; ds' <- cvtDecs ds
; returnL $ PatBind p' (GRHSs g' ds') void placeHolderNames }
; returnL $ PatBind { pat_lhs = p', pat_rhs = GRHSs g' ds',
pat_rhs_ty = void, bind_fvs = placeHolderNames } }
cvtBind d
= failWith (sep [ptext SLIT("Illegal kind of declaration in where clause"),
nest 2 (text (TH.pprint d))])
cvtClause :: TH.Clause -> CvtM (Hs.LMatch RdrName)
cvtClause (Clause ps body wheres)
= do { ps' <- cvtPats ps
......
......@@ -16,6 +16,7 @@ import {-# SOURCE #-} HsExpr ( HsExpr, pprExpr, LHsExpr,
import {-# SOURCE #-} HsPat ( LPat )
import HsTypes ( LHsType, PostTcType )
import Type ( Type )
import Name ( Name )
import NameSet ( NameSet, elemNameSet )
import BasicTypes ( IPName, RecFlag(..), InlineSpec(..), Fixity )
......@@ -55,41 +56,61 @@ type DictBinds id = LHsBinds id -- Used for dictionary or method bindings
type LHsBind id = Located (HsBind id)
data HsBind id
= FunBind (Located id)
-- Used for both functions f x = e
-- and variables f = \x -> e
-- Reason: the Match stuff lets us have an optional
-- result type sig f :: a->a = ...mentions a...
--
-- This also means that instance decls can only have
-- FunBinds, so if you change this, you'll need to
-- change e.g. rnMethodBinds
Bool -- True => infix declaration
(MatchGroup id)
NameSet -- After the renamer, this contains a superset of the
= FunBind { -- FunBind is used for both functions f x = e
-- and variables f = \x -> e
-- Reason: the Match stuff lets us have an optional
-- result type sig f :: a->a = ...mentions a...
--
-- This also means that instance decls can only have
-- FunBinds, so if you change this, you'll need to
-- change e.g. rnMethodBinds
fun_id :: Located id,
fun_infix :: Bool, -- True => infix declaration
fun_matches :: MatchGroup id, -- The payload
fun_co_fn :: ExprCoFn, -- Coercion from the type of the MatchGroup to the type of
-- the Id. Example:
-- f :: Int -> forall a. a -> a
-- f x y = y
-- Then the MatchGroup will have type (Int -> a' -> a')
-- (with a free type variable a'). The coercion will take
-- a CoreExpr of this type and convert it to a CoreExpr of
-- type Int -> forall a'. a' -> a'
-- Notice that the coercion captures the free a'. That's
-- why coercions are (CoreExpr -> CoreExpr), rather than
-- just CoreExpr (with a functional type)
bind_fvs :: NameSet -- After the renamer, this contains a superset of the
-- Names of the other binders in this binding group that
-- are free in the RHS of the defn
-- Before renaming, and after typechecking,
-- the field is unused; it's just an error thunk
| PatBind (LPat id) -- The pattern is never a simple variable;
-- That case is done by FunBind
(GRHSs id)
PostTcType -- Type of the GRHSs
NameSet -- Same as for FunBind
| VarBind id (Located (HsExpr id)) -- Dictionary binding and suchlike
-- All VarBinds are introduced by the type checker
-- Located only for consistency
| AbsBinds -- Binds abstraction; TRANSLATION
[TyVar] -- Type variables
[DictId] -- Dicts
[([TyVar], id, id, [Prag])] -- (tvs, poly_id, mono_id, prags)
(LHsBinds id) -- The dictionary bindings and typechecked user bindings
}
| PatBind { -- The pattern is never a simple variable;
-- That case is done by FunBind
pat_lhs :: LPat id,
pat_rhs :: GRHSs id,
pat_rhs_ty :: PostTcType, -- Type of the GRHSs
bind_fvs :: NameSet -- Same as for FunBind
}
| VarBind { -- Dictionary binding and suchlike
var_id :: id, -- All VarBinds are introduced by the type checker
var_rhs :: LHsExpr id -- Located only for consistency
}
| AbsBinds { -- Binds abstraction; TRANSLATION
abs_tvs :: [TyVar],
abs_dicts :: [DictId],
abs_exports :: [([TyVar], id, id, [Prag])], -- (tvs, poly_id, mono_id, prags)
abs_binds :: LHsBinds id -- The dictionary bindings and typechecked user bindings
-- mixed up together; you can tell the dict bindings because
-- they are all VarBinds
}
-- Consider (AbsBinds tvs ds [(ftvs, poly_f, mono_f) binds]
--
-- Creates bindings for (polymorphic, overloaded) poly_f
......@@ -209,12 +230,13 @@ instance OutputableBndr id => Outputable (HsBind id) where
ppr_monobind :: OutputableBndr id => HsBind id -> SDoc
ppr_monobind (PatBind pat grhss _ _) = pprPatBind pat grhss
ppr_monobind (VarBind var rhs) = ppr var <+> equals <+> pprExpr (unLoc rhs)
ppr_monobind (FunBind fun inf matches _) = pprFunBind (unLoc fun) matches
ppr_monobind (PatBind { pat_lhs = pat, pat_rhs = grhss }) = pprPatBind pat grhss
ppr_monobind (VarBind { var_id = var, var_rhs = rhs }) = ppr var <+> equals <+> pprExpr (unLoc rhs)
ppr_monobind (FunBind { fun_id = fun, fun_matches = matches }) = pprFunBind (unLoc fun) matches
-- ToDo: print infix if appropriate
ppr_monobind (AbsBinds tyvars dictvars exports val_binds)
ppr_monobind (AbsBinds { abs_tvs = tyvars, abs_dicts = dictvars,
abs_exports = exports, abs_binds = val_binds })
= sep [ptext SLIT("AbsBinds"),
brackets (interpp'SP tyvars),
brackets (interpp'SP dictvars),
......@@ -262,6 +284,37 @@ instance (OutputableBndr id) => Outputable (IPBind id) where
\end{code}
%************************************************************************
%* *
\subsection{Coercion functions}
%* *
%************************************************************************
\begin{code}
-- A Coercion is an expression with a hole in it
-- We need coercions to have concrete form so that we can zonk them
data ExprCoFn
= CoHole -- The identity coercion
| CoCompose ExprCoFn ExprCoFn
| CoApps ExprCoFn [Id] -- Non-empty list
| CoTyApps ExprCoFn [Type] -- in all of these
| CoLams [Id] ExprCoFn -- so that the identity coercion
| CoTyLams [TyVar] ExprCoFn -- is just Hole
| CoLet (LHsBinds Id) ExprCoFn -- Would be nicer to be core bindings
(<.>) :: ExprCoFn -> ExprCoFn -> ExprCoFn
(<.>) = CoCompose
idCoercion :: ExprCoFn
idCoercion = CoHole
isIdCoercion :: ExprCoFn -> Bool
isIdCoercion CoHole = True
isIdCoercion other = False
\end{code}
%************************************************************************
%* *
\subsection{@Sig@: type signatures and value-modifying user pragmas}
......@@ -350,31 +403,36 @@ sigName (L _ sig) = f sig
f other = Nothing
isFixityLSig :: LSig name -> Bool
isFixityLSig (L _ (FixSig _)) = True
isFixityLSig _ = False
isFixityLSig (L _ (FixSig {})) = True
isFixityLSig _ = False
isVanillaLSig :: LSig name -> Bool
isVanillaLSig (L _(TypeSig name _)) = True
isVanillaLSig sig = False
isVanillaLSig (L _(TypeSig {})) = True
isVanillaLSig sig = False
isSpecLSig :: LSig name -> Bool
isSpecLSig (L _(SpecSig name _ _)) = True
isSpecLSig sig = False
isSpecLSig (L _(SpecSig {})) = True
isSpecLSig sig = False
isSpecInstLSig (L _ (SpecInstSig _)) = True
isSpecInstLSig sig = False
isSpecInstLSig (L _ (SpecInstSig {})) = True
isSpecInstLSig sig = False
isPragLSig :: LSig name -> Bool
-- Identifies pragmas
isPragLSig (L _ (SpecSig _ _ _)) = True
isPragLSig (L _ (InlineSig _ _)) = True
isPragLSig other = False
hsSigDoc (TypeSig _ _) = ptext SLIT("type signature")
hsSigDoc (SpecSig _ _ _) = ptext SLIT("SPECIALISE pragma")
hsSigDoc (InlineSig _ spec) = ppr spec <+> ptext SLIT("pragma")
hsSigDoc (SpecInstSig _) = ptext SLIT("SPECIALISE instance pragma")
hsSigDoc (FixSig (FixitySig _ _)) = ptext SLIT("fixity declaration")
isPragLSig (L _ (SpecSig {})) = True