diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2015-05-11 23:19:14 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2015-05-18 13:44:15 +0100 |
commit | ffc21506894c7887d3620423aaf86bc6113a1071 (patch) | |
tree | c36353b98b3e5eeb9a257b39d95e56f441aa36da /utils | |
parent | 76024fdbad0f6daedd8757b974eace3314bd4eec (diff) | |
download | haskell-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')
-rw-r--r-- | utils/genprimopcode/Main.hs | 49 | ||||
m--------- | utils/haddock | 0 |
2 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 ++ "))" diff --git a/utils/haddock b/utils/haddock -Subproject 2380f07c430c525b205ce2eae6dab23c8388d89 +Subproject 5a57a24c44e06e964c4ea2276c842c722c4e93d |