Keep track of explicit kinding in HsTyVarBndr; plus fix Trac #3845
[ghc-hetmet.git] / compiler / typecheck / TcGenDeriv.lhs
index ba1c001..3fb1848 100644 (file)
@@ -42,7 +42,6 @@ import Name
 import HscTypes
 import PrelInfo
 import PrelNames
-import MkId
 import PrimOp
 import SrcLoc
 import TyCon
@@ -58,9 +57,7 @@ import Util
 import MonadUtils
 import Outputable
 import FastString
-import OccName
 import Bag
-
 import Data.List       ( partition, intersperse )
 \end{code}
 
@@ -314,75 +311,80 @@ gen_Ord_binds loc tycon
   | Just (con, prim_tc) <- primWrapperType_maybe tycon
   = gen_PrimOrd_binds con prim_tc
 
-  | otherwise 
+  | otherwise
   = (unitBag compare, aux_binds)
-       -- `AndMonoBinds` compare       
-       -- The default declaration in PrelBase handles this
+        -- `AndMonoBinds` compare
+        -- The default declaration in PrelBase handles this
   where
     aux_binds | single_con_type = []
-             | otherwise       = [GenCon2Tag tycon]
+              | otherwise       = [GenCon2Tag tycon]
 
     compare = L loc (mkFunBind (L loc compare_RDR) compare_matches)
     compare_matches = [mkMatch [a_Pat, b_Pat] compare_rhs cmp_eq_binds]
     cmp_eq_binds    = HsValBinds (ValBindsIn (unitBag cmp_eq) [])
 
     compare_rhs
-       | single_con_type = cmp_eq_Expr a_Expr b_Expr
-       | otherwise
-       = untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
-                 (cmp_tags_Expr eqInt_RDR ah_RDR bh_RDR
-                       (cmp_eq_Expr a_Expr b_Expr)     -- True case
-                       -- False case; they aren't equal
-                       -- So we need to do a less-than comparison on the tags
-                       (cmp_tags_Expr ltInt_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr))
+        | single_con_type = cmp_eq_Expr a_Expr b_Expr
+        | otherwise
+        = untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
+                  (cmp_tags_Expr eqInt_RDR ah_RDR bh_RDR
+                        (cmp_eq_Expr a_Expr b_Expr)     -- True case
+                        -- False case; they aren't equal
+                        -- So we need to do a less-than comparison on the tags
+                        (cmp_tags_Expr ltInt_RDR ah_RDR bh_RDR
+                                       ltTag_Expr gtTag_Expr))
 
     tycon_data_cons = tyConDataCons tycon
     single_con_type = isSingleton tycon_data_cons
     (nullary_cons, nonnullary_cons)
        | isNewTyCon tycon = ([], tyConDataCons tycon)
-       | otherwise       = partition isNullarySrcDataCon tycon_data_cons
+       | otherwise        = partition isNullarySrcDataCon tycon_data_cons
 
     cmp_eq = mk_FunBind loc cmp_eq_RDR cmp_eq_match
     cmp_eq_match
       | isEnumerationTyCon tycon
-                          -- We know the tags are equal, so if it's an enumeration TyCon,
-                          -- then there is nothing left to do
-                          -- Catch this specially to avoid warnings
-                          -- about overlapping patterns from the desugarer,
-                          -- and to avoid unnecessary pattern-matching
+                           -- We know the tags are equal, so if it's an
+                           -- enumeration TyCon,
+                           -- then there is nothing left to do
+                           -- Catch this specially to avoid warnings
+                           -- about overlapping patterns from the desugarer,
+                           -- and to avoid unnecessary pattern-matching
       = [([nlWildPat,nlWildPat], eqTag_Expr)]
       | otherwise
       = map pats_etc nonnullary_cons ++
