Skip to content
This repository was archived by the owner on Aug 3, 2024. It is now read-only.

Commit 6b37fde

Browse files
harpocratesalanz
authored andcommitted
Miscellaneous improvements to Convert (#1020)
Now that Haddock is moving towards working entirely over `.hi` and `.hie` files, all declarations and types are going to be synthesized via the `Convert` module. In preparation for this change, here are a bunch of fixes to this module: * Add kind annotations to type variables in `forall`'s whose kind is not `Type`, unless the kind can be inferred from some later use of the variable. See `implicitForAll` and `noKindTyVars` in particular if you wish to dive into this. * Properly detect `HsQualTy` in `synifyType`. This is done by following suit with what GHC's `toIfaceTypeX` does and checking the first argument of `FunTy{} :: Type` to see if it classified as a given/wanted in the typechecker (see `isPredTy`). * Beef up the logic around figuring out when an explicit `forall` is needed. This includes: observing if any of the type variables will need kind signatures, if the inferred type variable order _without_ a forall will still match the one GHC claims, and some other small things. * Add some (not yet used) functionality for default levity polymorphic type signatures. This functionality similar to `fprint-explicit-runtime-reps`. Couple other smaller fixes only worth mentioning: * Show the family result signature only when it isn't `Type` * Fix rendering of implicit parameters in the LaTeX and Hoogle backends * Better handling of the return kind of polykinded H98 data declarations * Class decls produced by `tyThingToLHsDecl` now contain associated type defaults and default method signatures when appropriate * Filter out more `forall`'s in pattern synonyms
1 parent 8a93973 commit 6b37fde

File tree

11 files changed

+472
-240
lines changed

11 files changed

+472
-240
lines changed

haddock-api/src/Haddock/Backends/Hoogle.hs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,13 @@ ppCtor dflags dat subdocs con@ConDeclH98 {}
263263
-- docs for con_names on why it is a list to begin with.
264264
name = commaSeparate dflags . map unL $ getConNames con
265265

266-
resType = apps $ map (reL . HsTyVar NoExt NotPromoted . reL) $
267-
(tcdName dat) : [hsTyVarName v | L _ v@(UserTyVar _ _) <- hsQTvExplicit $ tyClDeclTyVars dat]
266+
tyVarArg (UserTyVar _ n) = HsTyVar NoExt NotPromoted n
267+
tyVarArg (KindedTyVar _ n lty) = HsKindSig NoExt (reL (HsTyVar NoExt NotPromoted n)) lty
268+
tyVarArg _ = panic "ppCtor"
269+
270+
resType = apps $ map reL $
271+
(HsTyVar NoExt NotPromoted (reL (tcdName dat))) :
272+
map (tyVarArg . unLoc) (hsQTvExplicit $ tyClDeclTyVars dat)
268273

269274
ppCtor dflags _dat subdocs con@(ConDeclGADT { })
270275
= concatMap (lookupCon dflags subdocs) (getConNames con) ++ f

haddock-api/src/Haddock/Backends/LaTeX.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -960,7 +960,7 @@ ppContext cxt unicode = ppContextNoLocs (map unLoc cxt) unicode
960960

961961
pp_hs_context :: [HsType DocNameI] -> Bool -> LaTeX
962962
pp_hs_context [] _ = empty
963-
pp_hs_context [p] unicode = ppType unicode p
963+
pp_hs_context [p] unicode = ppCtxType unicode p
964964
pp_hs_context cxt unicode = parenList (map (ppType unicode) cxt)
965965

966966

@@ -995,11 +995,11 @@ ppLType unicode y = ppType unicode (unLoc y)
995995
ppLParendType unicode y = ppParendType unicode (unLoc y)
996996
ppLFunLhType unicode y = ppFunLhType unicode (unLoc y)
997997

998-
999-
ppType, ppParendType, ppFunLhType :: Bool -> HsType DocNameI -> LaTeX
998+
ppType, ppParendType, ppFunLhType, ppCtxType :: Bool -> HsType DocNameI -> LaTeX
1000999
ppType unicode ty = ppr_mono_ty (reparenTypePrec PREC_TOP ty) unicode
10011000
ppParendType unicode ty = ppr_mono_ty (reparenTypePrec PREC_TOP ty) unicode
10021001
ppFunLhType unicode ty = ppr_mono_ty (reparenTypePrec PREC_FUN ty) unicode
1002+
ppCtxType unicode ty = ppr_mono_ty (reparenTypePrec PREC_CTX ty) unicode
10031003

10041004
ppLHsTypeArg :: Bool -> LHsTypeArg DocNameI -> LaTeX
10051005
ppLHsTypeArg unicode (HsValArg ty) = ppLParendType unicode ty
@@ -1045,7 +1045,7 @@ ppr_mono_ty (HsTupleTy _ con tys) u = tupleParens con (map (ppLType u) tys)
10451045
ppr_mono_ty (HsSumTy _ tys) u = sumParens (map (ppLType u) tys)
10461046
ppr_mono_ty (HsKindSig _ ty kind) u = parens (ppr_mono_lty ty u <+> dcolon u <+> ppLKind u kind)
10471047
ppr_mono_ty (HsListTy _ ty) u = brackets (ppr_mono_lty ty u)
1048-
ppr_mono_ty (HsIParamTy _ (L _ n) ty) u = brackets (ppIPName n <+> dcolon u <+> ppr_mono_lty ty u)
1048+
ppr_mono_ty (HsIParamTy _ (L _ n) ty) u = ppIPName n <+> dcolon u <+> ppr_mono_lty ty u
10491049
ppr_mono_ty (HsSpliceTy {}) _ = error "ppr_mono_ty HsSpliceTy"
10501050
ppr_mono_ty (HsRecTy {}) _ = text "{..}"
10511051
ppr_mono_ty (XHsType (NHsCoreTy {})) _ = error "ppr_mono_ty HsCoreTy"
@@ -1110,7 +1110,7 @@ ppVerbOccName :: OccName -> LaTeX
11101110
ppVerbOccName = text . latexFilter . occNameString
11111111

11121112
ppIPName :: HsIPName -> LaTeX
1113-
ppIPName ip = text $ unpackFS $ hsIPNameFS ip
1113+
ppIPName = text . ('?':) . unpackFS . hsIPNameFS
11141114

11151115
ppOccName :: OccName -> LaTeX
11161116
ppOccName = text . occNameString

haddock-api/src/Haddock/Convert.hs

Lines changed: 322 additions & 143 deletions
Large diffs are not rendered by default.

haddock-api/src/Haddock/GhcUtils.hs

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{-# LANGUAGE BangPatterns, FlexibleInstances, ViewPatterns #-}
1+
{-# LANGUAGE BangPatterns, StandaloneDeriving, FlexibleInstances, ViewPatterns #-}
22
{-# LANGUAGE TypeFamilies #-}
33
{-# LANGUAGE FlexibleContexts #-}
44
{-# OPTIONS_GHC -fno-warn-orphans #-}
@@ -24,6 +24,7 @@ import Data.Char ( isSpace )
2424
import Haddock.Types( DocNameI )
2525

2626
import Exception
27+
import FV
2728
import Outputable ( Outputable, panic, showPpr )
2829
import Name
2930
import NameSet
@@ -33,6 +34,12 @@ import GHC
3334
import Class
3435
import DynFlags
3536
import SrcLoc ( advanceSrcLoc )
37+
import Var ( VarBndr(..), TyVarBinder, tyVarKind, updateTyVarKind,
38+
isInvisibleArgFlag )
39+
import VarSet ( VarSet, emptyVarSet )
40+
import VarEnv ( TyVarEnv, extendVarEnv, elemVarEnv, emptyVarEnv )
41+
import TyCoRep ( Type(..), isRuntimeRepVar )
42+
import TysWiredIn( liftedRepDataConTyCon )
3643

3744
import StringBuffer ( StringBuffer )
3845
import qualified StringBuffer as S
@@ -549,3 +556,104 @@ tryCppLine !loc !buf = spanSpace (S.prevChar buf '\n' == '\n') loc buf
549556

550557
(c , b') -> spanCppLine (advanceSrcLoc l c) b'
551558

559+
-------------------------------------------------------------------------------
560+
-- * Free variables of a 'Type'
561+
-------------------------------------------------------------------------------
562+
563+
-- | Get free type variables in a 'Type' in their order of appearance.
564+
-- See [Ordering of implicit variables].
565+
orderedFVs
566+
:: VarSet -- ^ free variables to ignore
567+
-> [Type] -- ^ types to traverse (in order) looking for free variables
568+
-> [TyVar] -- ^ free type variables, in the order they appear in
569+
orderedFVs vs tys =
570+
reverse . fst $ tyCoFVsOfTypes' tys (const True) vs ([], emptyVarSet)
571+
572+
573+
-- See the "Free variables of types and coercions" section in 'TyCoRep', or
574+
-- check out Note [Free variables of types]. The functions in this section
575+
-- don't output type variables in the order they first appear in in the 'Type'.
576+
--
577+
-- For example, 'tyCoVarsOfTypeList' reports an incorrect order for the type
578+
-- of 'const :: a -> b -> a':
579+
--
580+
-- >>> import Name
581+
-- >>> import TyCoRep
582+
-- >>> import TysPrim
583+
-- >>> import Var
584+
-- >>> a = TyVarTy alphaTyVar
585+
-- >>> b = TyVarTy betaTyVar
586+
-- >>> constTy = mkFunTys [a, b] a
587+
-- >>> map (getOccString . tyVarName) (tyCoVarsOfTypeList constTy)
588+
-- ["b","a"]
589+
--
590+
-- However, we want to reuse the very optimized traversal machinery there, so
591+
-- so we make our own `tyCoFVsOfType'`, `tyCoFVsBndr'`, and `tyCoVarsOfTypes'`.
592+
-- All these do differently is traverse in a different order and ignore
593+
-- coercion variables.
594+
595+
-- | Just like 'tyCoFVsOfType', but traverses type variables in reverse order
596+
-- of appearance.
597+
tyCoFVsOfType' :: Type -> FV
598+
tyCoFVsOfType' (TyVarTy v) a b c = (FV.unitFV v `unionFV` tyCoFVsOfType' (tyVarKind v)) a b c
599+
tyCoFVsOfType' (TyConApp _ tys) a b c = tyCoFVsOfTypes' tys a b c
600+
tyCoFVsOfType' (LitTy {}) a b c = emptyFV a b c
601+
tyCoFVsOfType' (AppTy fun arg) a b c = (tyCoFVsOfType' arg `unionFV` tyCoFVsOfType' fun) a b c
602+
tyCoFVsOfType' (FunTy arg res) a b c = (tyCoFVsOfType' res `unionFV` tyCoFVsOfType' arg) a b c
603+
tyCoFVsOfType' (ForAllTy bndr ty) a b c = tyCoFVsBndr' bndr (tyCoFVsOfType' ty) a b c
604+
tyCoFVsOfType' (CastTy ty _) a b c = (tyCoFVsOfType' ty) a b c
605+
tyCoFVsOfType' (CoercionTy _ ) a b c = emptyFV a b c
606+
607+
-- | Just like 'tyCoFVsOfTypes', but traverses type variables in reverse order
608+
-- of appearance.
609+
tyCoFVsOfTypes' :: [Type] -> FV
610+
tyCoFVsOfTypes' (ty:tys) fv_cand in_scope acc = (tyCoFVsOfTypes' tys `unionFV` tyCoFVsOfType' ty) fv_cand in_scope acc
611+
tyCoFVsOfTypes' [] fv_cand in_scope acc = emptyFV fv_cand in_scope acc
612+
613+
-- | Just like 'tyCoFVsBndr', but traverses type variables in reverse order of
614+
-- appearance.
615+
tyCoFVsBndr' :: TyVarBinder -> FV -> FV
616+
tyCoFVsBndr' (Bndr tv _) fvs = FV.delFV tv fvs `unionFV` tyCoFVsOfType' (tyVarKind tv)
617+
618+
619+
-------------------------------------------------------------------------------
620+
-- * Defaulting RuntimeRep variables
621+
-------------------------------------------------------------------------------
622+
623+
-- | Traverses the type, defaulting type variables of kind 'RuntimeRep' to
624+
-- 'LiftedType'. See 'defaultRuntimeRepVars' in IfaceType.hs the original such
625+
-- function working over `IfaceType`'s.
626+
defaultRuntimeRepVars :: Type -> Type
627+
defaultRuntimeRepVars = go emptyVarEnv
628+
where
629+
go :: TyVarEnv () -> Type -> Type
630+
go subs (ForAllTy (Bndr var flg) ty)
631+
| isRuntimeRepVar var
632+
, isInvisibleArgFlag flg
633+
= let subs' = extendVarEnv subs var ()
634+
in go subs' ty
635+
| otherwise
636+
= ForAllTy (Bndr (updateTyVarKind (go subs) var) flg)
637+
(go subs ty)
638+
639+
go subs (TyVarTy tv)
640+
| tv `elemVarEnv` subs
641+
= TyConApp liftedRepDataConTyCon []
642+
| otherwise
643+
= TyVarTy (updateTyVarKind (go subs) tv)
644+
645+
go subs (TyConApp tc tc_args)
646+
= TyConApp tc (map (go subs) tc_args)
647+
648+
go subs (FunTy arg res)
649+
= FunTy (go subs arg) (go subs res)
650+
651+
go subs (AppTy t u)
652+
= AppTy (go subs t) (go subs u)
653+
654+
go subs (CastTy x co)
655+
= CastTy (go subs x) co
656+
657+
go _ ty@(LitTy {}) = ty
658+
go _ ty@(CoercionTy {}) = ty
659+

haddock-api/src/Haddock/Interface/Create.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,7 +891,7 @@ hiDecl dflags t = do
891891
Nothing -> do
892892
liftErrMsg $ tell ["Warning: Not found in environment: " ++ pretty dflags t]
893893
return Nothing
894-
Just x -> case tyThingToLHsDecl x of
894+
Just x -> case tyThingToLHsDecl ShowRuntimeRep x of
895895
Left m -> liftErrMsg (tell [bugWarn m]) >> return Nothing
896896
Right (m, t') -> liftErrMsg (tell $ map bugWarn m)
897897
>> return (Just $ noLoc t')

hoogle-test/ref/Bug873/test.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module Bug873
2121
-- Note that <tt>(<a>$</a>)</tt> is levity-polymorphic in its result
2222
-- type, so that <tt>foo <a>$</a> True</tt> where <tt>foo :: Bool -&gt;
2323
-- Int#</tt> is well-typed.
24-
($) :: () => (a -> b) -> a -> b
24+
($) :: forall (r :: RuntimeRep) a (b :: TYPE r). (a -> b) -> a -> b
2525
infixr 0 $
2626
($$) :: (a -> b) -> a -> b
2727
infixr 0 $$

html-test/ref/Bug548.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@
148148
><p class="src"
149149
><a href="#"
150150
>from1</a
151-
> :: <a href="#" title="Bug548"
151+
> :: <span class="keyword"
152+
>forall</span
153+
> (a0 :: k). <a href="#" title="Bug548"
152154
>WrappedArrow</a
153155
> a b a0 -&gt; <a href="#" title="GHC.Generics"
154156
>Rep1</a
@@ -160,7 +162,9 @@
160162
><p class="src"
161163
><a href="#"
162164
>to1</a
163-
> :: <a href="#" title="GHC.Generics"
165+
> :: <span class="keyword"
166+
>forall</span
167+
> (a0 :: k). <a href="#" title="GHC.Generics"
164168
>Rep1</a
165169
> (<a href="#" title="Bug548"
166170
>WrappedArrow</a

html-test/ref/Instances.html

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,8 +2038,6 @@
20382038
>Int</a
20392039
> c <a href="#" title="Data.Bool"
20402040
>Bool</a
2041-
> :: <a href="#" title="Data.Kind"
2042-
>Type</a
20432041
> <a href="#" class="selflink"
20442042
>#</a
20452043
></p
@@ -2050,9 +2048,7 @@
20502048
>Thud</a
20512049
> <a href="#" title="Data.Int"
20522050
>Int</a
2053-
> c :: <a href="#" title="Data.Kind"
2054-
>Type</a
2055-
> <a href="#" class="selflink"
2051+
> c <a href="#" class="selflink"
20562052
>#</a
20572053
></p
20582054
></div
@@ -2112,19 +2108,15 @@
21122108
>type</span
21132109
> <a href="#" title="Instances"
21142110
>Plugh</a
2115-
> [a] c [b] :: <a href="#" title="Data.Kind"
2116-
>Type</a
2117-
> <a href="#" class="selflink"
2111+
> [a] c [b] <a href="#" class="selflink"
21182112
>#</a
21192113
></p
21202114
><p class="src"
21212115
><span class="keyword"
21222116
>data</span
21232117
> <a href="#" title="Instances"
21242118
>Thud</a
2125-
> [a] c :: <a href="#" title="Data.Kind"
2126-
>Type</a
2127-
> <a href="#" class="selflink"
2119+
> [a] c <a href="#" class="selflink"
21282120
>#</a
21292121
></p
21302122
></div

html-test/ref/Operators.html

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,7 @@
9696
>pattern</span
9797
> <a href="#"
9898
>(:+)</a
99-
> :: <span class="keyword"
100-
>forall</span
101-
> a. a -&gt; a -&gt; [a]</li
99+
> :: a -&gt; a -&gt; [a]</li
102100
><li class="src short"
103101
><span class="keyword"
104102
>data</span
@@ -285,9 +283,7 @@
285283
>pattern</span
286284
> <a id="v::-43-" class="def"
287285
>(:+)</a
288-
> :: <span class="keyword"
289-
>forall</span
290-
> a. a -&gt; a -&gt; [a] <span class="fixity"
286+
> :: a -&gt; a -&gt; [a] <span class="fixity"
291287
>infixr 3</span
292288
><span class="rightedge"
293289
></span
@@ -529,4 +525,4 @@
529525
></div
530526
></body
531527
></html
532-
>
528+
>

0 commit comments

Comments
 (0)