summaryrefslogtreecommitdiff
path: root/compiler/hsSyn
diff options
context:
space:
mode:
authorRichard Eisenberg <eir@cis.upenn.edu>2014-08-07 08:37:05 -0400
committerRichard Eisenberg <eir@cis.upenn.edu>2014-08-12 11:46:21 -0400
commit578377cec76d702da3714d4d6fe402b76de5aa7f (patch)
treeb161fc3308eaa603860d512ed79c22455378d2ce /compiler/hsSyn
parentb2c61670fced7a59d19c0665de23d38984f8d01c (diff)
downloadhaskell-578377cec76d702da3714d4d6fe402b76de5aa7f.tar.gz
Remove NonParametricKinds (#9200)
This commit also removes 'KindCheckingStrategy' and related gubbins, instead including the notion of a CUSK into HsDecls.
Diffstat (limited to 'compiler/hsSyn')
-rw-r--r--compiler/hsSyn/HsDecls.lhs48
-rw-r--r--compiler/hsSyn/HsTypes.lhs6
2 files changed, 53 insertions, 1 deletions
diff --git a/compiler/hsSyn/HsDecls.lhs b/compiler/hsSyn/HsDecls.lhs
index 313dccccd5..9680c89e9b 100644
--- a/compiler/hsSyn/HsDecls.lhs
+++ b/compiler/hsSyn/HsDecls.lhs
@@ -23,6 +23,7 @@ module HsDecls (
tyFamInstDeclName, tyFamInstDeclLName,
countTyClDecls, pprTyClDeclFlavour,
tyClDeclLName, tyClDeclTyVars,
+ hsDeclHasCusk, famDeclHasCusk,
FamilyDecl(..), LFamilyDecl,
-- ** Instance declarations
@@ -93,6 +94,7 @@ import Bag
import Data.Data hiding (TyCon)
import Data.Foldable (Foldable)
import Data.Traversable
+import Data.Maybe
\end{code}
%************************************************************************
@@ -604,8 +606,54 @@ countTyClDecls decls
isNewTy DataDecl{ tcdDataDefn = HsDataDefn { dd_ND = NewType } } = True
isNewTy _ = False
+
+-- | Does this declaration have a complete, user-supplied kind signature?
+-- See Note [Complete user-supplied kind signatures]
+hsDeclHasCusk :: TyClDecl name -> Bool
+hsDeclHasCusk (ForeignType {}) = True
+hsDeclHasCusk (FamDecl { tcdFam = fam_decl }) = famDeclHasCusk fam_decl
+hsDeclHasCusk (SynDecl { tcdTyVars = tyvars, tcdRhs = rhs })
+ = hsTvbAllKinded tyvars && rhs_annotated rhs
+ where
+ rhs_annotated (L _ ty) = case ty of
+ HsParTy lty -> rhs_annotated lty
+ HsKindSig {} -> True
+ _ -> False
+hsDeclHasCusk (DataDecl { tcdTyVars = tyvars }) = hsTvbAllKinded tyvars
+hsDeclHasCusk (ClassDecl { tcdTyVars = tyvars }) = hsTvbAllKinded tyvars
+
+-- | Does this family declaration have a complete, user-supplied kind signature?
+famDeclHasCusk :: FamilyDecl name -> Bool
+famDeclHasCusk (FamilyDecl { fdInfo = ClosedTypeFamily _
+ , fdTyVars = tyvars
+ , fdKindSig = m_sig })
+ = hsTvbAllKinded tyvars && isJust m_sig
+famDeclHasCusk _ = True -- all open families have CUSKs!
\end{code}
+Note [Complete user-supplied kind signatures]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We kind-check declarations differently if they have a complete, user-supplied
+kind signature (CUSK). This is because we can safely generalise a CUSKed
+declaration before checking all of the others, supporting polymorphic recursion.
+See https://ghc.haskell.org/trac/ghc/wiki/GhcKinds/KindInference#Proposednewstrategy
+and #9200 for lots of discussion of how we got here.
+
+A declaration has a CUSK if we can know its complete kind without doing any inference,
+at all. Here are the rules:
+
+ - A class or datatype is said to have a CUSK if and only if all of its type
+variables are annotated. Its result kind is, by construction, Constraint or *
+respectively.
+
+ - A type synonym has a CUSK if and only if all of its type variables and its
+RHS are annotated with kinds.
+
+ - A closed type family is said to have a CUSK if and only if all of its type
+variables and its return type are annotated.
+
+ - An open type family always has a CUSK -- unannotated type variables (and return type) default to *.
+
\begin{code}
instance OutputableBndr name
=> Outputable (TyClDecl name) where
diff --git a/compiler/hsSyn/HsTypes.lhs b/compiler/hsSyn/HsTypes.lhs
index eada762738..0cf8455bad 100644
--- a/compiler/hsSyn/HsTypes.lhs
+++ b/compiler/hsSyn/HsTypes.lhs
@@ -25,7 +25,7 @@ module HsTypes (
ConDeclField(..), pprConDeclFields,
- mkHsQTvs, hsQTvBndrs, isHsKindedTyVar,
+ mkHsQTvs, hsQTvBndrs, isHsKindedTyVar, hsTvbAllKinded,
mkExplicitHsForAllTy, mkImplicitHsForAllTy, hsExplicitTvs,
hsTyVarName, mkHsWithBndrs, hsLKiTyVarNames,
hsLTyVarName, hsLTyVarNames, hsLTyVarLocName, hsLTyVarLocNames,
@@ -193,6 +193,10 @@ isHsKindedTyVar :: HsTyVarBndr name -> Bool
isHsKindedTyVar (UserTyVar {}) = False
isHsKindedTyVar (KindedTyVar {}) = True
+-- | Do all type variables in this 'LHsTyVarBndr' come with kind annotations?
+hsTvbAllKinded :: LHsTyVarBndrs name -> Bool
+hsTvbAllKinded = all (isHsKindedTyVar . unLoc) . hsQTvBndrs
+
data HsType name
= HsForAllTy HsExplicitFlag -- Renamer leaves this flag unchanged, to record the way
-- the user wrote it originally, so that the printer can