summaryrefslogtreecommitdiff
path: root/utils/genprimopcode
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2015-05-11 23:19:14 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2015-05-18 13:44:15 +0100
commitffc21506894c7887d3620423aaf86bc6113a1071 (patch)
treec36353b98b3e5eeb9a257b39d95e56f441aa36da /utils/genprimopcode
parent76024fdbad0f6daedd8757b974eace3314bd4eec (diff)
downloadhaskell-ffc21506894c7887d3620423aaf86bc6113a1071.tar.gz
Refactor tuple constraints
Make tuple constraints be handled by a perfectly ordinary type class, with the component constraints being the superclasses: class (c1, c2) => (c2, c2) This change was provoked by #10359 inability to re-use a given tuple constraint as a whole #9858 confusion between term tuples and constraint tuples but it's generally a very nice simplification. We get rid of - In Type, the TuplePred constructor of PredTree, and all the code that dealt with TuplePreds - In TcEvidence, the constructors EvTupleMk, EvTupleSel See Note [How tuples work] in TysWiredIn. Of course, nothing is ever entirely simple. This one proved quite fiddly. - I did quite a bit of renaming, which makes this patch touch a lot of modules. In partiuclar tupleCon -> tupleDataCon. - I made constraint tuples known-key rather than wired-in. This is different to boxed/unboxed tuples, but it proved awkward to have all the superclass selectors wired-in. Easier just to use the standard mechanims. - While I was fiddling with known-key names, I split the TH Name definitions out of DsMeta into a new module THNames. That meant that the known-key names can all be gathered in PrelInfo, without causing module loops. - I found that the parser was parsing an import item like T( .. ) as a *data constructor* T, and then using setRdrNameSpace to fix it. Stupid! So I changed the parser to parse a *type constructor* T, which means less use of setRdrNameSpace. I also improved setRdrNameSpace to behave better on Exact Names. Largely on priciple; I don't think it matters a lot. - When compiling a data type declaration for a wired-in thing like tuples (,), or lists, we don't really need to look at the declaration. We have the wired-in thing! And not doing so avoids having to line up the uniques for data constructor workers etc. See Note [Declarations for wired-in things] - I found that FunDeps.oclose wasn't taking superclasses into account; easily fixed. - Some error message refactoring for invalid constraints in TcValidity - Haddock needs to absorb the change too; so there is a submodule update
Diffstat (limited to 'utils/genprimopcode')
-rw-r--r--utils/genprimopcode/Main.hs49
1 files changed, 37 insertions, 12 deletions
diff --git a/utils/genprimopcode/Main.hs b/utils/genprimopcode/Main.hs
index 803323fbc0..d8d555cdf2 100644
--- a/utils/genprimopcode/Main.hs
+++ b/utils/genprimopcode/Main.hs
@@ -305,20 +305,13 @@ gen_hs_source (Info defaults entries) =
++ (unlines $ map ("-- " ++ ) $ lines $ unlatex $ escape $ "|" ++ desc s) ++ "\n"
spec o = comm : decls
- where decls = case o of
+ where decls = case o of -- See Note [Placeholder declarations]
PrimOpSpec { name = n, ty = t, opts = options } ->
- [ pprFixity fixity n | OptionFixity (Just fixity) <- options ]
- ++
- [ wrapOp n ++ " :: " ++ pprTy t,
- wrapOp n ++ " = let x = x in x" ]
+ prim_fixity n options ++ prim_decl n t
PrimVecOpSpec { name = n, ty = t, opts = options } ->
- [ pprFixity fixity n | OptionFixity (Just fixity) <- options ]
- ++
- [ wrapOp n ++ " :: " ++ pprTy t,
- wrapOp n ++ " = let x = x in x" ]
+ prim_fixity n options ++ prim_decl n t
PseudoOpSpec { name = n, ty = t } ->
- [ wrapOp n ++ " :: " ++ pprTy t,
- wrapOp n ++ " = let x = x in x" ]
+ prim_decl n t
PrimTypeSpec { ty = t } ->
[ "data " ++ pprTy t ]
PrimVecTypeSpec { ty = t } ->
@@ -329,10 +322,21 @@ gen_hs_source (Info defaults entries) =
[] -> ""
d -> "\n" ++ (unlines $ map ("-- " ++ ) $ lines $ unlatex $ escape $ "|" ++ d)
+ prim_fixity n options = [ pprFixity fixity n | OptionFixity (Just fixity) <- options ]
+
+ prim_decl n t = [ wrapOp n ++ " :: " ++ pprTy t,
+ wrapOp n ++ " = " ++ wrapOpRhs n ]
+
wrapOp nm | isAlpha (head nm) = nm
| otherwise = "(" ++ nm ++ ")"
+
wrapTy nm | isAlpha (head nm) = nm
| otherwise = "(" ++ nm ++ ")"
+
+ wrapOpRhs "tagToEnum#" = "let x = x in x"
+ wrapOpRhs nm = wrapOp nm
+ -- Special case for tagToEnum#: see Note [Placeholder declarations]
+
unlatex s = case s of
'\\':'t':'e':'x':'t':'t':'t':'{':cs -> markup "@" "@" cs
'{':'\\':'t':'t':cs -> markup "@" "@" cs
@@ -349,6 +353,27 @@ gen_hs_source (Info defaults entries) =
pprFixity (Fixity i d) n = pprFixityDir d ++ " " ++ show i ++ " " ++ n
+{- Note [Placeholder declarations]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We are generating fake declarations for things in GHC.Prim, just to
+keep GHC's renamer and typechecker happy enough for what Haddock
+needs. Our main plan is to say
+ foo :: <type>
+ foo = foo
+We have to silence GHC's complaints about unboxed-top-level declarations
+with an ad-hoc fix in TcBinds: see Note [Compiling GHC.Prim] in TcBinds.
+
+That works for all the primitive functions except tagToEnum#.
+If we generate the binding
+ tagToEnum# = tagToEnum#
+GHC will complain about "tagToEnum# must appear applied to one argument".
+We could hack GHC to silence this complaint when compiling GHC.Prim,
+but it seems easier to generate
+ tagToEnum# = let x = x in x
+We don't do this for *all* bindings because for ones with an unboxed
+RHS we would get other complaints (e.g.can't unify "*" with "#").
+-}
+
pprTy :: Ty -> String
pprTy = pty
where
@@ -813,7 +838,7 @@ ppType (TyApp (TyCon "TVar#") [x,y]) = "mkTVarPrimTy " ++ ppType x
ppType (TyApp (VecTyCon _ pptc) []) = pptc
-ppType (TyUTup ts) = "(mkTupleTy UnboxedTuple "
+ppType (TyUTup ts) = "(mkTupleTy Unboxed "
++ listify (map ppType ts) ++ ")"
ppType (TyF s d) = "(mkFunTy (" ++ ppType s ++ ") (" ++ ppType d ++ "))"