Fix scoped type variables for expression type signatures
[ghc-hetmet.git] / compiler / simplCore / SimplUtils.lhs
index 4b6c4a3..b9e98f7 100644 (file)
@@ -51,9 +51,8 @@ import Type           ( Type, splitFunTys, dropForAlls, isStrictType,
 import Coercion         ( isEqPredTy
                        )
 import Coercion         ( Coercion, mkUnsafeCoercion, coercionKind )
-import TyCon           ( tyConDataCons_maybe, isNewTyCon )
-import DataCon         ( DataCon, dataConRepArity, dataConExTyVars, 
-                          dataConInstArgTys, dataConTyCon )
+import TyCon           ( tyConDataCons_maybe, isClosedNewTyCon )
+import DataCon         ( DataCon, dataConRepArity, dataConInstArgTys, dataConTyCon )
 import VarSet
 import BasicTypes      ( TopLevelFlag(..), isNotTopLevel, OccInfo(..), isLoopBreaker, isOneOcc,
                          Activation, isAlwaysActive, isActive )
@@ -246,7 +245,9 @@ getContArgs chkr fun orig_cont
        where
          args = reverse acc
          hole_ty = applyTypeToArgs (Var fun) (idType fun)
-                                   [substExpr se arg | (arg,se,_) <- args]
+                                   [substExpr_mb se arg | (arg,se,_) <- args]
+          substExpr_mb Nothing   arg = arg
+         substExpr_mb (Just se) arg = substExpr se arg
     
     ----------------------------
     vanilla_stricts, computed_stricts :: [Bool]
@@ -1137,27 +1138,6 @@ tryRhsTyLam env tyvars body              -- Only does something if there's a let
 %*                                                                     *
 %************************************************************************
 
-\begin{code}
-mkDataConAlt :: DataCon -> [OutType] -> InExpr -> SimplM InAlt
--- Make a data-constructor alternative to replace the DEFAULT case
--- NB: there's something a bit bogus here, because we put OutTypes into an InAlt
-mkDataConAlt con inst_tys rhs
-  = do         { tv_uniqs <- getUniquesSmpl 
-       ; arg_uniqs <- getUniquesSmpl
-       ; let tv_bndrs  = zipWith mk_tv_bndr (dataConExTyVars con) tv_uniqs
-             arg_tys   = dataConInstArgTys con (inst_tys ++ mkTyVarTys tv_bndrs)
-             arg_bndrs = zipWith mk_arg arg_tys arg_uniqs
-       ; return (DataAlt con, tv_bndrs ++ arg_bndrs, rhs) }
-  where
-    mk_arg arg_ty uniq -- Equality predicates get a TyVar
-                       -- while dictionaries and others get an Id
-      | isEqPredTy arg_ty = mk_tv arg_ty uniq
-      | otherwise        = mk_id arg_ty uniq
-
-    mk_tv_bndr tv uniq = mk_tv (tyVarKind tv) uniq
-    mk_tv kind uniq = mkTyVar (mkSysTvName uniq FSLIT("t")) kind
-    mk_id ty   uniq = mkSysLocal FSLIT("a") uniq ty
-\end{code}
 
 mkCase puts a case expression back together, trying various transformations first.
 
@@ -1481,36 +1461,31 @@ mkCase1 scrut case_bndr ty [(con,bndrs,rhs)]
 mkCase1 scrut case_bndr ty alts        -- Identity case
   | all identity_alt alts
   = tick (CaseIdentity case_bndr)              `thenSmpl_`
-    returnSmpl (re_note scrut)
+    returnSmpl (re_cast scrut)
   where
-    identity_alt (con, args, rhs) = de_note rhs `cheapEqExpr` identity_rhs con args
+    identity_alt (con, args, rhs) = de_cast rhs `cheapEqExpr` mk_id_rhs con args
 
-    identity_rhs (DataAlt con) args
-      | isNewTyCon (dataConTyCon con) 
-      = wrapNewTypeBody (dataConTyCon con) arg_tys (varToCoreExpr $ head args)
-      | otherwise
-      = pprTrace "mkCase1" (ppr con) $ mkConApp con (arg_ty_exprs ++ varsToCoreExprs args)
-    identity_rhs (LitAlt lit)  _    = Lit lit
-    identity_rhs DEFAULT       _    = Var case_bndr
+    mk_id_rhs (DataAlt con) args = mkConApp con (arg_tys ++ varsToCoreExprs args)
+    mk_id_rhs (LitAlt lit)  _    = Lit lit
+    mk_id_rhs DEFAULT       _    = Var case_bndr
 
-    arg_tys = (tyConAppArgs (idType case_bndr))
-    arg_ty_exprs = map Type arg_tys
+    arg_tys = map Type (tyConAppArgs (idType case_bndr))
 
        -- We've seen this:
-       --      case coerce T e of x { _ -> coerce T' x }
-       -- And we definitely want to eliminate this case!
-       -- So we throw away notes from the RHS, and reconstruct
-       -- (at least an approximation) at the other end
-    de_note (Note _ e) = de_note e
-    de_note e         = e
-
-       -- re_note wraps a coerce if it might be necessary
-    re_note scrut = case head alts of
-                       (_,_,rhs1@(Note _ _)) -> 
-                            let co = mkUnsafeCoercion (idType case_bndr) (exprType rhs1) in 
-                               -- this unsafeCoercion is bad, make this better
-                            mkCoerce co scrut
-                       other                 -> scrut
+       --      case e of x { _ -> x `cast` c }
+       -- And we definitely want to eliminate this case, to give
+       --      e `cast` c
+       -- So we throw away the cast from the RHS, and reconstruct
+       -- it at the other end.  All the RHS casts must be the same
+       -- if (all identity_alt alts) holds.
+       -- 
+       -- Don't worry about nested casts, because the simplifier combines them
+    de_cast (Cast e _) = e
+    de_cast e         = e
+
+    re_cast scrut = case head alts of
+                       (_,_,Cast _ co) -> Cast scrut co
+                       other           -> scrut