-       (if single_con_type then        -- Omit wildcards when there's just one 
-             []                        -- constructor, to silence desugarer
-       else
+        (if single_con_type then        -- Omit wildcards when there's just one
+              []                        -- constructor, to silence desugarer
+        else
               [([nlWildPat, nlWildPat], default_rhs)])
 
-    default_rhs | null nullary_cons = impossible_Expr  -- Keep desugarer from complaining about
-                                                       -- inexhaustive patterns
-               | otherwise         = eqTag_Expr        -- Some nullary constructors;
-                                                       -- Tags are equal, no args => return EQ
+    default_rhs | null nullary_cons = -- Keep desugarer from complaining about
+                                      -- inexhaustive patterns
+                                      impossible_Expr
+                | otherwise         = -- Some nullary constructors;
+                                      -- Tags are equal, no args => return EQ
+                                      eqTag_Expr
     pats_etc data_con
-       = ([con1_pat, con2_pat],
-          nested_compare_expr tys_needed as_needed bs_needed)
-       where
-         con1_pat = nlConVarPat data_con_RDR as_needed
-         con2_pat = nlConVarPat data_con_RDR bs_needed
-
-         data_con_RDR = getRdrName data_con
-         con_arity   = length tys_needed
-         as_needed   = take con_arity as_RDRs
-         bs_needed   = take con_arity bs_RDRs
-         tys_needed  = dataConOrigArgTys data_con
-
-         nested_compare_expr [ty] [a] [b]
-           = careful_compare_Case tycon ty eqTag_Expr (nlHsVar a) (nlHsVar b)
-
-         nested_compare_expr (ty:tys) (a:as) (b:bs)
-           = let eq_expr = nested_compare_expr tys as bs
-               in  careful_compare_Case tycon ty eq_expr (nlHsVar a) (nlHsVar b)
-
-         nested_compare_expr _ _ _ = panic "nested_compare_expr"       -- Args always equal length
+        = ([con1_pat, con2_pat],
+           nested_compare_expr tys_needed as_needed bs_needed)
+        where
+          con1_pat = nlConVarPat data_con_RDR as_needed
+          con2_pat = nlConVarPat data_con_RDR bs_needed
+
+          data_con_RDR = getRdrName data_con
+          con_arity   = length tys_needed
+          as_needed   = take con_arity as_RDRs
+          bs_needed   = take con_arity bs_RDRs
+          tys_needed  = dataConOrigArgTys data_con
+
+          nested_compare_expr [ty] [a] [b]
+            = careful_compare_Case tycon ty eqTag_Expr (nlHsVar a) (nlHsVar b)
+
+          nested_compare_expr (ty:tys) (a:as) (b:bs)
+            = let eq_expr = nested_compare_expr tys as bs
+              in careful_compare_Case tycon ty eq_expr (nlHsVar a) (nlHsVar b)
+
+          -- Args always equal length
+          nested_compare_expr _ _ _ = panic "nested_compare_expr"
 \end{code}
 
 Note [Comparision of primitive types]
@@ -569,8 +571,8 @@ gen_Bounded_binds loc tycon
     data_cons = tyConDataCons tycon
 
     ----- enum-flavored: ---------------------------
-    min_bound_enum = mkVarBind loc minBound_RDR (nlHsVar data_con_1_RDR)
-    max_bound_enum = mkVarBind loc maxBound_RDR (nlHsVar data_con_N_RDR)
+    min_bound_enum = mkHsVarBind loc minBound_RDR (nlHsVar data_con_1_RDR)
+    max_bound_enum = mkHsVarBind loc maxBound_RDR (nlHsVar data_con_N_RDR)
 
     data_con_1   = head data_cons
     data_con_N   = last data_cons
@@ -580,9 +582,9 @@ gen_Bounded_binds loc tycon
     ----- single-constructor-flavored: -------------
     arity         = dataConSourceArity data_con_1
 
-    min_bound_1con = mkVarBind loc minBound_RDR $
+    min_bound_1con = mkHsVarBind loc minBound_RDR $
                     nlHsVarApps data_con_1_RDR (nOfThem arity minBound_RDR)
-    max_bound_1con = mkVarBind loc maxBound_RDR $
+    max_bound_1con = mkHsVarBind loc maxBound_RDR $
                     nlHsVarApps data_con_1_RDR (nOfThem arity maxBound_RDR)
 \end{code}
 
@@ -721,7 +723,7 @@ gen_Ix_binds loc tycon
 
        mk_qual a b c = noLoc $ mkBindStmt (nlVarPat c)
                                 (nlHsApp (nlHsVar range_RDR) 
-                                       (nlTuple [nlHsVar a, nlHsVar b] Boxed))
+                                         (mkLHsVarTuple [a,b]))
 
     ----------------
     single_con_index
