Correct substitution into theta types (after merge)
[ghc-hetmet.git] / compiler / typecheck / TcExpr.lhs
index c0a9294..6354499 100644 (file)
@@ -12,7 +12,7 @@ module TcExpr ( tcPolyExpr, tcPolyExprNC,
 #ifdef GHCI    /* Only if bootstrapped */
 import {-# SOURCE #-}  TcSplice( tcSpliceExpr, tcBracket )
 import HsSyn           ( nlHsVar )
-import Id              ( Id )
+import Id              ( Id, idName )
 import Name            ( isExternalName )
 import TcType          ( isTauTy )
 import TcEnv           ( checkWellStaged )
@@ -54,7 +54,7 @@ import {- Kind parts of -}
 
 import Id              ( Id, idType, recordSelectorFieldLabel,
                          isRecordSelector, isNaughtyRecordSelector,
-                         isDataConId_maybe, idName )
+                         isDataConId_maybe )
 import DataCon         ( DataCon, dataConFieldLabels, dataConStrictMarks,
                          dataConSourceArity, 
                          dataConWrapId, isVanillaDataCon, dataConUnivTyVars,
@@ -772,14 +772,10 @@ instFun orig fun subst []
   = return fun         -- Common short cut
 
 instFun orig fun subst tv_theta_prs
-  = do         {-- !!!SPJ:     -- Horrid check for tagToEnum; see Note [tagToEnum#]
-        -- !!!SPJ: checkBadTagToEnumCall fun_id qtv_tys
+  = do         { let ty_theta_prs' = map subst_pr tv_theta_prs
 
-       ; let ty_theta_prs' = map subst_pr tv_theta_prs
-
-               -- First, chuck in the constraints from 
-               -- the "stupid theta" of a data constructor (sigh)
-       ; inst_stupid fun ty_theta_prs'
+                -- Make two ad-hoc checks 
+       ; doStupidChecks orig fun ty_theta_prs'
 
                -- Now do normal instantiation
        ; go True fun ty_theta_prs' }
@@ -787,11 +783,6 @@ instFun orig fun subst tv_theta_prs
     subst_pr (tvs, theta) 
        = (map (substTyVar subst) tvs, substTheta subst theta)
 
-    inst_stupid (HsVar fun_id) ((tys,_):_)
-       | Just con <- isDataConId_maybe fun_id 
-       = addDataConStupidTheta orig con tys
-    inst_stupid _ _ = return ()
-
     go _ fun [] = return fun
 
     go True (HsVar fun_id) ((tys,theta) : prs)
@@ -900,20 +891,33 @@ Here's are two cases that should fail
 
 
 \begin{code}
-checkBadTagToEnumCall :: Id -> [TcType] -> TcM ()
-checkBadTagToEnumCall fun_id tys
-  | fun_id `hasKey` tagToEnumKey
+doStupidChecks :: InstOrigin
+              -> HsExpr TcId
+              -> [([TcType], ThetaType)]
+              -> TcM ()
+-- Check two tiresome and ad-hoc cases
+-- (a) the "stupid theta" for a data con; add the constraints
+--     from the "stupid theta" of a data constructor (sigh)
+-- (b) deal with the tagToEnum# problem: see Note [tagToEnum#]
+
+doStupidChecks orig (HsVar fun_id) ((tys,_):_)
+  | Just con <- isDataConId_maybe fun_id   -- (a)
+  = addDataConStupidTheta orig con tys
+
+  | fun_id `hasKey` tagToEnumKey           -- (b)
   = do { tys' <- zonkTcTypes tys
        ; checkTc (ok tys') (tagToEnumError tys')
        }
-  | otherwise    -- Vastly common case
-  = return ()
   where
     ok []      = False
     ok (ty:tys) = case tcSplitTyConApp_maybe ty of
                        Just (tc,_) -> isEnumerationTyCon tc
                        Nothing     -> False
 
+doStupidChecks orig fun tv_theta_prs
+  = return () -- The common case
+                                     
+
 tagToEnumError tys
   = hang (ptext SLIT("Bad call to tagToEnum#") <+> at_type)
         2 (vcat [ptext SLIT("Specify the type by giving a type signature"),
@@ -965,16 +969,10 @@ thLocalId orig id id_ty th_bind_lvl
        ; case use_stage of
            Brack use_lvl ps_var lie_var | use_lvl > th_bind_lvl
                  -> thBrackId orig id ps_var lie_var
-           other -> checkWellStaged (quotes (ppr id)) th_bind_lvl use_stage
+           other -> do { checkWellStaged (quotes (ppr id)) th_bind_lvl use_stage
+                       ; return id }
        }
 
-thLocalId orig id_name id th_bind_lvl (Brack use_lvl ps_var lie_var)
-  | use_lvl > th_bind_lvl
-  = thBrackId 
-thLocalId orig id_name id th_bind_lvl use_stage
-  = do { checkWellStaged 
-       ; return id }
-
 --------------------------------------
 thBrackId orig id ps_var lie_var
   | isExternalName id_name