
Look at how instance declarations are parsed. If you look at Parser.y you’ll see that for
instance (Eq a, Eq b) => Eq (a,b)
we get (in effect)
mkImplicitHsForAllTy (mkQualifiedHsForAllTy (Eq a, Eq b) (Eq (a,b))
The outer mkImplicit.. is to ensure that there is always, in the end, a HsForAllTy around the whole thing, even around
instance Eq a
say.
But we don’t actually want two nested HsForAllTys. mk_forall_ty collapsed the two.
But you don’t want that either. So I think you should make mkImplictHsForAllTy do the test instead. Its goal is to wrap a HsForallTy if there isn’t one already. So
mkImplicitHsForAllTy (HsForAllTy exp tvs cxt ty)
= HsForAllTy exp’ tvs cxt ty
where
exp’ = case exp of
Qualified -> Implicit
_ -> exp
mkImplicitHsForAllTy ty = mkHsForAllTy Implicit [] (L loc _) ty
should do the job.
Incidentally, mkImplicitHsForAllTy should not take a ctxt argument. If you have a non-empty context, use mkQualifiedHsForAllTy. That means that in Convert you’ll need to use
mkHsForAllTy Implicit ctxt ty’
instead of mkImplicitHsForAllTy
Simon
From: Alan & Kim Zimmerman [mailto:alan.zimm@gmail.com]
Sent: 10 April 2015 08:02
To: Simon Peyton Jones
Cc: ghc-devs@haskell.org
Subject: Re: Collapsing HsForAllTy, again
If I replace it with
mkHsForAllTy :: HsExplicitFlag -> [LHsTyVarBndr RdrName] -> LHsContext RdrName -> LHsType RdrName -> HsType RdrName
-- Smart constructor for HsForAllTy
-- mkHsForAllTy exp tvs (L _ []) ty = mk_forall_ty exp tvs ty
mkHsForAllTy exp tvs (L _ []) ty = HsForAllTy exp Nothing (mkHsQTvs tvs) (L noSrcSpan []) ty
mkHsForAllTy exp tvs ctxt ty = HsForAllTy exp extra (mkHsQTvs tvs) cleanCtxt ty
where -- Separate the extra-constraints wildcard when present
(cleanCtxt, extra)
| (L l HsWildcardTy) <- ignoreParens (last (unLoc ctxt)) = (init `fmap` ctxt, Just l)
| otherwise = (ctxt, Nothing)
ignoreParens (L _ (HsParTy ty)) = ty -- TODO:AZ We lose the annotation here
ignoreParens ty = ty
I get the following errors in the stage 2 compile (only first 3 shown here)
libraries/ghc-prim/GHC/Classes.hs:52:19:
Malformed instance: (Eq a, Eq b) => Eq (a, b)
libraries/ghc-prim/GHC/Classes.hs:53:19:
Malformed instance: (Eq a, Eq b, Eq c) => Eq (a, b, c)
libraries/ghc-prim/GHC/Classes.hs:54:19:
Malformed instance: (Eq a, Eq b, Eq c, Eq d) => Eq (a, b, c, d)
Alan
On Fri, Apr 10, 2015 at 12:14 AM, Simon Peyton Jones