@@ -743,11 +745,11 @@ gen_Ix_binds loc tycon
            ) plus_RDR (
                genOpApp (
                    (nlHsApp (nlHsVar unsafeRangeSize_RDR) 
-                          (nlTuple [nlHsVar l, nlHsVar u] Boxed))
+                            (mkLHsVarTuple [l,u]))
                ) times_RDR (mk_index rest)
           )
        mk_one l u i
-         = nlHsApps unsafeIndex_RDR [nlTuple [nlHsVar l, nlHsVar u] Boxed, nlHsVar i]
+         = nlHsApps unsafeIndex_RDR [mkLHsVarTuple [l,u], nlHsVar i]
 
     ------------------
     single_con_inRange
@@ -756,8 +758,7 @@ gen_Ix_binds loc tycon
                 con_pat cs_needed] $
          foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed)
       where
-       in_range a b c = nlHsApps inRange_RDR [nlTuple [nlHsVar a, nlHsVar b] Boxed,
-                                              nlHsVar c]
+       in_range a b c = nlHsApps inRange_RDR [mkLHsVarTuple [a,b], nlHsVar c]
 \end{code}
 
 %************************************************************************
@@ -812,16 +813,16 @@ gen_Read_binds get_fixity loc tycon
   where
     -----------------------------------------------------------------------
     default_readlist 
-       = mkVarBind loc readList_RDR     (nlHsVar readListDefault_RDR)
+       = mkHsVarBind loc readList_RDR     (nlHsVar readListDefault_RDR)
 
     default_readlistprec
-       = mkVarBind loc readListPrec_RDR (nlHsVar readListPrecDefault_RDR)
+       = mkHsVarBind loc readListPrec_RDR (nlHsVar readListPrecDefault_RDR)
     -----------------------------------------------------------------------
 
     data_cons = tyConDataCons tycon
     (nullary_cons, non_nullary_cons) = partition isNullarySrcDataCon data_cons
     
-    read_prec = mkVarBind loc readPrec_RDR
+    read_prec = mkHsVarBind loc readPrec_RDR
                              (nlHsApp (nlHsVar parens_RDR) read_cons)
 
     read_cons            = foldr1 mk_alt (read_nullary_cons ++ read_non_nullary_cons)
@@ -835,9 +836,8 @@ gen_Read_binds get_fixity loc tycon
             _     -> [nlHsApp (nlHsVar choose_RDR) 
                              (nlList (map mk_pair nullary_cons))]
     
-    mk_pair con = nlTuple [nlHsLit (mkHsString (data_con_str con)), 
-                          result_expr con []]
-                         Boxed
+    mk_pair con = mkLHsTupleExpr [nlHsLit (mkHsString (data_con_str con)), 
+                                 result_expr con []]
     
     read_non_nullary_con data_con
       | is_infix  = mk_parser infix_prec  infix_stmts  body
@@ -966,7 +966,7 @@ gen_Show_binds get_fixity loc tycon
   = (listToBag [shows_prec, show_list], [])
   where
     -----------------------------------------------------------------------
-    show_list = mkVarBind loc showList_RDR
+    show_list = mkHsVarBind loc showList_RDR
                  (nlHsApp (nlHsVar showList___RDR) (nlHsPar (nlHsApp (nlHsVar showsPrec_RDR) (nlHsIntLit 0))))
     -----------------------------------------------------------------------
     shows_prec = mk_FunBind loc showsPrec_RDR (map pats_etc (tyConDataCons tycon))
@@ -1098,7 +1098,7 @@ gen_Typeable_binds loc tycon
                [nlWildPat] 
                (nlHsApps mkTypeRep_RDR [tycon_rep, nlList []])
   where
