diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2020-07-05 16:15:01 -0400 |
---|---|---|
committer | Ryan Scott <ryan.gl.scott@gmail.com> | 2020-10-30 19:38:31 -0400 |
commit | e9b2578fa17989f13ec6ba8fae0c35b2dac4d900 (patch) | |
tree | 2032245a504f20b62c0980cd84208673f45c2ac4 /compiler/GHC/Hs/Decls.hs | |
parent | 31fcb55f4ff8c06c5ab100a6817cae8b571295a9 (diff) | |
download | haskell-wip/T16762.tar.gz |
Replace HsImplicitBndrs with HsOuterTyVarBndrswip/T16762
This refactors the GHC AST to remove `HsImplicitBndrs` and replace it with
`HsOuterTyVarBndrs`, a type which records whether the outermost quantification
in a type is explicit (i.e., with an outermost, invisible `forall`) or
implicit. As a result of this refactoring, it is now evident in the AST where
the `forall`-or-nothing rule applies: it's all the places that use
`HsOuterTyVarBndrs`. See the revamped `Note [forall-or-nothing rule]` in
`GHC.Hs.Type` (previously in `GHC.Rename.HsType`).
Moreover, the places where `ScopedTypeVariables` brings lexically scoped type
variables into scope are a subset of the places that adhere to the
`forall`-or-nothing rule, so this also makes places that interact with
`ScopedTypeVariables` easier to find. See the revamped
`Note [Lexically scoped type variables]` in `GHC.Hs.Type` (previously in
`GHC.Tc.Gen.Sig`).
`HsOuterTyVarBndrs` are used in type signatures (see `HsOuterSigTyVarBndrs`)
and type family equations (see `HsOuterFamEqnTyVarBndrs`). The main difference
between the former and the latter is that the former cares about specificity
but the latter does not.
There are a number of knock-on consequences:
* There is now a dedicated `HsSigType` type, which is the combination of
`HsOuterSigTyVarBndrs` and `HsType`. `LHsSigType` is now an alias for an
`XRec` of `HsSigType`.
* Working out the details led us to a substantial refactoring of
the handling of explicit (user-written) and implicit type-variable
bindings in `GHC.Tc.Gen.HsType`.
Instead of a confusing family of higher order functions, we now
have a local data type, `SkolemInfo`, that controls how these
binders are kind-checked.
It remains very fiddly, not fully satisfying. But it's better
than it was.
Fixes #16762. Bumps the Haddock submodule.
Co-authored-by: Simon Peyton Jones <simonpj@microsoft.com>
Co-authored-by: Richard Eisenberg <rae@richarde.dev>
Co-authored-by: Zubin Duggal <zubin@cmi.ac.in>
Diffstat (limited to 'compiler/GHC/Hs/Decls.hs')
-rw-r--r-- | compiler/GHC/Hs/Decls.hs | 86 |
1 files changed, 33 insertions, 53 deletions
diff --git a/compiler/GHC/Hs/Decls.hs b/compiler/GHC/Hs/Decls.hs index 2024b61b81..dcb810ed7e 100644 --- a/compiler/GHC/Hs/Decls.hs +++ b/compiler/GHC/Hs/Decls.hs @@ -50,8 +50,7 @@ module GHC.Hs.Decls ( TyFamDefltDecl, LTyFamDefltDecl, DataFamInstDecl(..), LDataFamInstDecl, pprDataFamInstFlavour, pprTyFamInstDecl, pprHsFamInstLHS, - FamInstEqn, LFamInstEqn, FamEqn(..), - TyFamInstEqn, LTyFamInstEqn, HsTyPats, + FamEqn(..), TyFamInstEqn, LTyFamInstEqn, HsTyPats, LClsInstDecl, ClsInstDecl(..), -- ** Standalone deriving declarations @@ -759,8 +758,7 @@ tyFamInstDeclName :: TyFamInstDecl (GhcPass p) -> IdP (GhcPass p) tyFamInstDeclName = unLoc . tyFamInstDeclLName tyFamInstDeclLName :: TyFamInstDecl (GhcPass p) -> Located (IdP (GhcPass p)) -tyFamInstDeclLName (TyFamInstDecl { tfid_eqn = - (HsIB { hsib_body = FamEqn { feqn_tycon = ln }}) }) +tyFamInstDeclLName (TyFamInstDecl { tfid_eqn = FamEqn { feqn_tycon = ln }}) = ln tyClDeclLName :: TyClDecl (GhcPass p) -> Located (IdP (GhcPass p)) @@ -1467,15 +1465,9 @@ data ConDecl pass -- The following fields describe the type after the '::' -- See Note [GADT abstract syntax] - , con_forall :: XRec pass Bool -- ^ True <=> explicit forall - -- False => hsq_explicit is empty - -- - -- The 'XRec' is used to anchor API - -- annotations, AnnForall and AnnDot. - , con_qvars :: [LHsTyVarBndr Specificity pass] - -- Whether or not there is an /explicit/ forall, we still - -- need to capture the implicitly-bound type/kind variables - + , con_bndrs :: XRec pass (HsOuterSigTyVarBndrs pass) + -- ^ The outermost type variable binders, be they explicit or implicit. + -- The 'XRec' is used to anchor API annotations, AnnForall and AnnDot. , con_mb_cxt :: Maybe (LHsContext pass) -- ^ User-written context (if any) , con_g_args :: HsConDeclGADTDetails pass -- ^ Arguments; never infix , con_res_ty :: LHsType pass -- ^ Result type @@ -1502,10 +1494,7 @@ data ConDecl pass } | XConDecl !(XXConDecl pass) -type instance XConDeclGADT GhcPs = NoExtField -type instance XConDeclGADT GhcRn = [Name] -- Implicitly bound type variables -type instance XConDeclGADT GhcTc = NoExtField - +type instance XConDeclGADT (GhcPass _) = NoExtField type instance XConDeclH98 (GhcPass _) = NoExtField type instance XXConDecl (GhcPass _) = NoExtCon @@ -1733,11 +1722,11 @@ pprConDecl (ConDeclH98 { con_name = L _ con <+> pprConDeclFields (unLoc fields) cxt = fromMaybe noLHsContext mcxt -pprConDecl (ConDeclGADT { con_names = cons, con_qvars = qvars +pprConDecl (ConDeclGADT { con_names = cons, con_bndrs = L _ outer_bndrs , con_mb_cxt = mcxt, con_g_args = args , con_res_ty = res_ty, con_doc = doc }) = ppr_mbDoc doc <+> ppr_con_names cons <+> dcolon - <+> (sep [pprHsForAll (mkHsForAllInvisTele qvars) cxt, + <+> (sep [pprHsOuterSigTyVarBndrs outer_bndrs <+> pprLHsContext cxt, ppr_arrow_chain (get_args args ++ [ppr res_ty]) ]) where get_args (PrefixConGADT args) = map ppr args @@ -1796,26 +1785,23 @@ type HsTyPats pass = [LHsTypeArg pass] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The feqn_pats field of FamEqn (family instance equation) stores the LHS type (and kind) patterns. Any type (and kind) variables contained -in these type patterns are bound in the hsib_vars field of the HsImplicitBndrs -in FamInstEqn depending on whether or not an explicit forall is present. In -the case of an explicit forall, the hsib_vars only includes kind variables not -bound in the forall. Otherwise, all type (and kind) variables are bound in -the hsib_vars. In the latter case, note that in particular +in these type patterns are bound in the feqn_bndrs field. +Note that in particular: -* The hsib_vars *includes* any anonymous wildcards. For example +* The feqn_bndrs *include* any anonymous wildcards. For example type instance F a _ = a - The hsib_vars will be {a, _}. Remember that each separate wildcard - '_' gets its own unique. In this context wildcards behave just like + The feqn_bndrs will be HsOuterImplicit {a, _}. Remember that each separate + wildcard '_' gets its own unique. In this context wildcards behave just like an ordinary type variable, only anonymous. -* The hsib_vars *includes* type variables that are already in scope +* The feqn_bndrs *include* type variables that are already in scope Eg class C s t where type F t p :: * instance C w (a,b) where type F (a,b) x = x->a - The hsib_vars of the F decl are {a,b,x}, even though the F decl - is nested inside the 'instance' decl. + The feqn_bndrs of the F decl is HsOuterImplicit {a,b,x}, even though the + F decl is nested inside the 'instance' decl. However after the renamer, the uniques will match up: instance C w7 (a8,b9) where @@ -1827,7 +1813,9 @@ c.f. Note [TyVar binders for associated decls] -} -- | Type Family Instance Equation -type TyFamInstEqn pass = FamInstEqn pass (LHsType pass) +type TyFamInstEqn pass = FamEqn pass (LHsType pass) + -- Here, the @pats@ are type patterns (with kind and type bndrs). + -- See Note [Family instance declaration binders] -- | Type family default declarations. -- A convenient synonym for 'TyFamInstDecl'. @@ -1855,7 +1843,7 @@ type LDataFamInstDecl pass = XRec pass (DataFamInstDecl pass) -- | Data Family Instance Declaration newtype DataFamInstDecl pass - = DataFamInstDecl { dfid_eqn :: FamInstEqn pass (HsDataDefn pass) } + = DataFamInstDecl { dfid_eqn :: FamEqn pass (HsDataDefn pass) } -- ^ -- - 'GHC.Parser.Annotation.AnnKeywordId' : 'GHC.Parser.Annotation.AnnData', -- 'GHC.Parser.Annotation.AnnNewType','GHC.Parser.Annotation.AnnInstance', @@ -1867,14 +1855,6 @@ newtype DataFamInstDecl pass ----------------- Family instances (common types) ------------- --- | Located Family Instance Equation -type LFamInstEqn pass rhs = XRec pass (FamInstEqn pass rhs) - --- | Family Instance Equation -type FamInstEqn pass rhs = HsImplicitBndrs pass (FamEqn pass rhs) - -- ^ Here, the @pats@ are type patterns (with kind and type bndrs). - -- See Note [Family instance declaration binders] - -- | Family Equation -- -- One equation in a type family instance declaration, data family instance @@ -1885,7 +1865,7 @@ data FamEqn pass rhs = FamEqn { feqn_ext :: XCFamEqn pass rhs , feqn_tycon :: LIdP pass - , feqn_bndrs :: Maybe [LHsTyVarBndr () pass] -- ^ Optional quantified type vars + , feqn_bndrs :: HsOuterFamEqnTyVarBndrs pass -- ^ Optional quantified type vars , feqn_pats :: HsTyPats pass , feqn_fixity :: LexicalFixity -- ^ Fixity used in the declaration , feqn_rhs :: rhs @@ -1974,11 +1954,11 @@ pprTyFamDefltDecl = pprTyFamInstDecl NotTopLevel ppr_fam_inst_eqn :: (OutputableBndrId p) => TyFamInstEqn (GhcPass p) -> SDoc -ppr_fam_inst_eqn (HsIB { hsib_body = FamEqn { feqn_tycon = L _ tycon - , feqn_bndrs = bndrs - , feqn_pats = pats - , feqn_fixity = fixity - , feqn_rhs = rhs }}) +ppr_fam_inst_eqn (FamEqn { feqn_tycon = L _ tycon + , feqn_bndrs = bndrs + , feqn_pats = pats + , feqn_fixity = fixity + , feqn_rhs = rhs }) = pprHsFamInstLHS tycon bndrs pats fixity noLHsContext <+> equals <+> ppr rhs instance OutputableBndrId p @@ -1987,12 +1967,12 @@ instance OutputableBndrId p pprDataFamInstDecl :: (OutputableBndrId p) => TopLevelFlag -> DataFamInstDecl (GhcPass p) -> SDoc -pprDataFamInstDecl top_lvl (DataFamInstDecl { dfid_eqn = HsIB { hsib_body = - FamEqn { feqn_tycon = L _ tycon +pprDataFamInstDecl top_lvl (DataFamInstDecl { dfid_eqn = + (FamEqn { feqn_tycon = L _ tycon , feqn_bndrs = bndrs , feqn_pats = pats , feqn_fixity = fixity - , feqn_rhs = defn }}}) + , feqn_rhs = defn })}) = pp_data_defn pp_hdr defn where pp_hdr ctxt = ppr_instance_keyword top_lvl @@ -2000,19 +1980,19 @@ pprDataFamInstDecl top_lvl (DataFamInstDecl { dfid_eqn = HsIB { hsib_body = -- pp_data_defn pretty-prints the kind sig. See #14817. pprDataFamInstFlavour :: DataFamInstDecl (GhcPass p) -> SDoc -pprDataFamInstFlavour (DataFamInstDecl { dfid_eqn = HsIB { hsib_body = - FamEqn { feqn_rhs = HsDataDefn { dd_ND = nd }}}}) +pprDataFamInstFlavour (DataFamInstDecl { dfid_eqn = + (FamEqn { feqn_rhs = HsDataDefn { dd_ND = nd }})}) = ppr nd pprHsFamInstLHS :: (OutputableBndrId p) => IdP (GhcPass p) - -> Maybe [LHsTyVarBndr () (GhcPass p)] + -> HsOuterFamEqnTyVarBndrs (GhcPass p) -> HsTyPats (GhcPass p) -> LexicalFixity -> LHsContext (GhcPass p) -> SDoc pprHsFamInstLHS thing bndrs typats fixity mb_ctxt - = hsep [ pprHsExplicitForAll bndrs + = hsep [ pprHsOuterFamEqnTyVarBndrs bndrs , pprLHsContext mb_ctxt , pp_pats typats ] where |