summaryrefslogtreecommitdiff
path: root/compiler/GHC/Hs/Decls.hs
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2020-07-05 16:15:01 -0400
committerRyan Scott <ryan.gl.scott@gmail.com>2020-10-30 19:38:31 -0400
commite9b2578fa17989f13ec6ba8fae0c35b2dac4d900 (patch)
tree2032245a504f20b62c0980cd84208673f45c2ac4 /compiler/GHC/Hs/Decls.hs
parent31fcb55f4ff8c06c5ab100a6817cae8b571295a9 (diff)
downloadhaskell-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.hs86
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