-    tycon_rep = nlHsVar mkTyConRep_RDR `nlHsApp` nlHsLit (mkHsString (showSDoc (ppr tycon)))
+    tycon_rep = nlHsVar mkTyConRep_RDR `nlHsApp` nlHsLit (mkHsString (showSDocOneLine (ppr tycon)))
 
 mk_typeOf_RDR :: TyCon -> RdrName
 -- Use the arity of the TyCon to make the right typeOfn function
@@ -1142,13 +1142,18 @@ we generate
     
     dataTypeOf _ = $dT
 
+    dataCast1 = gcast1   -- If T :: * -> *
+    dataCast2 = gcast2   -- if T :: * -> * -> *
+
+    
 \begin{code}
 gen_Data_binds :: SrcSpan
               -> TyCon 
               -> (LHsBinds RdrName,    -- The method bindings
                   DerivAuxBinds)       -- Auxiliary bindings
 gen_Data_binds loc tycon
-  = (listToBag [gfoldl_bind, gunfold_bind, toCon_bind, dataTypeOf_bind],
+  = (listToBag [gfoldl_bind, gunfold_bind, toCon_bind, dataTypeOf_bind]
+     `unionBags` gcast_binds,
                -- Auxiliary definitions: the data type and constructors
      MkTyCon tycon : map MkDataCon data_cons)
   where
@@ -1200,13 +1205,31 @@ gen_Data_binds loc tycon
                        [nlWildPat]
                         (nlHsVar (mk_data_type_name tycon))
 
+       ------------ gcast1/2
+    tycon_kind = tyConKind tycon
+    gcast_binds | tycon_kind `eqKind` kind1 = mk_gcast dataCast1_RDR gcast1_RDR
+               | tycon_kind `eqKind` kind2 = mk_gcast dataCast2_RDR gcast2_RDR
+               | otherwise           = emptyBag
+    mk_gcast dataCast_RDR gcast_RDR 
+      = unitBag (mk_easy_FunBind loc dataCast_RDR [nlVarPat f_RDR] 
+                                 (nlHsVar gcast_RDR `nlHsApp` nlHsVar f_RDR))
+
+
+kind1, kind2 :: Kind
+kind1 = liftedTypeKind `mkArrowKind` liftedTypeKind
+kind2 = liftedTypeKind `mkArrowKind` kind1
 
 gfoldl_RDR, gunfold_RDR, toConstr_RDR, dataTypeOf_RDR, mkConstr_RDR,
-    mkDataType_RDR, conIndex_RDR, prefix_RDR, infix_RDR :: RdrName
+    mkDataType_RDR, conIndex_RDR, prefix_RDR, infix_RDR,
+    dataCast1_RDR, dataCast2_RDR, gcast1_RDR, gcast2_RDR :: RdrName
 gfoldl_RDR     = varQual_RDR gENERICS (fsLit "gfoldl")
 gunfold_RDR    = varQual_RDR gENERICS (fsLit "gunfold")
 toConstr_RDR   = varQual_RDR gENERICS (fsLit "toConstr")
 dataTypeOf_RDR = varQual_RDR gENERICS (fsLit "dataTypeOf")
+dataCast1_RDR  = varQual_RDR gENERICS (fsLit "dataCast1")
+dataCast2_RDR  = varQual_RDR gENERICS (fsLit "dataCast2")
+gcast1_RDR     = varQual_RDR tYPEABLE (fsLit "gcast1")
+gcast2_RDR     = varQual_RDR tYPEABLE (fsLit "gcast2")
 mkConstr_RDR   = varQual_RDR gENERICS (fsLit "mkConstr")
 mkDataType_RDR = varQual_RDR gENERICS (fsLit "mkDataType")
 conIndex_RDR   = varQual_RDR gENERICS (fsLit "constrIndex")
@@ -1218,7 +1241,10 @@ infix_RDR      = dataQual_RDR gENERICS (fsLit "Infix")
 
 %************************************************************************
 %*                                                                     *
-       Functor instances
+                       Functor instances
+
+ see http://www.mail-archive.com/haskell-prime@haskell.org/msg02116.html
+
 %*                                                                     *
 %************************************************************************
 
@@ -1421,7 +1447,10 @@ mkSimpleTupleCase match_for_con boxity insides x = do
 
 %************************************************************************
 %*                                                                     *
-       Foldable instances
+                       Foldable instances
+
+ see http://www.mail-archive.com/haskell-prime@haskell.org/msg02116.html
+
 %*                                                                     *
 %************************************************************************
 
@@ -1449,7 +1478,7 @@ gen_Foldable_binds loc tycon
   where
     data_cons = tyConDataCons tycon
 
-    foldr_bind = L loc $ mkFunBind (L loc foldr_RDR) (map foldr_eqn data_cons)
+    foldr_bind = L loc $ mkFunBind (L loc foldable_foldr_RDR) (map foldr_eqn data_cons)
     foldr_eqn con = evalState (match_for_con z_Expr [f_Pat,z_Pat] con parts) bs_RDRs
       where 
         parts = foldDataConArgs ft_foldr con
@@ -1471,7 +1500,9 @@ gen_Foldable_binds loc tycon
 
 %************************************************************************
 %*                                                                     *
-       Traversable instances
+                       Traversable instances
+
+ see http://www.mail-archive.com/haskell-prime@haskell.org/msg02116.html
 %*                                                                     *
 %************************************************************************
 
@@ -1567,7 +1598,8 @@ genAuxBind loc (GenCon2Tag tycon)
     get_tag_rhs = L loc $ ExprWithTySig 
                        (nlHsLam (mkSimpleHsAlt (nlVarPat a_RDR) 
                                              (nlHsApp (nlHsVar getTag_RDR) a_Expr)))
-                       (noLoc (mkExplicitHsForAllTy (map (noLoc.UserTyVar) tvs) (noLoc []) con2tag_ty))
+                       (noLoc (mkExplicitHsForAllTy (userHsTyVarBndrs (map noLoc tvs)) 
+                                                     (noLoc []) con2tag_ty))
 
     con2tag_ty = nlHsTyConApp (getRdrName tycon) (map nlHsTyVar tvs)
                `nlHsFunTy` 
@@ -1590,7 +1622,7 @@ genAuxBind loc (GenTag2Con tycon)
     rdr_name = tag2con_RDR tycon
 
 genAuxBind loc (GenMaxTag tycon)
-  = mkVarBind loc rdr_name 
+  = mkHsVarBind loc rdr_name 
                  (nlHsApp (nlHsVar intDataCon_RDR) (nlHsLit (HsIntPrim max_tag)))
   where
     rdr_name = maxtag_RDR tycon
@@ -1598,16 +1630,16 @@ genAuxBind loc (GenMaxTag tycon)
                 data_cons -> toInteger ((length data_cons) - fIRST_TAG)
 
 genAuxBind loc (MkTyCon tycon) --  $dT
-  = mkVarBind loc (mk_data_type_name tycon)
-                 ( nlHsVar mkDataType_RDR 
-                    `nlHsApp` nlHsLit (mkHsString (showSDoc (ppr tycon)))
+  = mkHsVarBind loc (mk_data_type_name tycon)
+                   ( nlHsVar mkDataType_RDR 
+                    `nlHsApp` nlHsLit (mkHsString (showSDocOneLine (ppr tycon)))
                     `nlHsApp` nlList constrs )
   where
     constrs = [nlHsVar (mk_constr_name con) | con <- tyConDataCons tycon]
 
 genAuxBind loc (MkDataCon dc)  --  $cT1 etc
-  = mkVarBind loc (mk_constr_name dc) 
-                 (nlHsApps mkConstr_RDR constr_args)
+  = mkHsVarBind loc (mk_constr_name dc) 
+                   (nlHsApps mkConstr_RDR constr_args)
   where
     constr_args 
        = [ -- nlHsIntLit (toInteger (dataConTag dc)),    -- Tag