diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2012-05-27 22:31:43 +0100 |
---|---|---|
committer | Manuel M T Chakravarty <chak@cse.unsw.edu.au> | 2012-06-27 14:58:42 +1000 |
commit | aa1e0976055e89ee20cb4c393ee05a33d670bc5d (patch) | |
tree | b25411a4016fdc0c8dbe445a9cbaf9c5f2f05740 /compiler/coreSyn | |
parent | b65562c7000ca745fae7ad1a6fd546951abdd14a (diff) | |
download | haskell-aa1e0976055e89ee20cb4c393ee05a33d670bc5d.tar.gz |
Add silent superclass parameters (again)
Silent superclass parameters solve the problem that
the superclasses of a dicionary construction can easily
turn out to be (wrongly) bottom. The problem and solution
are described in
Note [Silent superclass arguments] in TcInstDcls
I first implemented this fix (with Dimitrios) in Dec 2010, but removed
it again in Jun 2011 becuase we thought it wasn't necessary any
more. (The reason we thought it wasn't necessary is that we'd stopped
generating derived superclass constraints for *wanteds*. But we were
wrong; that didn't solve the superclass-loop problem.)
So we have to re-implement it. It's not hard. Main features:
* The IdDetails for a DFunId says how many silent arguments it has
* A DFunUnfolding describes which dictionary args are
just parameters (DFunLamArg) and which are a function to apply
to the parameters (DFunPolyArg). This adds the DFunArg type
to CoreSyn
* Consequential changes to IfaceSyn. (Binary hi file format changes
slightly.)
* TcInstDcls changes to generate the right dfuns
* CoreSubst.exprIsConApp_maybe handles the new DFunUnfolding
The thing taht is *not* done yet is to alter the vectoriser to
pass the relevant extra argument when building a PA dictionary.
Diffstat (limited to 'compiler/coreSyn')
-rw-r--r-- | compiler/coreSyn/CoreFVs.lhs | 2 | ||||
-rw-r--r-- | compiler/coreSyn/CoreSubst.lhs | 5 | ||||
-rw-r--r-- | compiler/coreSyn/CoreSyn.lhs | 18 | ||||
-rw-r--r-- | compiler/coreSyn/CoreTidy.lhs | 4 | ||||
-rw-r--r-- | compiler/coreSyn/CoreUnfold.lhs | 2 | ||||
-rw-r--r-- | compiler/coreSyn/CoreUtils.lhs | 2 | ||||
-rw-r--r-- | compiler/coreSyn/PprCore.lhs | 4 |
7 files changed, 29 insertions, 8 deletions
diff --git a/compiler/coreSyn/CoreFVs.lhs b/compiler/coreSyn/CoreFVs.lhs index eb3cd5e948..d2bb6ed57a 100644 --- a/compiler/coreSyn/CoreFVs.lhs +++ b/compiler/coreSyn/CoreFVs.lhs @@ -442,7 +442,7 @@ stableUnfoldingVars fv_cand unf = case unf of CoreUnfolding { uf_tmpl = rhs, uf_src = src } | isStableSource src -> Just (exprSomeFreeVars fv_cand rhs) - DFunUnfolding _ _ args -> Just (exprsSomeFreeVars fv_cand args) + DFunUnfolding _ _ args -> Just (exprsSomeFreeVars fv_cand (dfunArgExprs args)) _other -> Nothing \end{code} diff --git a/compiler/coreSyn/CoreSubst.lhs b/compiler/coreSyn/CoreSubst.lhs index 16173fb332..a8de9c2b16 100644 --- a/compiler/coreSyn/CoreSubst.lhs +++ b/compiler/coreSyn/CoreSubst.lhs @@ -658,7 +658,7 @@ substUnfoldingSC subst unf -- Short-cut version substUnfolding subst (DFunUnfolding ar con args) = DFunUnfolding ar con (map subst_arg args) where - subst_arg = substExpr (text "dfun-unf") subst + subst_arg = fmap (substExpr (text "dfun-unf") subst) substUnfolding subst unf@(CoreUnfolding { uf_tmpl = tmpl, uf_src = src }) -- Retain an InlineRule! @@ -1194,7 +1194,8 @@ exprIsConApp_maybe id_unf expr , length args == dfun_nargs -- See Note [DFun arity check] , let (dfun_tvs, _n_theta, _cls, dfun_res_tys) = tcSplitDFunTy (idType fun) subst = zipOpenTvSubst dfun_tvs (stripTypeArgs (takeList dfun_tvs args)) - mk_arg e = mkApps e args + mk_arg (DFunPolyArg e) = mkApps e args + mk_arg (DFunLamArg i) = args !! i = dealWithCoercion co (con, substTys subst dfun_res_tys, map mk_arg ops) -- Look through unfoldings, but only arity-zero one; diff --git a/compiler/coreSyn/CoreSyn.lhs b/compiler/coreSyn/CoreSyn.lhs index e52a6cfe45..a84a29a6c0 100644 --- a/compiler/coreSyn/CoreSyn.lhs +++ b/compiler/coreSyn/CoreSyn.lhs @@ -49,6 +49,7 @@ module CoreSyn ( -- * Unfolding data types Unfolding(..), UnfoldingGuidance(..), UnfoldingSource(..), + DFunArg(..), dfunArgExprs, -- ** Constructing 'Unfolding's noUnfolding, evaldUnfolding, mkOtherCon, @@ -635,7 +636,7 @@ data Unfolding DataCon -- The dictionary data constructor (possibly a newtype datacon) - [CoreExpr] -- Specification of superclasses and methods, in positional order + [DFunArg CoreExpr] -- Specification of superclasses and methods, in positional order | CoreUnfolding { -- An unfolding for an Id with no pragma, -- or perhaps a NOINLINE pragma @@ -673,6 +674,21 @@ data Unfolding -- uf_guidance: Tells us about the /size/ of the unfolding template ------------------------------------------------ +data DFunArg e -- Given (df a b d1 d2 d3) + = DFunPolyArg e -- Arg is (e a b d1 d2 d3) + | DFunLamArg Int -- Arg is one of [a,b,d1,d2,d3], zero indexed + deriving( Functor ) + + -- 'e' is often CoreExpr, which are usually variables, but can + -- be trivial expressions instead (e.g. a type application). + +dfunArgExprs :: [DFunArg e] -> [e] +dfunArgExprs [] = [] +dfunArgExprs (DFunPolyArg e : as) = e : dfunArgExprs as +dfunArgExprs (DFunLamArg {} : as) = dfunArgExprs as + + +------------------------------------------------ data UnfoldingSource = InlineRhs -- The current rhs of the function -- Replace uf_tmpl each time around diff --git a/compiler/coreSyn/CoreTidy.lhs b/compiler/coreSyn/CoreTidy.lhs index 2045538ace..e29c50cc9d 100644 --- a/compiler/coreSyn/CoreTidy.lhs +++ b/compiler/coreSyn/CoreTidy.lhs @@ -205,8 +205,8 @@ tidyIdBndr env@(tidy_env, var_env) id ------------ Unfolding -------------- tidyUnfolding :: TidyEnv -> Unfolding -> Unfolding -> Unfolding -tidyUnfolding tidy_env (DFunUnfolding ar con ids) _ - = DFunUnfolding ar con (map (tidyExpr tidy_env) ids) +tidyUnfolding tidy_env (DFunUnfolding ar con args) _ + = DFunUnfolding ar con (map (fmap (tidyExpr tidy_env)) args) tidyUnfolding tidy_env unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src }) unf_from_rhs diff --git a/compiler/coreSyn/CoreUnfold.lhs b/compiler/coreSyn/CoreUnfold.lhs index 8f62ed439e..816d34e87b 100644 --- a/compiler/coreSyn/CoreUnfold.lhs +++ b/compiler/coreSyn/CoreUnfold.lhs @@ -96,7 +96,7 @@ mkImplicitUnfolding expr = mkTopUnfolding False (simpleOptExpr expr) mkSimpleUnfolding :: CoreExpr -> Unfolding mkSimpleUnfolding = mkUnfolding InlineRhs False False -mkDFunUnfolding :: Type -> [CoreExpr] -> Unfolding +mkDFunUnfolding :: Type -> [DFunArg CoreExpr] -> Unfolding mkDFunUnfolding dfun_ty ops = DFunUnfolding dfun_nargs data_con ops where diff --git a/compiler/coreSyn/CoreUtils.lhs b/compiler/coreSyn/CoreUtils.lhs index c7dc1a6524..17e2966e15 100644 --- a/compiler/coreSyn/CoreUtils.lhs +++ b/compiler/coreSyn/CoreUtils.lhs @@ -928,7 +928,7 @@ expr_ok primop_ok other_expr app_ok :: (PrimOp -> Bool) -> Id -> [Expr b] -> Bool app_ok primop_ok fun args = case idDetails fun of - DFunId new_type -> not new_type + DFunId _ new_type -> not new_type -- DFuns terminate, unless the dict is implemented -- with a newtype in which case they may not diff --git a/compiler/coreSyn/PprCore.lhs b/compiler/coreSyn/PprCore.lhs index 8ac0664b8b..39910c0812 100644 --- a/compiler/coreSyn/PprCore.lhs +++ b/compiler/coreSyn/PprCore.lhs @@ -430,6 +430,10 @@ instance Outputable Unfolding where | otherwise = empty -- Don't print the RHS or we get a quadratic -- blowup in the size of the printout! + +instance Outputable e => Outputable (DFunArg e) where + ppr (DFunPolyArg e) = braces (ppr e) + ppr (DFunLamArg i) = char '<' <> int i <> char '>' \end{code} ----------------------------------------------------- |