summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/iface/MkIface.lhs129
-rw-r--r--compiler/typecheck/TcHsType.lhs143
-rw-r--r--compiler/typecheck/TcRnDriver.lhs8
-rw-r--r--compiler/typecheck/TcRnTypes.lhs40
-rw-r--r--compiler/typecheck/TcRules.lhs3
-rw-r--r--compiler/typecheck/TcTyClsDecls.lhs110
-rw-r--r--compiler/types/Kind.lhs9
7 files changed, 267 insertions, 175 deletions
diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs
index 7420dd8c32..d51fdd460a 100644
--- a/compiler/iface/MkIface.lhs
+++ b/compiler/iface/MkIface.lhs
@@ -1433,19 +1433,45 @@ checkList (check:checks) = do recompile <- check
\begin{code}
tyThingToIfaceDecl :: TyThing -> IfaceDecl
--- Assumption: the thing is already tidied, so that locally-bound names
--- (lambdas, for-alls) already have non-clashing OccNames
--- Reason: Iface stuff uses OccNames, and the conversion here does
--- not do tidying on the way
-tyThingToIfaceDecl (AnId id)
+tyThingToIfaceDecl (AnId id) = idToIfaceDecl id
+tyThingToIfaceDecl (ATyCon tycon) = tyConToIfaceDecl emptyTidyEnv tycon
+tyThingToIfaceDecl (ACoAxiom ax) = coAxiomToIfaceDecl ax
+tyThingToIfaceDecl (ADataCon dc) = pprPanic "toIfaceDecl" (ppr dc)
+ -- Should be trimmed out earlier
+
+--------------------------
+idToIfaceDecl :: Id -> IfaceDecl
+-- The Id is already tidied, so that locally-bound names
+-- (lambdas, for-alls) already have non-clashing OccNames
+-- We can't tidy it here, locally, because it may have
+-- free variables in its type or IdInfo
+idToIfaceDecl id
= IfaceId { ifName = getOccName id,
ifType = toIfaceType (idType id),
ifIdDetails = toIfaceIdDetails (idDetails id),
ifIdInfo = toIfaceIdInfo (idInfo id) }
-tyThingToIfaceDecl (ATyCon tycon)
+
+--------------------------
+coAxiomToIfaceDecl :: CoAxiom -> IfaceDecl
+-- We *do* tidy Axioms, because they are not (and cannot
+-- conveniently be) built in tidy form
+coAxiomToIfaceDecl ax
+ = IfaceAxiom { ifName = name
+ , ifTyVars = toIfaceTvBndrs tv_bndrs
+ , ifLHS = tidyToIfaceType env (coAxiomLHS ax)
+ , ifRHS = tidyToIfaceType env (coAxiomRHS ax) }
+ where
+ name = getOccName ax
+ (env, tv_bndrs) = tidyTyVarBndrs emptyTidyEnv (coAxiomTyVars ax)
+
+-----------------
+tyConToIfaceDecl :: TidyEnv -> TyCon -> IfaceDecl
+-- We *do* tidy TyCons, because they are not (and cannot
+-- conveniently be) built in tidy form
+tyConToIfaceDecl env tycon
| Just clas <- tyConClass_maybe tycon
- = classToIfaceDecl clas
+ = classToIfaceDecl env clas
| isSynTyCon tycon
= IfaceSyn { ifName = getOccName tycon,
@@ -1457,7 +1483,7 @@ tyThingToIfaceDecl (ATyCon tycon)
= IfaceData { ifName = getOccName tycon,
ifCType = tyConCType tycon,
ifTyVars = toIfaceTvBndrs tyvars,
- ifCtxt = toIfaceContext (tyConStupidTheta tycon),
+ ifCtxt = tidyToIfaceContext env1 (tyConStupidTheta tycon),
ifCons = ifaceConDecls (algTyConRhs tycon),
ifRec = boolToRecFlag (isRecursiveTyCon tycon),
ifGadtSyntax = isGadtSyntaxTyCon tycon,
@@ -1469,16 +1495,15 @@ tyThingToIfaceDecl (ATyCon tycon)
| otherwise = pprPanic "toIfaceDecl" (ppr tycon)
where
- tyvars = tyConTyVars tycon
+ (env1, tyvars) = tidyTyVarBndrs env (tyConTyVars tycon)
+
(syn_rhs, syn_ki)
= case synTyConRhs tycon of
- SynFamilyTyCon -> (Nothing, toIfaceType (synTyConResKind tycon))
- SynonymTyCon ty -> (Just (toIfaceType ty), toIfaceType (typeKind ty))
+ SynFamilyTyCon -> (Nothing, tidyToIfaceType env1 (synTyConResKind tycon))
+ SynonymTyCon ty -> (Just (toIfaceType ty), tidyToIfaceType env1 (typeKind ty))
- ifaceConDecls (NewTyCon { data_con = con }) =
- IfNewTyCon (ifaceConDecl con)
- ifaceConDecls (DataTyCon { data_cons = cons }) =
- IfDataTyCon (map ifaceConDecl cons)
+ ifaceConDecls (NewTyCon { data_con = con }) = IfNewTyCon (ifaceConDecl con)
+ ifaceConDecls (DataTyCon { data_cons = cons }) = IfDataTyCon (map ifaceConDecl cons)
ifaceConDecls DataFamilyTyCon {} = IfDataFamTyCon
ifaceConDecls (AbstractTyCon distinct) = IfAbstractTyCon distinct
-- The last case happens when a TyCon has been trimmed during tidying
@@ -1490,39 +1515,27 @@ tyThingToIfaceDecl (ATyCon tycon)
= IfCon { ifConOcc = getOccName (dataConName data_con),
ifConInfix = dataConIsInfix data_con,
ifConWrapper = isJust (dataConWrapId_maybe data_con),
- ifConUnivTvs = toIfaceTvBndrs univ_tvs,
- ifConExTvs = toIfaceTvBndrs ex_tvs,
+ ifConUnivTvs = toIfaceTvBndrs univ_tvs',
+ ifConExTvs = toIfaceTvBndrs ex_tvs',
ifConEqSpec = to_eq_spec eq_spec,
- ifConCtxt = toIfaceContext theta,
- ifConArgTys = map toIfaceType arg_tys,
+ ifConCtxt = tidyToIfaceContext env3 theta,
+ ifConArgTys = map (tidyToIfaceType env3) arg_tys,
ifConFields = map getOccName
(dataConFieldLabels data_con),
ifConStricts = dataConStrictMarks data_con }
where
(univ_tvs, ex_tvs, eq_spec, theta, arg_tys, _) = dataConFullSig data_con
+ (env2, univ_tvs') = tidyTyClTyVarBndrs env1 univ_tvs
+ (env3, ex_tvs') = tidyTyVarBndrs env2 ex_tvs
+ to_eq_spec spec = [ (getOccName (tidyTyVar env3 tv), tidyToIfaceType env3 ty)
+ | (tv,ty) <- spec]
- to_eq_spec spec = [(getOccName tv, toIfaceType ty) | (tv,ty) <- spec]
-tyThingToIfaceDecl (ACoAxiom ax)
- = IfaceAxiom { ifName = name
- , ifTyVars = tv_bndrs
- , ifLHS = lhs
- , ifRHS = rhs }
- where
- name = getOccName ax
- tv_bndrs = toIfaceTvBndrs (coAxiomTyVars ax)
- lhs = toIfaceType (coAxiomLHS ax)
- rhs = toIfaceType (coAxiomRHS ax)
-
-tyThingToIfaceDecl (ADataCon dc)
- = pprPanic "toIfaceDecl" (ppr dc) -- Should be trimmed out earlier
-
-
-classToIfaceDecl :: Class -> IfaceDecl
-classToIfaceDecl clas
- = IfaceClass { ifCtxt = toIfaceContext sc_theta,
+classToIfaceDecl :: TidyEnv -> Class -> IfaceDecl
+classToIfaceDecl env clas
+ = IfaceClass { ifCtxt = tidyToIfaceContext env1 sc_theta,
ifName = getOccName (classTyCon clas),
- ifTyVars = toIfaceTvBndrs clas_tyvars,
+ ifTyVars = toIfaceTvBndrs clas_tyvars',
ifFDs = map toIfaceFD clas_fds,
ifATs = map toIfaceAT clas_ats,
ifSigs = map toIfaceClassOp op_stuff,
@@ -1532,17 +1545,23 @@ classToIfaceDecl clas
= classExtraBigSig clas
tycon = classTyCon clas
+ (env1, clas_tyvars') = tidyTyVarBndrs env clas_tyvars
+
toIfaceAT :: ClassATItem -> IfaceAT
toIfaceAT (tc, defs)
- = IfaceAT (tyThingToIfaceDecl (ATyCon tc))
- (map to_if_at_def defs)
+ = IfaceAT (tyConToIfaceDecl env1 tc) (map to_if_at_def defs)
where
to_if_at_def (ATD tvs pat_tys ty _loc)
- = IfaceATD (toIfaceTvBndrs tvs) (map toIfaceType pat_tys) (toIfaceType ty)
+ = IfaceATD (toIfaceTvBndrs tvs')
+ (map (tidyToIfaceType env2) pat_tys)
+ (tidyToIfaceType env2 ty)
+ where
+ (env2, tvs') = tidyTyClTyVarBndrs env1 tvs
toIfaceClassOp (sel_id, def_meth)
= ASSERT(sel_tyvars == clas_tyvars)
- IfaceClassOp (getOccName sel_id) (toDmSpec def_meth) (toIfaceType op_ty)
+ IfaceClassOp (getOccName sel_id) (toDmSpec def_meth)
+ (tidyToIfaceType env1 op_ty)
where
-- Be careful when splitting the type, because of things
-- like class Foo a where
@@ -1556,8 +1575,30 @@ classToIfaceDecl clas
toDmSpec (GenDefMeth _) = GenericDM
toDmSpec (DefMeth _) = VanillaDM
- toIfaceFD (tvs1, tvs2) = (map getFS tvs1, map getFS tvs2)
+ toIfaceFD (tvs1, tvs2) = (map (getFS . tidyTyVar env1) tvs1,
+ map (getFS . tidyTyVar env1) tvs2)
+--------------------------
+tidyToIfaceType :: TidyEnv -> Type -> IfaceType
+tidyToIfaceType env ty = toIfaceType (tidyType env ty)
+
+tidyToIfaceContext :: TidyEnv -> ThetaType -> IfaceContext
+tidyToIfaceContext env theta = map (tidyToIfaceType env) theta
+
+tidyTyClTyVarBndrs :: TidyEnv -> [TyVar] -> (TidyEnv, [TyVar])
+tidyTyClTyVarBndrs env tvs = mapAccumL tidyTyClTyVarBndr env tvs
+
+tidyTyClTyVarBndr :: TidyEnv -> TyVar -> (TidyEnv, TyVar)
+-- If the type variable "binder" is in scope, don't re-bind it
+-- In a class decl, for example, the ATD binders mention
+-- (amd must mention) the class tyvars
+tidyTyClTyVarBndr env@(_, subst) tv
+ | Just tv' <- lookupVarEnv subst tv = (env, tv')
+ | otherwise = tidyTyVarBndr env tv
+
+tidyTyVar :: TidyEnv -> TyVar -> TyVar
+tidyTyVar (_, subst) tv = lookupVarEnv subst tv `orElse` tv
+ -- TcType.tidyTyVarOcc messes around with FlatSkols
getFS :: NamedThing a => a -> FastString
getFS x = occNameFS (getOccName x)
diff --git a/compiler/typecheck/TcHsType.lhs b/compiler/typecheck/TcHsType.lhs
index 7808c6b44c..1e30d7c328 100644
--- a/compiler/typecheck/TcHsType.lhs
+++ b/compiler/typecheck/TcHsType.lhs
@@ -30,7 +30,7 @@ module TcHsType (
tcHsContext, tcInferApps, tcHsArgTys,
ExpKind(..), ekConstraint, expArgKind, checkExpectedKind,
- bindScopedKindVars, kindGeneralize,
+ kindGeneralize,
-- Sort-checking kinds
tcLHsKind,
@@ -292,7 +292,7 @@ tcCheckHsTypeAndGen :: HsType Name -> Kind -> TcM Type
-- The result is not necessarily zonked, and has not been checked for validity
tcCheckHsTypeAndGen hs_ty kind
= do { ty <- tc_hs_type hs_ty (EK kind (ptext (sLit "Expected")))
- ; kvs <- kindGeneralize (tyVarsOfType ty)
+ ; kvs <- kindGeneralize (tyVarsOfType ty) []
; return (mkForAllTys kvs ty) }
\end{code}
@@ -583,16 +583,10 @@ tcTyVar name -- Could be a tyvar, a tycon, or a datacon
ty = dataConUserType dc
tc = buildPromotedDataCon dc
- AFamDataCon -> bad_promote (ptext (sLit "it comes from a data family instance"))
- ARecDataCon -> bad_promote (ptext (sLit "it is defined and used in the same recursive group"))
+ APromotionErr err -> promotionErr name err
_ -> wrongThingErr "type" thing name }
where
- bad_promote reason
- = failWithTc (hang (ptext (sLit "You can't use data constructor") <+> quotes (ppr name)
- <+> ptext (sLit "here"))
- 2 (parens reason))
-
get_loopy_tc name
= do { env <- getGblEnv
; case lookupNameEnv (tcg_type_env env) name of
@@ -793,42 +787,53 @@ then we'd also need
since we only have BOX for a super kind)
\begin{code}
-bindScopedKindVars :: [Name] -> ([KindVar] -> TcM a) -> TcM a
+kcScopedKindVars :: [Name] -> TcM a -> TcM a
-- Given some tyvar binders like [a (b :: k -> *) (c :: k)]
-- bind each scoped kind variable (k in this case) to a fresh
-- kind skolem variable
-bindScopedKindVars kv_ns thing_inside
- = tcExtendTyVarEnv kvs (thing_inside kvs)
- where
- kvs = map mkKindSigVar kv_ns
+kcScopedKindVars kv_ns thing_inside
+ = do { kvs <- mapM (\n -> newSigTyVar n superKind) kv_ns
+ -- NB: use mutable signature variables
+ ; tcExtendTyVarEnv2 (kv_ns `zip` kvs) thing_inside }
kcHsTyVarBndrs :: Bool -- Default UserTyVar to *
+ -- and use KindVars not meta kind vars
-> LHsTyVarBndrs Name
-> ([TcKind] -> TcM r)
-> TcM r
-kcHsTyVarBndrs default_to_star (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
- = bindScopedKindVars kvs $ \ _ ->
+kcHsTyVarBndrs full_kind_sig (HsQTvs { hsq_kvs = kv_ns, hsq_tvs = hs_tvs }) thing_inside
+ = do { kvs <- if full_kind_sig
+ then return (map mkKindSigVar kv_ns)
+ else mapM (\n -> newSigTyVar n superKind) kv_ns
+ ; tcExtendTyVarEnv2 (kv_ns `zip` kvs) $
do { nks <- mapM (kc_hs_tv . unLoc) hs_tvs
- ; tcExtendKindEnv nks (thing_inside (map snd nks)) }
+ ; tcExtendKindEnv nks (thing_inside (map snd nks)) } }
where
kc_hs_tv :: HsTyVarBndr Name -> TcM (Name, TcKind)
kc_hs_tv (UserTyVar n)
= do { mb_thing <- tcLookupLcl_maybe n
; kind <- case mb_thing of
- Just (AThing k) -> return k
- _ | default_to_star -> return liftedTypeKind
- | otherwise -> newMetaKindVar
+ Just (AThing k) -> return k
+ _ | full_kind_sig -> return liftedTypeKind
+ | otherwise -> newMetaKindVar
; return (n, kind) }
kc_hs_tv (KindedTyVar n k)
= do { kind <- tcLHsKind k
; return (n, kind) }
+tcScopedKindVars :: [Name] -> TcM a -> TcM a
+-- Given some tyvar binders like [a (b :: k -> *) (c :: k)]
+-- bind each scoped kind variable (k in this case) to a fresh
+-- kind skolem variable
+tcScopedKindVars kv_ns thing_inside
+ = tcExtendTyVarEnv (map mkKindSigVar kv_ns) thing_inside
+
tcHsTyVarBndrs :: LHsTyVarBndrs Name
-> ([TyVar] -> TcM r)
-> TcM r
-- Bind the type variables to skolems, each with a meta-kind variable kind
tcHsTyVarBndrs (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
- = bindScopedKindVars kvs $ \ _ ->
+ = tcScopedKindVars kvs $
do { tvs <- mapM tcHsTyVarBndr hs_tvs
; traceTc "tcHsTyVarBndrs" (ppr hs_tvs $$ ppr tvs)
; tcExtendTyVarEnv tvs (thing_inside tvs) }
@@ -857,13 +862,13 @@ tcHsTyVarBndr (L _ hs_tv)
; return (mkTcTyVar name kind (SkolemTv False)) } } }
------------------
-kindGeneralize :: TyVarSet -> TcM [KindVar]
-kindGeneralize tkvs
- = do { gbl_tvs <- tcGetGlobalTyVars -- Already zonked
- ; tidy_env <- tcInitTidyEnv
- ; tkvs <- zonkTyVarsAndFV tkvs
+kindGeneralize :: TyVarSet -> [Name] -> TcM [KindVar]
+kindGeneralize tkvs _names_to_avoid
+ = do { gbl_tvs <- tcGetGlobalTyVars -- Already zonked
+ ; tkvs <- zonkTyVarsAndFV tkvs
; let kvs_to_quantify = filter isKindVar (varSetElems (tkvs `minusVarSet` gbl_tvs))
- -- Any type varaibles in tkvs will be in scope,
+ -- ToDo: remove the (filter isKindVar)
+ -- Any type variables in tkvs will be in scope,
-- and hence in gbl_tvs, so after removing gbl_tvs
-- we should only have kind variables left
--
@@ -873,14 +878,16 @@ kindGeneralize tkvs
-- unification variable 'alpha', with no biding forall. We don't
-- want to kind-quantify it!
- (_, tidy_kvs_to_quantify) = tidyTyVarBndrs tidy_env kvs_to_quantify
- -- We do not get a later chance to tidy!
-
+ ; traceTc "kindGeneralise" (vcat [ppr kvs_to_quantify])
; ASSERT2 (all isKindVar kvs_to_quantify, ppr kvs_to_quantify $$ ppr tkvs)
- -- This assertion is obviosy true because of the filter isKindVar
+ -- This assertion is obviosly true because of the filter isKindVar
-- but we'll remove that when reorganising TH, and then the assertion
-- will mean something
- zonkQuantifiedTyVars tidy_kvs_to_quantify }
+
+ -- If we tidied the kind variables, which should all be mutable,
+ -- this 'zonkQuantifiedTyVars' update the original TyVar to point to
+ -- the tided and skolemised one
+ zonkQuantifiedTyVars kvs_to_quantify }
\end{code}
Note [Kind generalisation]
@@ -937,7 +944,7 @@ kcTyClTyVars :: Name -> LHsTyVarBndrs Name -> (TcKind -> TcM a) -> TcM a
-- Used for the type variables of a type or class decl,
-- when doing the initial kind-check.
kcTyClTyVars name (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
- = bindScopedKindVars kvs $ \ _ ->
+ = kcScopedKindVars kvs $
do { tc_kind <- kcLookupKind name
; let (arg_ks, res_k) = splitKindFunTysN (length hs_tvs) tc_kind
-- There should be enough arrows, because
@@ -980,21 +987,24 @@ tcTyClTyVars :: Name -> LHsTyVarBndrs Name -- LHS of the type or class decl
--
-- No need to freshen the k's because they are just skolem
-- constants here, and we are at top level anyway.
-tcTyClTyVars tycon tyvars thing_inside
- = do { thing <- tcLookup tycon
+tcTyClTyVars tycon (HsQTvs { hsq_kvs = kvs, hsq_tvs = hs_tvs }) thing_inside
+ = kcScopedKindVars kvs $
+ do { thing <- tcLookup tycon
; let { kind = case thing of
AThing kind -> kind
_ -> panic "tcTyClTyVars"
-- We only call tcTyClTyVars during typechecking in
-- TcTyClDecls, where the local env is extended with
-- the generalized_env (mapping Names to AThings).
- ; (kvs, body) = splitForAllTys kind
- ; (kinds, res) = splitKindFunTysN (length names) body
- ; names = hsLTyVarNames tyvars
- ; tvs = zipWith mkTyVar names kinds
- ; all_vs = kvs ++ tvs }
- ; tcExtendTyVarEnv all_vs (thing_inside all_vs res) }
-
+ ; (kvs, body) = splitForAllTys kind
+ ; (kinds, res) = splitKindFunTysN (length hs_tvs) body }
+ ; tvs <- zipWithM tc_hs_tv hs_tvs kinds
+ ; tcExtendTyVarEnv tvs (thing_inside (kvs ++ tvs) res) }
+ where
+ tc_hs_tv (L _ (UserTyVar n)) kind = return (mkTyVar n kind)
+ tc_hs_tv (L _ (KindedTyVar n hs_k)) kind = do { tc_kind <- tcLHsKind hs_k
+ ; _ <- unifyKind kind tc_kind
+ ; return (mkTyVar n kind) }
-----------------------------------
tcDataKindSig :: Kind -> TcM [TyVar]
@@ -1384,19 +1394,19 @@ tc_kind_var_app name arg_kis
-- General case
tc_kind_var_app name arg_kis
- = do { (_errs, mb_thing) <- tryTc (tcLookup name)
- ; case mb_thing of
- Just (AGlobal (ATyCon tc))
+ = do { thing <- tcLookup name
+ ; case thing of
+ AGlobal (ATyCon tc)
-> do { data_kinds <- xoptM Opt_DataKinds
; unless data_kinds $ addErr (dataKindsErr name)
; case isPromotableTyCon tc of
Just n | n == length arg_kis ->
return (mkTyConApp (buildPromotedTyCon tc) arg_kis)
- Just _ -> err tc "is not fully applied"
- Nothing -> err tc "is not promotable" }
+ Just _ -> tycon_err tc "is not fully applied"
+ Nothing -> tycon_err tc "is not promotable" }
-- A lexically scoped kind variable
- Just (ATyVar _ kind_var)
+ ATyVar _ kind_var
| not (isKindVar kind_var)
-> failWithTc (ptext (sLit "Type variable") <+> quotes (ppr kind_var)
<+> ptext (sLit "used as a kind"))
@@ -1408,19 +1418,32 @@ tc_kind_var_app name arg_kis
-> return (mkAppTys (mkTyVarTy kind_var) arg_kis)
-- It is in scope, but not what we expected
- Just thing -> wrongThingErr "promoted type" thing name
-
- -- It is not in scope, but it passed the renamer: staging error
- Nothing
- -> -- ASSERT2 ( isTyConName name, ppr name )
- do { env <- getLclEnv
- ; traceTc "tc_kind_var_app" (ppr name $$ ppr (tcl_env env))
- ; failWithTc (ptext (sLit "Promoted kind") <+>
- quotes (ppr name) <+>
- ptext (sLit "used in a mutually recursive group")) } }
+ AThing _
+ | isTyVarName name
+ -> failWithTc (ptext (sLit "Type variable") <+> quotes (ppr name)
+ <+> ptext (sLit "used in a kind"))
+ | otherwise
+ -> failWithTc (hang (ptext (sLit "Type constructor") <+> quotes (ppr name)
+ <+> ptext (sLit "used in a kind"))
+ 2 (ptext (sLit "inside its own recursive group")))
+
+ APromotionErr err -> promotionErr name err
+
+ _ -> wrongThingErr "promoted type" thing name
+ -- This really should not happen
+ }
where
- err tc msg = failWithTc (quotes (ppr tc) <+> ptext (sLit "of kind")
- <+> quotes (ppr (tyConKind tc)) <+> ptext (sLit msg))
+ tycon_err tc msg = failWithTc (quotes (ppr tc) <+> ptext (sLit "of kind")
+ <+> quotes (ppr (tyConKind tc)) <+> ptext (sLit msg))
+
+promotionErr :: Name -> PromotionErr -> TcM a
+promotionErr name err
+ = failWithTc (hang (pprPECategory err <+> quotes (ppr name) <+> ptext (sLit "cannot be used here"))
+ 2 (parens reason))
+ where
+ reason = case err of
+ FamDataConPE -> ptext (sLit "it comes from a data family instance")
+ _ -> ptext (sLit "it is defined and used in the same recursive group")
\end{code}
%************************************************************************
diff --git a/compiler/typecheck/TcRnDriver.lhs b/compiler/typecheck/TcRnDriver.lhs
index d4eb93113a..778a4b266f 100644
--- a/compiler/typecheck/TcRnDriver.lhs
+++ b/compiler/typecheck/TcRnDriver.lhs
@@ -967,8 +967,8 @@ tcTyClsInstDecls :: ModDetails
HsValBinds Name) -- Supporting bindings for derived instances
tcTyClsInstDecls boot_details tycl_decls inst_decls deriv_decls
- = tcExtendTcTyThingEnv [(con, AFamDataCon) | lid <- inst_decls
- , con <- get_cons lid ] $
+ = tcExtendTcTyThingEnv [(con, APromotionErr FamDataConPE)
+ | lid <- inst_decls, con <- get_cons lid ] $
-- Note [AFamDataCon: not promoting data family constructors]
do { tcg_env <- tcTyAndClassDecls boot_details tycl_decls ;
; setGblEnv tcg_env $
@@ -1890,7 +1890,9 @@ ppr_tydecls tycons
= vcat (map ppr_tycon (sortLe le_sig tycons))
where
le_sig tycon1 tycon2 = getOccName tycon1 <= getOccName tycon2
- ppr_tycon tycon = ppr (tyThingToIfaceDecl (ATyCon tycon))
+ ppr_tycon tycon = vcat [ ppr (tyConName tycon) <+> dcolon <+> ppr (tyConKind tycon)
+ -- Temporarily print the kind signature too
+ , ppr (tyThingToIfaceDecl (ATyCon tycon)) ]
ppr_rules :: [CoreRule] -> SDoc
ppr_rules [] = empty
diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs
index 1ed3d0d198..ac35c37df2 100644
--- a/compiler/typecheck/TcRnTypes.lhs
+++ b/compiler/typecheck/TcRnTypes.lhs
@@ -38,7 +38,8 @@ module TcRnTypes(
WhereFrom(..), mkModDeps,
-- Typechecker types
- TcTypeEnv, TcTyThing(..), pprTcTyThingCategory,
+ TcTypeEnv, TcTyThing(..), PromotionErr(..),
+ pprTcTyThingCategory, pprPECategory,
-- Template Haskell
ThStage(..), topStage, topAnnStage, topSpliceStage,
@@ -580,10 +581,17 @@ data TcTyThing
-- Can be a mono-kind or a poly-kind; in TcTyClsDcls see
-- Note [Type checking recursive type and class declarations]
- | AFamDataCon -- Data constructor for a data family
+ | APromotionErr PromotionErr
+
+data PromotionErr
+ = TyConPE -- TyCon used in a kind before we are ready
+ -- data T :: T -> * where ...
+ | ClassPE -- Ditto Class
+
+ | FamDataConPE -- Data constructor for a data family
-- See Note [AFamDataCon: not promoting data family constructors] in TcRnDriver
- | ARecDataCon -- Data constructor in a reuursive loop
+ | RecDataConPE -- Data constructor in a reuursive loop
-- See Note [ARecDataCon: recusion and promoting data constructors] in TcTyClsDecls
instance Outputable TcTyThing where -- Debugging only
@@ -595,16 +603,26 @@ instance Outputable TcTyThing where -- Debugging only
<+> ppr (tct_level elt))
ppr (ATyVar tv _) = text "Type variable" <+> quotes (ppr tv)
ppr (AThing k) = text "AThing" <+> ppr k
- ppr AFamDataCon = text "AFamDataCon"
- ppr ARecDataCon = text "ARecDataCon"
+ ppr (APromotionErr err) = text "APromotionErr" <+> ppr err
+
+instance Outputable PromotionErr where
+ ppr ClassPE = text "ClassPE"
+ ppr TyConPE = text "TyConPE"
+ ppr FamDataConPE = text "FamDataConPE"
+ ppr RecDataConPE = text "RecDataConPE"
pprTcTyThingCategory :: TcTyThing -> SDoc
-pprTcTyThingCategory (AGlobal thing) = pprTyThingCategory thing
-pprTcTyThingCategory (ATyVar {}) = ptext (sLit "Type variable")
-pprTcTyThingCategory (ATcId {}) = ptext (sLit "Local identifier")
-pprTcTyThingCategory (AThing {}) = ptext (sLit "Kinded thing")
-pprTcTyThingCategory AFamDataCon = ptext (sLit "Family data con")
-pprTcTyThingCategory ARecDataCon = ptext (sLit "Recursive data con")
+pprTcTyThingCategory (AGlobal thing) = pprTyThingCategory thing
+pprTcTyThingCategory (ATyVar {}) = ptext (sLit "Type variable")
+pprTcTyThingCategory (ATcId {}) = ptext (sLit "Local identifier")
+pprTcTyThingCategory (AThing {}) = ptext (sLit "Kinded thing")
+pprTcTyThingCategory (APromotionErr pe) = pprPECategory pe
+
+pprPECategory :: PromotionErr -> SDoc
+pprPECategory ClassPE = ptext (sLit "Class")
+pprPECategory TyConPE = ptext (sLit "Type constructor")
+pprPECategory FamDataConPE = ptext (sLit "Data constructor")
+pprPECategory RecDataConPE = ptext (sLit "Data constructor")
\end{code}
diff --git a/compiler/typecheck/TcRules.lhs b/compiler/typecheck/TcRules.lhs
index 4f2dab07fe..f4f8c96964 100644
--- a/compiler/typecheck/TcRules.lhs
+++ b/compiler/typecheck/TcRules.lhs
@@ -166,7 +166,8 @@ tcRule (HsRule name act hs_bndrs lhs fv_lhs rhs fv_rhs)
; zonked_forall_tvs <- zonkTyVarsAndFV forall_tvs
; gbl_tvs <- tcGetGlobalTyVars -- Already zonked
; let tvs_to_quantify = varSetElems (zonked_forall_tvs `minusVarSet` gbl_tvs)
- ; qkvs <- kindGeneralize $ tyVarsOfTypes (map tyVarKind tvs_to_quantify)
+ ; qkvs <- kindGeneralize (tyVarsOfTypes (map tyVarKind tvs_to_quantify))
+ (map getName tvs_to_quantify)
; qtvs <- zonkQuantifiedTyVars tvs_to_quantify
; let qtkvs = qkvs ++ qtvs
; traceTc "tcRule" (vcat [ doubleQuotes (ftext name)
diff --git a/compiler/typecheck/TcTyClsDecls.lhs b/compiler/typecheck/TcTyClsDecls.lhs
index a22697d217..ab2880488d 100644
--- a/compiler/typecheck/TcTyClsDecls.lhs
+++ b/compiler/typecheck/TcTyClsDecls.lhs
@@ -129,9 +129,9 @@ tcTyClGroup boot_details tyclds
-- Populate environment with knot-tied ATyCon for TyCons
-- NB: if the decls mention any ill-staged data cons
- -- (see Note [ANothing] in typecheck/TcRnTypes.lhs) we
- -- will have failed already in kcTyClGroup, so no worries here
- ; tcExtendRecEnv (zipRecTyClss tyclds rec_tyclss) $
+ -- (see Note [ARecDataCon: Recusion and promoting data constructors]
+ -- we will have failed already in kcTyClGroup, so no worries here
+ ; tcExtendRecEnv (zipRecTyClss names_w_poly_kinds rec_tyclss) $
-- Also extend the local type envt with bindings giving
-- the (polymorphic) kind of each knot-tied TyCon or Class
@@ -147,7 +147,7 @@ tcTyClGroup boot_details tyclds
-- expects well-formed TyCons
; tcExtendGlobalEnv tyclss $ do
{ traceTc "Starting validity check" (ppr tyclss)
- ; mapM_ (addLocM checkValidTyCl) tyclds
+ ; mapM_ (addLocM checkValidTyCl) (flattenTyClDecls tyclds)
-- Step 4: Add the implicit things;
-- we want them in the environment because
@@ -163,16 +163,15 @@ tcAddImplicits tyclss
implicit_things = concatMap implicitTyThings tyclss
rec_sel_binds = mkRecSelBinds tyclss
-zipRecTyClss :: TyClGroup Name
+zipRecTyClss :: [(Name, Kind)]
-> [TyThing] -- Knot-tied
-> [(Name,TyThing)]
-- Build a name-TyThing mapping for the things bound by decls
-- being careful not to look at the [TyThing]
-- The TyThings in the result list must have a visible ATyCon,
-- because typechecking types (in, say, tcTyClDecl) looks at this outer constructor
-zipRecTyClss decls rec_things
- = [ (name, ATyCon (get name))
- | name <- tyClsBinders decls ]
+zipRecTyClss kind_pairs rec_things
+ = [ (name, ATyCon (get name)) | (name, _kind) <- kind_pairs ]
where
rec_type_env :: TypeEnv
rec_type_env = mkTypeEnv rec_things
@@ -181,13 +180,12 @@ zipRecTyClss decls rec_things
Just (ATyCon tc) -> tc
other -> pprPanic "zipRecTyClss" (ppr name <+> ppr other)
-tyClsBinders :: TyClGroup Name -> [Name]
--- Just the tycon and class binders of a group (not the data constructors)
-tyClsBinders decls
- = concatMap get decls
- where
- get (L _ (ClassDecl { tcdLName = L _ n, tcdATs = ats })) = n : tyClsBinders ats
- get (L _ d) = [tcdName d]
+flattenTyClDecls :: [LTyClDecl Name] -> [LTyClDecl Name]
+-- Lift out the associated type declaraitons to top level
+flattenTyClDecls [] = []
+flattenTyClDecls (ld@(L _ d) : lds)
+ | isClassDecl d = ld : tcdATs d ++ flattenTyClDecls lds
+ | otherwise = ld : flattenTyClDecls lds
\end{code}
@@ -254,6 +252,7 @@ initial kind environment. (This is handled by `allDecls').
\begin{code}
kcTyClGroup :: TyClGroup Name -> TcM [(Name,Kind)]
-- Kind check this group, kind generalize, and return the resulting local env
+-- This bindds the TyCons and Classes of the group, but not the DataCons
-- See Note [Kind checking for type and class decls]
kcTyClGroup decls
= do { mod <- getModule
@@ -268,39 +267,49 @@ kcTyClGroup decls
-- Step 1: Bind kind variables for non-synonyms
; let (syn_decls, non_syn_decls) = partition (isSynDecl . unLoc) decls
- ; initial_kinds <- getInitialKinds TopLevel non_syn_decls
-
+ ; initial_kinds <-
+ getInitialKinds TopLevel non_syn_decls
; traceTc "kcTyClGroup: initial kinds" (ppr initial_kinds)
- ; tcl_env <- tcExtendTcTyThingEnv initial_kinds $ do
- do { -- Step 2: kind-check the synonyms, and extend envt
- tcl_env <- kcSynDecls (calcSynCycles syn_decls)
- -- Step 3: kind-check the synonyms
- ; setLclEnv tcl_env $
- do { mapM_ kcLTyClDecl non_syn_decls
- ; getLclTypeEnv } }
+
+ -- Step 2: Set initial envt, kind-check the synonyms
+ ; lcl_env <- tcExtendTcTyThingEnv initial_kinds $
+ kcSynDecls (calcSynCycles syn_decls)
+
+ -- Step 3: Set extended envt, kind-check the non-synonyms
+ ; setLclEnv lcl_env $
+ mapM_ kcLTyClDecl non_syn_decls
-- Step 4: generalisation
-- Kind checking done for this group
-- Now we have to kind generalize the flexis
- ; res <- mapM (generalise tcl_env) (tyClsBinders decls)
+ ; res <- mapM (generalise (tcl_env lcl_env)) (flattenTyClDecls decls)
; traceTc "kcTyClGroup result" (ppr res)
; return res }
where
- generalise :: TcTypeEnv -> Name -> TcM (Name, Kind)
+ generalise :: TcTypeEnv -> LTyClDecl Name -> TcM (Name, Kind)
-- For polymorphic things this is a no-op
- generalise kind_env name
- = do { traceTc "Generalise type of" (ppr name)
+ generalise kind_env (L _ decl)
+ = do { let name = tcdName decl
+ tvs = tcdTyVars decl
; let kc_kind = case lookupNameEnv kind_env name of
Just (AThing k) -> k
_ -> pprPanic "kcTyClGroup" (ppr name $$ ppr kind_env)
- ; kvs <- kindGeneralize (tyVarsOfType kc_kind)
- ; kc_kind' <- zonkTcKind kc_kind
+ ; kvs <- kindGeneralize (tyVarsOfType kc_kind) (hsLTyVarNames tvs)
+ ; kc_kind' <- zonkTcKind kc_kind -- Make sure kc_kind' has the final,
+ -- skolemised kind variables
+ ; traceTc "Generalise kind" (vcat [ ppr name, ppr kc_kind, ppr kvs, ppr kc_kind' ])
; return (name, mkForAllTys kvs kc_kind') }
getInitialKinds :: TopLevelFlag -> [LTyClDecl Name] -> TcM [(Name, TcTyThing)]
-getInitialKinds top_lvl = concatMapM (addLocM (getInitialKind top_lvl))
+getInitialKinds top_lvl decls
+ = tcExtendTcTyThingEnv [ (tcdName d, APromotionErr (mk_promotion_err d))
+ | L _ d <- flattenTyClDecls decls] $
+ concatMapM (addLocM (getInitialKind top_lvl)) decls
+ where
+ mk_promotion_err (ClassDecl {}) = ClassPE
+ mk_promotion_err _ = TyConPE
getInitialKind :: TopLevelFlag -> TyClDecl Name -> TcM [(Name, TcTyThing)]
-- Allocate a fresh kind variable for each TyCon and Class
@@ -311,8 +320,8 @@ getInitialKind :: TopLevelFlag -> TyClDecl Name -> TcM [(Name, TcTyThing)]
-- Example: data T a b = ...
-- return (T, kv1 -> kv2 -> kv3)
--
--- ALSO for each datacon, return (dc, ANothing)
--- See Note [ANothing] in TcRnTypes
+-- ALSO for each datacon, return (dc, ARecDataCon)
+-- Note [ARecDataCon: Recusion and promoting data constructors]
--
-- No family instances are passed to getInitialKinds
@@ -347,14 +356,14 @@ getInitialKind top_lvl decl@(TyDecl { tcdLName = L _ name, tcdTyVars = ktvs, tcd
; let body_kind = mkArrowKinds arg_kinds res_k
kvs = varSetElems (tyVarsOfType body_kind)
main_pr = (name, AThing (mkForAllTys kvs body_kind))
- inner_prs = [(unLoc (con_name con), ARecDataCon) | L _ con <- cons ]
+ inner_prs = [(unLoc (con_name con), APromotionErr RecDataConPE) | L _ con <- cons ]
-- See Note [ARecDataCon: Recusion and promoting data constructors]
; return (main_pr : inner_prs) }
| TyData { td_cons = cons } <- defn
= kcHsTyVarBndrs False ktvs $ \ arg_kinds ->
do { let main_pr = (name, AThing (mkArrowKinds arg_kinds liftedTypeKind))
- inner_prs = [(unLoc (con_name con), ARecDataCon) | L _ con <- cons ]
+ inner_prs = [(unLoc (con_name con), APromotionErr RecDataConPE) | L _ con <- cons ]
-- See Note [ARecDataCon: Recusion and promoting data constructors]
; return (main_pr : inner_prs) }
@@ -622,13 +631,19 @@ tcTyDefn calc_isrec tc_name tvs kind
final_tvs = tvs ++ extra_tvs
; stupid_theta <- tcHsContext ctxt
; kind_signatures <- xoptM Opt_KindSignatures
- ; existential_ok <- xoptM Opt_ExistentialQuantification
- ; gadt_ok <- xoptM Opt_GADTs
+ ; existential_ok <- xoptM Opt_ExistentialQuantification
+ ; gadt_ok <- xoptM Opt_GADTs
; is_boot <- tcIsHsBoot -- Are we compiling an hs-boot file?
; let ex_ok = existential_ok || gadt_ok -- Data cons can have existential context
-- Check that we don't use kind signatures without Glasgow extensions
- ; checkTc (kind_signatures || isNothing mb_ksig) (badSigTyDecl tc_name)
+ ;
+ ; case mb_ksig of
+ Nothing -> return ()
+ Just hs_k -> do { checkTc (kind_signatures) (badSigTyDecl tc_name)
+ ; tc_kind <- tcLHsKind hs_k
+ ; _ <- unifyKind kind tc_kind
+ ; return () }
; dataDeclChecks tc_name new_or_data stupid_theta cons
@@ -717,7 +732,6 @@ tcSynFamInstDecl :: TyCon -> FamInstDecl Name -> TcM ([TyVar], [Type], Type)
tcSynFamInstDecl fam_tc
(FamInstDecl { fid_pats = pats, fid_defn = defn@(TySynonym { td_synRhs = hs_ty }) })
= do { checkTc (isSynTyCon fam_tc) (wrongKindOfFamily fam_tc)
-
; tcFamTyPats fam_tc pats (kcTyDefn defn) $ \tvs' pats' res_kind ->
do { rhs_ty <- tcCheckLHsType hs_ty res_kind
; rhs_ty <- zonkTcTypeToType emptyZonkEnv rhs_ty
@@ -965,7 +979,7 @@ tcConDecl new_or_data existential_ok rep_tycon res_tmpl -- Data types
-- Generalise the kind variables (returning quantifed TcKindVars)
-- and quanify the type variables (substiting their kinds)
- ; kvs <- kindGeneralize (tyVarsOfType pretend_con_ty)
+ ; kvs <- kindGeneralize (tyVarsOfType pretend_con_ty) (map getName tvs)
; tvs <- zonkQuantifiedTyVars tvs
-- Zonk to Types
@@ -1069,7 +1083,7 @@ rejigConRes (tmpl_tvs, res_tmpl) dc_tvs (ResTyGADT res_ty)
-- /Lazily/ figure out the univ_tvs etc
-- Each univ_tv is either a dc_tv or a tmpl_tv
- (univ_tvs, eq_spec) = foldr choose ([], []) tidy_tmpl_tvs
+ (univ_tvs, eq_spec) = foldr choose ([], []) tmpl_tvs
choose tmpl (univs, eqs)
| Just ty <- lookupTyVar subst tmpl
= case tcGetTyVar_maybe ty of
@@ -1081,17 +1095,6 @@ rejigConRes (tmpl_tvs, res_tmpl) dc_tvs (ResTyGADT res_ty)
| otherwise = pprPanic "tcResultType" (ppr res_ty)
ex_tvs = dc_tvs `minusList` univ_tvs
- -- NB: tmpl_tvs and dc_tvs are distinct, but
- -- we want them to be *visibly* distinct, both for
- -- interface files and general confusion. So rename
- -- the tc_tvs, since they are not used yet (no
- -- consequential renaming needed)
- (_, tidy_tmpl_tvs) = mapAccumL tidy_one init_occ_env tmpl_tvs
- init_occ_env = initTidyOccEnv (map getOccName dc_tvs)
- tidy_one env tv = (env', setTyVarName tv (tidyNameOcc name occ'))
- where
- name = tyVarName tv
- (env', occ') = tidyOccName env (getOccName name)
{-
Note [Substitution in template variables kinds]
@@ -1258,9 +1261,6 @@ checkValidTyCl decl
ATyCon tc -> do
traceTc " of kind" (ppr (tyConKind tc))
checkValidTyCon tc
- case decl of
- ClassDecl { tcdATs = ats } -> mapM_ (addLocM checkValidTyCl) ats
- _ -> return ()
AnId _ -> return () -- Generic default methods are checked
-- with their parent class
_ -> panic "checkValidTyCl"
diff --git a/compiler/types/Kind.lhs b/compiler/types/Kind.lhs
index 5f567eba36..7318891d87 100644
--- a/compiler/types/Kind.lhs
+++ b/compiler/types/Kind.lhs
@@ -34,7 +34,8 @@ module Kind (
-- ** Predicates on Kinds
isLiftedTypeKind, isUnliftedTypeKind, isOpenTypeKind,
- isConstraintKind, isConstraintOrLiftedKind, isKind, isKindVar,
+ isConstraintKind, isConstraintOrLiftedKind, returnsConstraintKind,
+ isKind, isKindVar,
isSuperKind, isSuperKindTyCon,
isLiftedTypeKindCon, isConstraintKindCon,
isAnyKind, isAnyKindCon,
@@ -135,6 +136,12 @@ isConstraintOrLiftedKind (TyConApp tc _)
= isConstraintKindCon tc || isLiftedTypeKindCon tc
isConstraintOrLiftedKind _ = False
+returnsConstraintKind :: Kind -> Bool
+returnsConstraintKind (ForAllTy _ k) = returnsConstraintKind k
+returnsConstraintKind (FunTy _ k) = returnsConstraintKind k
+returnsConstraintKind (TyConApp tc _) = isConstraintKindCon tc
+returnsConstraintKind _ = False
+
--------------------------------------------
-- Kinding for arrow (->)
-- Says when a kind is acceptable on lhs or rhs of an arrow