diff options
| author | Ryan Scott <ryan.gl.scott@gmail.com> | 2019-10-23 09:42:20 -0400 | 
|---|---|---|
| committer | Alec Theriault <alec.theriault@gmail.com> | 2019-10-23 10:37:17 -0400 | 
| commit | 2a5fc0ad50c857098558461434c29abd478ea0a1 (patch) | |
| tree | 0c1b0312461b6e23380e73d5187747d50970cb8f | |
| parent | cdf4445a877428f5969f712a95830af38029b9a0 (diff) | |
Reify oversaturated data family instances correctly (#1103)
This fixes #1103 by adapting the corresponding patch for GHC (see
https://gitlab.haskell.org/ghc/ghc/issues/17296 and
https://gitlab.haskell.org/ghc/ghc/merge_requests/1877).
| -rw-r--r-- | haddock-api/src/Haddock/Convert.hs | 38 | ||||
| -rw-r--r-- | html-test/ref/Bug1103.html | 556 | ||||
| -rw-r--r-- | html-test/src/Bug1103.hs | 24 | 
3 files changed, 603 insertions, 15 deletions
| diff --git a/haddock-api/src/Haddock/Convert.hs b/haddock-api/src/Haddock/Convert.hs index d22efc9a..5dc3a508 100644 --- a/haddock-api/src/Haddock/Convert.hs +++ b/haddock-api/src/Haddock/Convert.hs @@ -150,8 +150,7 @@ synifyAxBranch tc (CoAxBranch { cab_tvs = tkvs, cab_lhs = args, cab_rhs = rhs })    = let name            = synifyName tc          args_types_only = filterOutInvisibleTypes tc args          typats          = map (synifyType WithinType []) args_types_only -        annot_typats    = zipWith3 annotHsType (mkIsPolyTvs fam_tvs) -                                   args_types_only typats +        annot_typats    = zipWith3 annotHsType args_poly args_types_only typats          hs_rhs          = synifyType WithinType [] rhs      in HsIB { hsib_ext = map tyVarName tkvs              , hsib_body   = FamEqn { feqn_ext    = noExt @@ -162,7 +161,7 @@ synifyAxBranch tc (CoAxBranch { cab_tvs = tkvs, cab_lhs = args, cab_rhs = rhs })                                     , feqn_fixity = synifyFixity name                                     , feqn_rhs    = hs_rhs } }    where -    fam_tvs = tyConVisibleTyVars tc +    args_poly = tyConArgsPolyKinded tc  synifyAxiom :: CoAxiom br -> Either ErrMsg (HsDecl GhcRn)  synifyAxiom ax@(CoAxiom { co_ax_tc = tc }) @@ -472,17 +471,26 @@ annotHsType True ty hs_ty      in noLoc (HsKindSig noExt hs_ty hs_ki)  annotHsType _    _ hs_ty = hs_ty --- | For every type variable in the input, --- report whether or not the tv is poly-kinded. This is used to eventually --- feed into 'annotHsType'. -mkIsPolyTvs :: [TyVar] -> [Bool] -mkIsPolyTvs = map is_poly_tv +-- | For every argument type that a type constructor accepts, +-- report whether or not the argument is poly-kinded. This is used to +-- eventually feed into 'annotThType'. +tyConArgsPolyKinded :: TyCon -> [Bool] +tyConArgsPolyKinded tc = +     map (is_poly_ty . tyVarKind)      tc_vis_tvs +  ++ map (is_poly_ty . tyCoBinderType) tc_res_kind_vis_bndrs +  ++ repeat True    where -    is_poly_tv tv = not $ +    is_poly_ty :: Type -> Bool +    is_poly_ty ty = not $                      isEmptyVarSet $                      filterVarSet isTyVar $ -                    tyCoVarsOfType $ -                    tyVarKind tv +                    tyCoVarsOfType ty + +    tc_vis_tvs :: [TyVar] +    tc_vis_tvs = tyConVisibleTyVars tc + +    tc_res_kind_vis_bndrs :: [TyCoBinder] +    tc_res_kind_vis_bndrs = filter isVisibleBinder $ fst $ splitPiTys $ tyConResKind tc  --states of what to do with foralls:  data SynifyTypeState @@ -787,8 +795,8 @@ synifyInstHead (vs, preds, cls, types) = specializeInstHead $ InstHead      cls_tycon = classTyCon cls      ts  = filterOutInvisibleTypes cls_tycon types      ts' = map (synifyType WithinType vs) ts -    annot_ts = zipWith3 annotHsType is_poly_tvs ts ts' -    is_poly_tvs = mkIsPolyTvs (tyConVisibleTyVars cls_tycon) +    annot_ts = zipWith3 annotHsType args_poly ts ts' +    args_poly = tyConArgsPolyKinded cls_tycon      synifyClsIdSig = synifyIdSig ShowRuntimeRep DeleteTopLevelQuantification vs  -- Convert a family instance, this could be a type family or data family @@ -827,8 +835,8 @@ synifyFamInst fi opaque = do      ts = filterOutInvisibleTypes fam_tc eta_expanded_lhs      synifyTypes = map (synifyType WithinType [])      ts' = synifyTypes ts -    annot_ts = zipWith3 annotHsType is_poly_tvs ts ts' -    is_poly_tvs = mkIsPolyTvs (tyConVisibleTyVars fam_tc) +    annot_ts = zipWith3 annotHsType args_poly ts ts' +    args_poly = tyConArgsPolyKinded fam_tc  {-  Note [Invariant: Never expand type synonyms] diff --git a/html-test/ref/Bug1103.html b/html-test/ref/Bug1103.html new file mode 100644 index 00000000..cc16017b --- /dev/null +++ b/html-test/ref/Bug1103.html @@ -0,0 +1,556 @@ +<html xmlns="http://www.w3.org/1999/xhtml" +><head +  ><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" +     /><meta name="viewport" content="width=device-width, initial-scale=1" +     /><title +    >Bug1103</title +    ><link href="#" rel="stylesheet" type="text/css" title="Linuwial" +     /><link rel="stylesheet" type="text/css" href="#" +     /><link rel="stylesheet" type="text/css" href="#" +     /><script src="haddock-bundle.min.js" async="async" type="text/javascript" +    ></script +    ><script type="text/x-mathjax-config" +    >MathJax.Hub.Config({ tex2jax: { processClass: "mathjax", ignoreClass: ".*" } });</script +    ><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript" +    ></script +    ></head +  ><body +  ><div id="package-header" +    ><span class="caption empty" +      ></span +      ><ul class="links" id="page-menu" +      ><li +	><a href="#" +	  >Contents</a +	  ></li +	><li +	><a href="#" +	  >Index</a +	  ></li +	></ul +      ></div +    ><div id="content" +    ><div id="module-header" +      ><table class="info" +	><tr +	  ><th +	    >Safe Haskell</th +	    ><td +	    >Safe</td +	    ></tr +	  ></table +	><p class="caption" +	>Bug1103</p +	></div +      ><div id="interface" +      ><h1 +	>Documentation</h1 +	><div class="top" +	><p class="src" +	  ><span class="keyword" +	    >data family</span +	    > <a id="t:Foo1" class="def" +	    >Foo1</a +	    > :: <a href="#" title="Data.Kind" +	    >Type</a +	    > -> <a href="#" title="Data.Kind" +	    >Type</a +	    > <a href="#" class="selflink" +	    >#</a +	    ></p +	  ><div class="subs instances" +	  ><h4 class="instances details-toggle-control details-toggle" data-details-id="i:Foo1" +	    >Instances</h4 +	    ><details id="i:Foo1" open="open" +	    ><summary class="hide-when-js-enabled" +	      >Instances details</summary +	      ><table +	      ><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo1:Foo1:1" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo1</a +		      > <a href="#" title="Data.Bool" +		      >Bool</a +		      ></span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo1:Foo1:1" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo1</a +			> <a href="#" title="Data.Bool" +			>Bool</a +			> = <a id="v:Foo1Bool" class="def" +			>Foo1Bool</a +			></div +		      ></details +		    ></td +		  ></tr +		><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo1:Foo1:2" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo1</a +		      > (<a href="#" title="Data.Maybe" +		      >Maybe</a +		      > a)</span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo1:Foo1:2" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo1</a +			> (<a href="#" title="Data.Maybe" +			>Maybe</a +			> a)</div +		      ></details +		    ></td +		  ></tr +		></table +	      ></details +	    ></div +	  ></div +	><div class="top" +	><p class="src" +	  ><span class="keyword" +	    >data family</span +	    > <a id="t:Foo2" class="def" +	    >Foo2</a +	    > :: k -> <a href="#" title="Data.Kind" +	    >Type</a +	    > <a href="#" class="selflink" +	    >#</a +	    ></p +	  ><div class="subs instances" +	  ><h4 class="instances details-toggle-control details-toggle" data-details-id="i:Foo2" +	    >Instances</h4 +	    ><details id="i:Foo2" open="open" +	    ><summary class="hide-when-js-enabled" +	      >Instances details</summary +	      ><table +	      ><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo2:Foo2:1" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo2</a +		      > (a :: <a href="#" title="Data.Char" +		      >Char</a +		      >)</span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo2:Foo2:1" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo2</a +			> (a :: <a href="#" title="Data.Char" +			>Char</a +			>)</div +		      ></details +		    ></td +		  ></tr +		><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo2:Foo2:2" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo2</a +		      > <a href="#" title="Data.Bool" +		      >Bool</a +		      ></span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo2:Foo2:2" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo2</a +			> <a href="#" title="Data.Bool" +			>Bool</a +			> = <a id="v:Foo2Bool" class="def" +			>Foo2Bool</a +			></div +		      ></details +		    ></td +		  ></tr +		><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo2:Foo2:3" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo2</a +		      > (<a href="#" title="Data.Maybe" +		      >Maybe</a +		      > a :: <a href="#" title="Data.Kind" +		      >Type</a +		      >)</span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo2:Foo2:3" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo2</a +			> (<a href="#" title="Data.Maybe" +			>Maybe</a +			> a :: <a href="#" title="Data.Kind" +			>Type</a +			>)</div +		      ></details +		    ></td +		  ></tr +		><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo2:Foo2:4" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo2</a +		      > (a :: <a href="#" title="Data.Char" +		      >Char</a +		      > -> <a href="#" title="Data.Char" +		      >Char</a +		      >)</span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo2:Foo2:4" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo2</a +			> (a :: <a href="#" title="Data.Char" +			>Char</a +			> -> <a href="#" title="Data.Char" +			>Char</a +			>)</div +		      ></details +		    ></td +		  ></tr +		></table +	      ></details +	    ></div +	  ></div +	><div class="top" +	><p class="src" +	  ><span class="keyword" +	    >data family</span +	    > <a id="t:Foo3" class="def" +	    >Foo3</a +	    > :: k <a href="#" class="selflink" +	    >#</a +	    ></p +	  ><div class="subs instances" +	  ><h4 class="instances details-toggle-control details-toggle" data-details-id="i:Foo3" +	    >Instances</h4 +	    ><details id="i:Foo3" open="open" +	    ><summary class="hide-when-js-enabled" +	      >Instances details</summary +	      ><table +	      ><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo3:Foo3:1" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo3</a +		      ></span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo3:Foo3:1" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo3</a +			></div +		      ></details +		    ></td +		  ></tr +		><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo3:Foo3:2" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo3</a +		      > (a :: <a href="#" title="Data.Char" +		      >Char</a +		      >)</span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo3:Foo3:2" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo3</a +			> (a :: <a href="#" title="Data.Char" +			>Char</a +			>)</div +		      ></details +		    ></td +		  ></tr +		><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo3:Foo3:3" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo3</a +		      > (a :: <a href="#" title="Data.Char" +		      >Char</a +		      > -> <a href="#" title="Data.Char" +		      >Char</a +		      >)</span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo3:Foo3:3" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo3</a +			> (a :: <a href="#" title="Data.Char" +			>Char</a +			> -> <a href="#" title="Data.Char" +			>Char</a +			>)</div +		      ></details +		    ></td +		  ></tr +		><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo3:Foo3:4" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo3</a +		      > <a href="#" title="Data.Bool" +		      >Bool</a +		      ></span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo3:Foo3:4" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo3</a +			> <a href="#" title="Data.Bool" +			>Bool</a +			> = <a id="v:Foo3Bool" class="def" +			>Foo3Bool</a +			></div +		      ></details +		    ></td +		  ></tr +		><tr +		><td class="src clearfix" +		  ><span class="inst-left" +		    ><span class="instance details-toggle-control details-toggle" data-details-id="i:if:Foo3:Foo3:5" +		      ></span +		      > <span class="keyword" +		      >data</span +		      > <a href="#" title="Bug1103" +		      >Foo3</a +		      > (<a href="#" title="Data.Maybe" +		      >Maybe</a +		      > a :: <a href="#" title="Data.Kind" +		      >Type</a +		      >)</span +		    > <a href="#" class="selflink" +		    >#</a +		    ></td +		  ><td class="doc empty" +		  ></td +		  ></tr +		><tr +		><td colspan="2" +		  ><details id="i:if:Foo3:Foo3:5" +		    ><summary class="hide-when-js-enabled" +		      >Instance details</summary +		      ><p +		      >Defined in <a href="#" +			>Bug1103</a +			></p +		      > <div class="src" +		      ><span class="keyword" +			>data</span +			> <a href="#" title="Bug1103" +			>Foo3</a +			> (<a href="#" title="Data.Maybe" +			>Maybe</a +			> a :: <a href="#" title="Data.Kind" +			>Type</a +			>)</div +		      ></details +		    ></td +		  ></tr +		></table +	      ></details +	    ></div +	  ></div +	></div +      ></div +    ><div id="footer" +    ></div +    ></body +  ></html +>
\ No newline at end of file diff --git a/html-test/src/Bug1103.hs b/html-test/src/Bug1103.hs new file mode 100644 index 00000000..1f387e62 --- /dev/null +++ b/html-test/src/Bug1103.hs @@ -0,0 +1,24 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeFamilies #-} +module Bug1103 where + +import Data.Kind + +data family   Foo1 :: Type -> Type +data instance Foo1 Bool = Foo1Bool +data instance Foo1 (Maybe a) + +data family   Foo2 :: k -> Type +data instance Foo2 Bool = Foo2Bool +data instance Foo2 (Maybe a) +data instance Foo2 :: Char -> Type +data instance Foo2 :: (Char -> Char) -> Type where + +data family   Foo3 :: k +data instance Foo3 +data instance Foo3 Bool = Foo3Bool +data instance Foo3 (Maybe a) +data instance Foo3 :: Char -> Type +data instance Foo3 :: (Char -> Char) -> Type where | 
