This is where we do all the grimy bindings' generation.
\begin{code}
-#include "HsVersions.h"
-
module TcGenDeriv (
gen_Bounded_binds,
gen_Enum_binds,
TagThingWanted(..)
) where
-IMP_Ubiq()
-IMPORT_1_3(List(partition))
+#include "HsVersions.h"
-import HsSyn ( HsBinds(..), Bind(..), MonoBinds(..), Match(..), GRHSsAndBinds(..),
- GRHS(..), HsExpr(..), HsLit(..), InPat(..), Qualifier(..), Stmt,
- ArithSeqInfo, Sig, HsType, FixityDecl, Fake )
-import RdrHsSyn ( RdrName(..), varQual, varUnqual,
- SYN_IE(RdrNameMonoBinds), SYN_IE(RdrNameHsExpr), SYN_IE(RdrNamePat)
+import HsSyn ( InPat(..), HsExpr(..), MonoBinds(..), GRHS(..),
+ Match(..), GRHSsAndBinds(..), Stmt(..), HsLit(..),
+ HsBinds(..), DoOrListComp(..),
+ unguardedRHS
)
--- import RnHsSyn ( RenamedFixityDecl(..) )
-
-import Id ( GenId, dataConNumFields, isNullaryDataCon, dataConTag,
+import RdrHsSyn ( RdrName(..), varQual, varUnqual, mkOpApp,
+ RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat
+ )
+import BasicTypes ( IfaceFlavour(..), RecFlag(..) )
+import FieldLabel ( fieldLabelName )
+import Id ( GenId, isNullaryDataCon, dataConTag,
dataConRawArgTys, fIRST_TAG,
- isDataCon, SYN_IE(DataCon), SYN_IE(ConTag) )
+ isDataCon, DataCon, ConTag,
+ dataConFieldLabels, Id )
import Maybes ( maybeToBool )
-import Name ( getOccString, getSrcLoc, occNameString, modAndOcc, OccName, Name )
+import Name ( getOccString, getOccName, getSrcLoc, occNameString,
+ modAndOcc, OccName, Name )
import PrimOp ( PrimOp(..) )
import PrelInfo -- Lots of RdrNames
-import SrcLoc ( mkGeneratedSrcLoc )
-import TyCon ( TyCon, tyConDataCons, isEnumerationTyCon, maybeTyConSingleCon )
-import Type ( eqTy, isPrimType )
+import SrcLoc ( mkGeneratedSrcLoc, SrcLoc )
+import TyCon ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon, maybeTyConSingleCon )
+import Type ( isUnpointedType, isUnboxedType, Type )
import TysPrim ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy,
floatPrimTy, doublePrimTy
)
-import Util ( mapAccumL, zipEqual, zipWith3Equal, nOfThem, panic, assertPanic )
+import Util ( mapAccumL, zipEqual, zipWithEqual,
+ zipWith3Equal, nOfThem, panic, assertPanic )
+
+import List ( partition, intersperse )
\end{code}
%************************************************************************
gen_Eq_binds tycon
= let
tycon_loc = getSrcLoc tycon
- (nullary_cons, nonnullary_cons)
- = partition isNullaryDataCon (tyConDataCons tycon)
+ (nullary_cons, nonnullary_cons)
+ | isNewTyCon tycon = ([], tyConDataCons tycon)
+ | otherwise = partition isNullaryDataCon (tyConDataCons tycon)
rest
= if (null nullary_cons) then
where
nested_eq_expr [] [] [] = true_Expr
nested_eq_expr tys as bs
- = foldr1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
+ = foldl1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
where
nested_eq ty a b = HsPar (eq_Expr ty (HsVar a) (HsVar b))
\end{code}
Again, we must be careful about unboxed comparisons. For example,
if \tr{a1} and \tr{a2} were \tr{Int#}s in the 2nd example above, we'd need to
generate:
+
\begin{verbatim}
cmp_eq lt eq gt (O2 a1) (O2 a2)
= compareInt# a1 a2
\end{verbatim}
\end{itemize}
+If there is only one constructor in the Data Type we don't need the WildCard Pattern.
+JJQC-30-Nov-1997
+
\begin{code}
gen_Ord_binds :: TyCon -> RdrNameMonoBinds
-- So we need to do a less-than comparison on the tags
(cmp_tags_Expr ltH_Int_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr)))
+ tycon_data_cons = tyConDataCons tycon
(nullary_cons, nonnullary_cons)
- = partition isNullaryDataCon (tyConDataCons tycon)
-
- cmp_eq
- = mk_FunMonoBind tycon_loc cmp_eq_RDR (map pats_etc nonnullary_cons ++ deflt_pats_etc)
+ | isNewTyCon tycon = ([], tyConDataCons tycon)
+ | otherwise = partition isNullaryDataCon tycon_data_cons
+
+ cmp_eq =
+ mk_FunMonoBind tycon_loc
+ cmp_eq_RDR
+ (if null nonnullary_cons && (length nullary_cons == 1) then
+ -- catch this specially to avoid warnings
+ -- about overlapping patterns from the desugarer.
+ let
+ data_con = head nullary_cons
+ data_con_RDR = qual_orig_name data_con
+ pat = ConPatIn data_con_RDR []
+ in
+ [([pat,pat], eqTag_Expr)]
+ else
+ map pats_etc nonnullary_cons ++
+ -- leave out wildcards to silence desugarer.
+ (if length tycon_data_cons == 1 then
+ []
+ else
+ [([WildPatIn, WildPatIn], default_rhs)]))
where
pats_etc data_con
= ([con1_pat, con2_pat],
= let eq_expr = nested_compare_expr tys as bs
in careful_compare_Case ty ltTag_Expr eq_expr gtTag_Expr (HsVar a) (HsVar b)
- deflt_pats_etc
- = if null nullary_cons
- then []
- else [([a_Pat, b_Pat], eqTag_Expr)]
+ 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
--------------------------------------------------------------------
defaulted = foldr1 AndMonoBinds [lt, le, ge, gt, max_, min_]
\begin{verbatim}
instance ... Enum (Foo ...) where
+ toEnum i = tag2con_Foo i
+
enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo]
-- or, really...
gen_Enum_binds :: TyCon -> RdrNameMonoBinds
gen_Enum_binds tycon
- = enum_from `AndMonoBinds`
+ = to_enum `AndMonoBinds`
+ enum_from `AndMonoBinds`
enum_from_then `AndMonoBinds`
from_enum
where
tycon_loc = getSrcLoc tycon
+
+ to_enum
+ = mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $
+ mk_easy_App (tag2con_RDR tycon) [a_RDR]
+
enum_from
= mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $
untag_Expr tycon [(a_RDR, ah_RDR)] $
data_con_N_RDR = qual_orig_name data_con_N
----- single-constructor-flavored: -------------
- arity = dataConNumFields data_con_1
+ arity = argFieldCount data_con_1
min_bound_1con = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] $
mk_easy_App data_con_1_RDR (nOfThem arity minBound_RDR)
untag_Expr tycon [(a_RDR, ah_RDR)] (
untag_Expr tycon [(d_RDR, dh_RDR)] (
let
- grhs = [OtherwiseGRHS (mk_easy_App mkInt_RDR [c_RDR]) tycon_loc]
+ grhs = unguardedRHS (mk_easy_App mkInt_RDR [c_RDR]) tycon_loc
in
HsCase
- (HsPar (OpApp (HsVar dh_RDR) (HsVar minusH_RDR) (HsVar ah_RDR)))
+ (genOpApp (HsVar dh_RDR) minusH_RDR (HsVar ah_RDR))
[PatMatch (VarPatIn c_RDR)
(GRHSMatch (GRHSsAndBindsIn grhs EmptyBinds))]
tycon_loc
untag_Expr tycon [(a_RDR, ah_RDR)] (
untag_Expr tycon [(b_RDR, bh_RDR)] (
untag_Expr tycon [(c_RDR, ch_RDR)] (
- HsIf (HsPar (OpApp (HsVar ch_RDR) (HsVar geH_RDR) (HsVar ah_RDR))) (
- (OpApp (HsVar ch_RDR) (HsVar leH_RDR) (HsVar bh_RDR))
+ HsIf (genOpApp (HsVar ch_RDR) geH_RDR (HsVar ah_RDR)) (
+ (genOpApp (HsVar ch_RDR) leH_RDR (HsVar bh_RDR))
) {-else-} (
false_Expr
) tycon_loc))))
--------------------------------------------------------------
- single_con_ixes = single_con_range `AndMonoBinds`
- single_con_index `AndMonoBinds` single_con_inRange
+ single_con_ixes
+ = single_con_range `AndMonoBinds`
+ single_con_index `AndMonoBinds`
+ single_con_inRange
data_con
= case maybeTyConSingleCon tycon of -- just checking...
Nothing -> panic "get_Ix_binds"
- Just dc -> if (any isPrimType (dataConRawArgTys dc)) then
+ Just dc -> if (any isUnpointedType (dataConRawArgTys dc)) then
error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
else
dc
- con_arity = dataConNumFields data_con
+ con_arity = argFieldCount data_con
data_con_RDR = qual_orig_name data_con
- con_pat xs = ConPatIn data_con_RDR (map VarPatIn xs)
- con_expr xs = mk_easy_App data_con_RDR xs
as_needed = take con_arity as_RDRs
bs_needed = take con_arity bs_RDRs
cs_needed = take con_arity cs_RDRs
+ con_pat xs = ConPatIn data_con_RDR (map VarPatIn xs)
+ con_expr = mk_easy_App data_con_RDR cs_needed
+
--------------------------------------------------------------
single_con_range
- = mk_easy_FunMonoBind tycon_loc range_RDR [TuplePatIn [con_pat as_needed, con_pat bs_needed]] [] (
- ListComp (con_expr cs_needed) (zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed)
- )
+ = mk_easy_FunMonoBind tycon_loc range_RDR [TuplePatIn [con_pat as_needed, con_pat bs_needed]] [] $
+ HsDo ListComp stmts tycon_loc
where
- mk_qual a b c = GeneratorQual (VarPatIn c)
- (HsApp (HsVar range_RDR) (ExplicitTuple [HsVar a, HsVar b]))
+ stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
+ ++
+ [ReturnStmt con_expr]
+
+ mk_qual a b c = BindStmt (VarPatIn c)
+ (HsApp (HsVar range_RDR) (ExplicitTuple [HsVar a, HsVar b]))
+ tycon_loc
----------------
single_con_index
foldl mk_index (HsLit (HsInt 0)) (zip3 as_needed bs_needed cs_needed))
where
mk_index multiply_by (l, u, i)
- =OpApp (
+ = genOpApp (
(HsApp (HsApp (HsVar index_RDR) (ExplicitTuple [HsVar l, HsVar u])) (HsVar i))
- ) (HsVar plus_RDR) (
- OpApp (
+ ) plus_RDR (
+ genOpApp (
(HsApp (HsVar rangeSize_RDR) (ExplicitTuple [HsVar l, HsVar u]))
- ) (HsVar times_RDR) multiply_by
+ ) times_RDR multiply_by
)
range_size
= mk_easy_FunMonoBind tycon_loc rangeSize_RDR [TuplePatIn [a_Pat, b_Pat]] [] (
- OpApp (
+ genOpApp (
(HsApp (HsApp (HsVar index_RDR) (ExplicitTuple [a_Expr, b_Expr])) b_Expr)
- ) (HsVar plus_RDR) (HsLit (HsInt 1)))
+ ) plus_RDR (HsLit (HsInt 1)))
------------------
single_con_inRange
= map read_con (tyConDataCons tycon)
in
mk_easy_FunMonoBind tycon_loc readsPrec_RDR [a_Pat, b_Pat] [] (
- foldl1 append_Expr read_con_comprehensions
+ foldr1 append_Expr read_con_comprehensions
)
where
read_con data_con -- note: "b" is the string being "read"
= let
data_con_RDR = qual_orig_name data_con
data_con_str= occNameString (getOccName data_con)
- con_arity = dataConNumFields data_con
- as_needed = take con_arity as_RDRs
- bs_needed = take con_arity bs_RDRs
+ con_arity = argFieldCount data_con
con_expr = mk_easy_App data_con_RDR as_needed
- nullary_con = isNullaryDataCon data_con
+ nullary_con = con_arity == 0
+ labels = dataConFieldLabels data_con
+ lab_fields = length labels
+ as_needed = take con_arity as_RDRs
+ bs_needed
+ | lab_fields == 0 = take con_arity bs_RDRs
+ | otherwise = take (4*lab_fields + 1) bs_RDRs
+ -- (label, '=' and field)*n, (n-1)*',' + '{' + '}'
con_qual
- = GeneratorQual
- (TuplePatIn [LitPatIn (HsString data_con_str), d_Pat])
- (HsApp (HsVar lex_RDR) c_Expr)
-
- field_quals = snd (mapAccumL mk_qual d_Expr (zipEqual "as_needed" as_needed bs_needed))
-
+ = BindStmt
+ (TuplePatIn [LitPatIn (HsString data_con_str), d_Pat])
+ (HsApp (HsVar lex_RDR) c_Expr)
+ tycon_loc
+
+ str_qual str res draw_from
+ = BindStmt
+ (TuplePatIn [LitPatIn (HsString str), VarPatIn res])
+ (HsApp (HsVar lex_RDR) draw_from)
+ tycon_loc
+
+ read_label f
+ = let nm = occNameString (getOccName (fieldLabelName f))
+ in
+ [str_qual nm, str_qual SLIT("=")]
+ -- There might be spaces between the label and '='
+
+ field_quals
+ | lab_fields == 0 =
+ snd (mapAccumL mk_qual
+ d_Expr
+ (zipWithEqual "as_needed"
+ (\ con_field draw_from -> (mk_read_qual con_field,
+ draw_from))
+ as_needed bs_needed))
+ | otherwise =
+ snd $
+ mapAccumL mk_qual d_Expr
+ (zipEqual "bs_needed"
+ ((str_qual (SLIT("{")):
+ concat (
+ intersperse ([str_qual (_CONS_ ',' _NIL_)]) $
+ zipWithEqual
+ "field_quals"
+ (\ as b -> as ++ [b])
+ -- The labels
+ (map read_label labels)
+ -- The fields
+ (map mk_read_qual as_needed))) ++ [str_qual (SLIT("}"))])
+ bs_needed)
+
+ mk_qual draw_from (f, str_left)
+ = (HsVar str_left, -- what to draw from down the line...
+ f str_left draw_from)
+
+ mk_read_qual con_field res draw_from =
+ BindStmt
+ (TuplePatIn [VarPatIn con_field, VarPatIn res])
+ (HsApp (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt 10))) draw_from)
+ tycon_loc
+
+ result_expr = ExplicitTuple [con_expr, if null bs_needed
+ then d_Expr
+ else HsVar (last bs_needed)]
+
+ stmts = con_qual:field_quals ++ [ReturnStmt result_expr]
+
read_paren_arg
= if nullary_con then -- must be False (parens are surely optional)
false_Expr
else -- parens depend on precedence...
- HsPar (OpApp a_Expr (HsVar gt_RDR) (HsLit (HsInt 9)))
+ HsPar (genOpApp a_Expr gt_RDR (HsLit (HsInt 9)))
in
HsApp (
readParen_Expr read_paren_arg $ HsPar $
- HsLam (mk_easy_Match tycon_loc [c_Pat] [] (
- ListComp (ExplicitTuple [con_expr,
- if null bs_needed then d_Expr else HsVar (last bs_needed)])
- (con_qual : field_quals)))
+ HsLam (mk_easy_Match tycon_loc [c_Pat] [] $
+ HsDo ListComp stmts tycon_loc)
) (HsVar b_RDR)
- where
- mk_qual draw_from (con_field, str_left)
- = (HsVar str_left, -- what to draw from down the line...
- GeneratorQual
- (TuplePatIn [VarPatIn con_field, VarPatIn str_left])
- (HsApp (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt 10))) draw_from))
+
\end{code}
%************************************************************************
pats_etc data_con
= let
data_con_RDR = qual_orig_name data_con
- con_arity = dataConNumFields data_con
- bs_needed = take con_arity bs_RDRs
- con_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
- nullary_con = isNullaryDataCon data_con
+ con_arity = argFieldCount data_con
+ bs_needed = take con_arity bs_RDRs
+ con_pat = ConPatIn data_con_RDR (map VarPatIn bs_needed)
+ nullary_con = con_arity == 0
+ labels = dataConFieldLabels data_con
+ lab_fields = length labels
show_con
= let nm = occNameString (getOccName data_con)
- space_maybe = if nullary_con then _NIL_ else SLIT(" ")
+ space_ocurly_maybe
+ | nullary_con = _NIL_
+ | lab_fields == 0 = SLIT(" ")
+ | otherwise = SLIT("{")
+
in
- HsApp (HsVar showString_RDR) (HsLit (HsString (nm _APPEND_ space_maybe)))
+ mk_showString_app (nm _APPEND_ space_ocurly_maybe)
- show_thingies = show_con : (spacified real_show_thingies)
+ show_all con fs
+ = let
+ ccurly_maybe
+ | lab_fields > 0 = [mk_showString_app (SLIT("}"))]
+ | otherwise = []
+ in
+ con:fs ++ ccurly_maybe
+
+ show_thingies = show_all show_con real_show_thingies_with_labs
+
+ show_label l
+ = let nm = occNameString (getOccName (fieldLabelName l))
+ in
+ mk_showString_app (nm _APPEND_ SLIT("="))
+
+ mk_showString_app str = HsApp (HsVar showString_RDR)
+ (HsLit (HsString str))
+
+ real_show_thingies =
+ [ HsApp (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 10))) (HsVar b)
+ | b <- bs_needed ]
+
+ real_show_thingies_with_labs
+ | lab_fields == 0 = intersperse (HsVar showSpace_RDR) real_show_thingies
+ | otherwise = --Assumption: no of fields == no of labelled fields
+ -- (and in same order)
+ concat $
+ intersperse ([mk_showString_app (_CONS_ ',' SLIT(" "))]) $ -- Using SLIT()s containing ,s spells trouble.
+ zipWithEqual "gen_Show_binds"
+ (\ a b -> [a,b])
+ (map show_label labels)
+ real_show_thingies
+
- real_show_thingies
- = [ HsApp (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 10))) (HsVar b)
- | b <- bs_needed ]
in
if nullary_con then -- skip the showParen junk...
ASSERT(null bs_needed)
([a_Pat, con_pat], show_con)
else
([a_Pat, con_pat],
- showParen_Expr (HsPar (OpApp a_Expr (HsVar ge_RDR) (HsLit (HsInt 10))))
+ showParen_Expr (HsPar (genOpApp a_Expr ge_RDR (HsLit (HsInt 10))))
(HsPar (nested_compose_Expr show_thingies)))
- where
- spacified [] = []
- spacified [x] = [x]
- spacified (x:xs) = (x : (HsVar showSpace_RDR) : spacified xs)
\end{code}
%************************************************************************
= ASSERT(isDataCon var)
([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
where
- pat = ConPatIn var_RDR (nOfThem (dataConNumFields var) WildPatIn)
+ pat = ConPatIn var_RDR (nOfThem (argFieldCount var) WildPatIn)
var_RDR = qual_orig_name var
gen_tag_n_con_monobind (rdr_name, tycon, GenTag2Con)
- = mk_FunMonoBind (getSrcLoc tycon) rdr_name (map mk_stuff (tyConDataCons tycon))
+ = mk_FunMonoBind (getSrcLoc tycon) rdr_name (map mk_stuff (tyConDataCons tycon) ++
+ [([WildPatIn], impossible_Expr)])
where
mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
where
max_tag = case (tyConDataCons tycon) of
data_cons -> toInteger ((length data_cons) - fIRST_TAG)
+
\end{code}
%************************************************************************
= mk_match loc pats expr (mkbind binds)
where
mkbind [] = EmptyBinds
- mkbind bs = SingleBind (RecBind (foldr1 AndMonoBinds bs))
+ mkbind bs = MonoBind (foldr1 AndMonoBinds bs) [] Recursive
-- The renamer expects everything in its input to be a
-- "recursive" MonoBinds, and it is its job to sort things out
-- from there.
mk_match loc pats expr binds
= foldr PatMatch
- (GRHSMatch (GRHSsAndBindsIn [OtherwiseGRHS expr loc] binds))
+ (GRHSMatch (GRHSsAndBindsIn (unguardedRHS expr loc) binds))
(map paren pats)
where
paren p@(VarPatIn _) = p
compare_gen_Case fun lt eq gt a b
= HsCase (HsPar (HsApp (HsApp (HsVar fun) a) b)) {-of-}
[PatMatch (ConPatIn ltTag_RDR [])
- (GRHSMatch (GRHSsAndBindsIn [OtherwiseGRHS lt mkGeneratedSrcLoc] EmptyBinds)),
+ (GRHSMatch (GRHSsAndBindsIn (unguardedRHS lt mkGeneratedSrcLoc) EmptyBinds)),
PatMatch (ConPatIn eqTag_RDR [])
- (GRHSMatch (GRHSsAndBindsIn [OtherwiseGRHS eq mkGeneratedSrcLoc] EmptyBinds)),
+ (GRHSMatch (GRHSsAndBindsIn (unguardedRHS eq mkGeneratedSrcLoc) EmptyBinds)),
PatMatch (ConPatIn gtTag_RDR [])
- (GRHSMatch (GRHSsAndBindsIn [OtherwiseGRHS gt mkGeneratedSrcLoc] EmptyBinds))]
+ (GRHSMatch (GRHSsAndBindsIn (unguardedRHS gt mkGeneratedSrcLoc) EmptyBinds))]
mkGeneratedSrcLoc
careful_compare_Case ty lt eq gt a b
- = if not (isPrimType ty) then
+ = if not (isUnboxedType ty) then
compare_gen_Case compare_RDR lt eq gt a b
else -- we have to do something special for primitive things...
- HsIf (HsPar (OpApp a (HsVar relevant_eq_op) b))
+ HsIf (genOpApp a relevant_eq_op b)
eq
- (HsIf (HsPar (OpApp a (HsVar relevant_lt_op) b)) lt gt mkGeneratedSrcLoc)
+ (HsIf (genOpApp a relevant_lt_op b) lt gt mkGeneratedSrcLoc)
mkGeneratedSrcLoc
where
relevant_eq_op = assoc_ty_id eq_op_tbl ty
= if null res then panic "assoc_ty"
else head res
where
- res = [id | (ty',id) <- tyids, eqTy ty ty']
+ res = [id | (ty',id) <- tyids, ty == ty']
eq_op_tbl =
[(charPrimTy, eqH_Char_RDR)
and_Expr, append_Expr :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
-and_Expr a b = OpApp a (HsVar and_RDR) b
-append_Expr a b = OpApp a (HsVar append_RDR) b
+and_Expr a b = genOpApp a and_RDR b
+append_Expr a b = genOpApp a append_RDR b
-----------------------------------------------------------------------
eq_Expr :: Type -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
eq_Expr ty a b
- = if not (isPrimType ty) then
- OpApp a (HsVar eq_RDR) b
+ = if not (isUnboxedType ty) then
+ genOpApp a eq_RDR b
else -- we have to do something special for primitive things...
- OpApp a (HsVar relevant_eq_op) b
+ genOpApp a relevant_eq_op b
where
relevant_eq_op = assoc_ty_id eq_op_tbl ty
\end{code}
\begin{code}
+argFieldCount :: Id -> Int -- Works on data and newtype constructors
+argFieldCount con = length (dataConRawArgTys con)
+\end{code}
+
+\begin{code}
untag_Expr :: TyCon -> [(RdrName, RdrName)] -> RdrNameHsExpr -> RdrNameHsExpr
untag_Expr tycon [] expr = expr
untag_Expr tycon ((untag_this, put_tag_here) : more) expr
(GRHSMatch (GRHSsAndBindsIn grhs EmptyBinds))]
mkGeneratedSrcLoc
where
- grhs = [OtherwiseGRHS (untag_Expr tycon more expr) mkGeneratedSrcLoc]
+ grhs = unguardedRHS (untag_Expr tycon more expr) mkGeneratedSrcLoc
cmp_tags_Expr :: RdrName -- Comparison op
-> RdrName -> RdrName -- Things to compare
-> RdrNameHsExpr
cmp_tags_Expr op a b true_case false_case
- = HsIf (HsPar (OpApp (HsVar a) (HsVar op) (HsVar b))) true_case false_case mkGeneratedSrcLoc
+ = HsIf (genOpApp (HsVar a) op (HsVar b)) true_case false_case mkGeneratedSrcLoc
enum_from_to_Expr
:: RdrNameHsExpr -> RdrNameHsExpr
nested_compose_Expr (e:es)
= HsApp (HsApp (HsVar compose_RDR) (parenify e)) (nested_compose_Expr es)
+-- impossible_Expr is used in case RHSs that should never happen.
+-- We generate these to keep the desugarer from complaining that they *might* happen!
+impossible_Expr = HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ "Urk! in TcGenDeriv")))
+
parenify e@(HsVar _) = e
parenify e = HsPar e
+
+-- genOpApp wraps brackets round the operator application, so that the
+-- renamer won't subsequently try to re-associate it.
+-- For some reason the renamer doesn't reassociate it right, and I can't
+-- be bothered to find out why just now.
+
+genOpApp e1 op e2 = mkOpApp e1 op e2
\end{code}
\begin{code}
-qual_orig_name n = case modAndOcc n of { (m,n) -> Qual m n }
+qual_orig_name n = case modAndOcc n of { (m,n) -> Qual m n HiFile }
a_RDR = varUnqual SLIT("a")
b_RDR = varUnqual SLIT("b")
con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon -> RdrName
-con2tag_RDR tycon
- = let (mod, nm) = modAndOcc tycon
- con2tag = SLIT("con2tag_") _APPEND_ occNameString nm _APPEND_ SLIT("#")
- in
- varQual (mod, con2tag)
-
-tag2con_RDR tycon
- = let (mod, nm) = modAndOcc tycon
- tag2con = SLIT("tag2con_") _APPEND_ occNameString nm _APPEND_ SLIT("#")
- in
- varQual (mod, tag2con)
-
-maxtag_RDR tycon
- = let (mod, nm) = modAndOcc tycon
- maxtag = SLIT("maxtag_") _APPEND_ occNameString nm _APPEND_ SLIT("#")
- in
- varQual (mod, maxtag)
+con2tag_RDR tycon = varUnqual (SLIT("con2tag_") _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
+tag2con_RDR tycon = varUnqual (SLIT("tag2con_") _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
+maxtag_RDR tycon = varUnqual (SLIT("maxtag_") _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
\end{code}