Fix recursive superclasses (again). Fixes Trac #4809.
[ghc-hetmet.git] / compiler / basicTypes / MkId.lhs
index 774c919..4bfb53b 100644 (file)
@@ -13,8 +13,7 @@ have a standard form, namely:
 
 \begin{code}
 module MkId (
-        mkDictFunId, mkDefaultMethodId,
-        mkDictSelId, 
+        mkDictFunId, mkDictFunTy, mkDefaultMethodId, mkDictSelId,
 
         mkDataConIds,
         mkPrimOpId, mkFCallId, mkTickBoxOpId, mkBreakPointOpId,
@@ -300,6 +299,7 @@ mkDataConIds wrap_name wkr_name data_con
                     `setArityInfo`         wrap_arity
                         -- It's important to specify the arity, so that partial
                         -- applications are treated as values
+                   `setInlinePragInfo`    alwaysInlinePragma
                     `setUnfoldingInfo`     wrap_unf
                     `setStrictnessInfo` Just wrap_sig
 
@@ -317,7 +317,7 @@ mkDataConIds wrap_name wkr_name data_con
         --      ...(let w = C x in ...(w p q)...)...
         -- we want to see that w is strict in its two arguments
 
-    wrap_unf = mkInlineRule wrap_rhs (Just (length dict_args + length id_args))
+    wrap_unf = mkInlineUnfolding (Just (length dict_args + length id_args)) wrap_rhs
     wrap_rhs = mkLams wrap_tvs $ 
                mkLams eq_args $
                mkLams dict_args $ mkLams id_args $
@@ -491,15 +491,11 @@ mkDictSelId no_unf name clas
 
 dictSelRule :: Int -> Arity -> Arity 
             -> IdUnfoldingFun -> [CoreExpr] -> Maybe CoreExpr
--- Oh, very clever
---       sel_i t1..tk (df s1..sn d1..dm) = op_i_helper s1..sn d1..dm
+-- Tries to persuade the argument to look like a constructor
+-- application, using exprIsConApp_maybe, and then selects
+-- from it
 --       sel_i t1..tk (D t1..tk op1 ... opm) = opi
 --
--- NB: the data constructor has the same number of type and 
---     coercion args as the selector
---
--- This only works for *value* superclasses
--- There are no selector functions for equality superclasses
 dictSelRule val_index n_ty_args n_eq_args id_unf args
   | (dict_arg : _) <- drop n_ty_args args
   , Just (_, _, con_args) <- exprIsConApp_maybe id_unf dict_arg
@@ -838,12 +834,29 @@ mkDictFunId :: Name      -- Name to use for the dict fun;
             -> Class 
             -> [Type]
             -> Id
+-- Implements the DFun Superclass Invariant (see TcInstDcls)
 
-mkDictFunId dfun_name inst_tyvars dfun_theta clas inst_tys
-  = mkExportedLocalVar (DFunId is_nt) dfun_name dfun_ty vanillaIdInfo
+mkDictFunId dfun_name tvs theta clas tys
+  = mkExportedLocalVar (DFunId n_silent is_nt)
+                       dfun_name
+                       dfun_ty
+                       vanillaIdInfo
   where
     is_nt = isNewTyCon (classTyCon clas)
-    dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
+    (n_silent, dfun_ty) = mkDictFunTy tvs theta clas tys
+
+mkDictFunTy :: [TyVar] -> ThetaType -> Class -> [Type] -> (Int, Type)
+mkDictFunTy tvs theta clas tys
+  = (length silent_theta, dfun_ty)
+  where
+    dfun_ty = mkSigmaTy tvs (silent_theta ++ theta) (mkDictTy clas tys)
+    silent_theta = filterOut discard $
+                   substTheta (zipTopTvSubst (classTyVars clas) tys)
+                              (classSCTheta clas)
+                   -- See Note [Silent Superclass Arguments]
+    discard pred = isEmptyVarSet (tyVarsOfPred pred)
+                 || any (`tcEqPred` pred) theta
+                 -- See the DFun Superclass Invariant in TcInstDcls
 \end{code}