Commit c5919f75 authored by eir@cis.upenn.edu's avatar eir@cis.upenn.edu

Remove the incredibly hairy splitTelescopeTvs.

This patch removes splitTelescopeTvs by adding information about
scoped type variables to TcTyCon. Vast simplification!

This also fixes #11821 by bringing only unzonked vars into scope.

Test case: polykinds/T11821
parent a2970f88
This diff is collapsed.
......@@ -67,7 +67,8 @@ module TcMType (
mkTypeErrorThing, mkTypeErrorThingArgs,
tidyEvVar, tidyCt, tidySkolemInfo,
skolemiseUnboundMetaTyVar,
zonkTcTyVar, zonkTcTyVars, zonkTyCoVarsAndFV, zonkTcTypeAndFV,
zonkTcTyVar, zonkTcTyVars, zonkTcTyVarToTyVar,
zonkTyCoVarsAndFV, zonkTcTypeAndFV,
zonkTyCoVarsAndFVList,
zonkTcTypeAndSplitDepVars, zonkTcTypesAndSplitDepVars,
zonkQuantifiedTyVar, zonkQuantifiedTyVarOrType,
......@@ -1406,6 +1407,13 @@ zonkTcTyVar tv
zonk_kind_and_return = do { z_tv <- zonkTyCoVarKind tv
; return (mkTyVarTy z_tv) }
-- Variant that assumes that any result of zonking is still a TyVar.
-- Should be used only on skolems and SigTvs
zonkTcTyVarToTyVar :: TcTyVar -> TcM TcTyVar
zonkTcTyVarToTyVar tv
= do { ty <- zonkTcTyVar tv
; return (tcGetTyVar "zonkTcTyVarToVar" ty) }
{-
%************************************************************************
%* *
......
This diff is collapsed.
......@@ -1966,4 +1966,3 @@ allDistinctTyVars tkvs (ty : tys)
Nothing -> False
Just tv | tv `elemVarSet` tkvs -> False
| otherwise -> allDistinctTyVars (tkvs `extendVarSet` tv) tys
......@@ -85,6 +85,7 @@ module TyCon(
algTcFields,
tyConRuntimeRepInfo,
tyConBinders, tyConResKind,
tcTyConScopedTyVars,
-- ** Manipulating TyCons
expandSynTyCon_maybe,
......@@ -599,10 +600,14 @@ data TyCon
tyConUnsat :: Bool, -- ^ can this tycon be unsaturated?
-- See Note [The binders/kind/arity fields of a TyCon]
tyConTyVars :: [TyVar], -- ^ The TyCon's parameterised tyvars
tyConBinders :: [TyBinder], -- ^ The TyBinders for this TyCon's kind.
tyConResKind :: Kind, -- ^ Result kind
tyConKind :: Kind, -- ^ Kind of this TyCon
tyConArity :: Arity -- ^ Arity
tyConArity :: Arity, -- ^ Arity
tcTyConScopedTyVars :: [TyVar] -- ^ Scoped tyvars over the
-- tycon's body. See Note [TcTyCon]
}
deriving Typeable
......@@ -953,6 +958,45 @@ so the coercion tycon CoT must have
kind: T ~ []
and arity: 0
Note [TcTyCon]
~~~~~~~~~~~~~~
When checking a type/class declaration (in module TcTyClsDecls), we come
upon knowledge of the eventual tycon in bits and pieces. First, we use
getInitialKinds to look over the user-provided kind signature of a tycon
(including, for example, the number of parameters written to the tycon)
to get an initial shape of the tycon's kind. Then, using these initial
kinds, we kind-check the body of the tycon (class methods, data constructors,
etc.), filling in the metavariables in the tycon's initial kind.
We then generalize to get the tycon's final, fixed kind. Finally, once
this has happened for all tycons in a mutually recursive group, we
can desugar the lot.
For convenience, we store partially-known tycons in TcTyCons, which
might store meta-variables. These TcTyCons are stored in the local
environment in TcTyClsDecls, until the real full TyCons can be created
during desugaring. A desugared program should never have a TcTyCon.
A challenging piece in all of this is that we end up taking three separate
passes over every declaration: one in getInitialKind (this pass look only
at the head, not the body), one in kcTyClDecls (to kind-check the body),
and a final one in tcTyClDecls (to desugar). In the latter two passes,
we need to connect the user-written type variables in an LHsQTyVars
with the variables in the tycon's inferred kind. Because the tycon might
not have a CUSK, this matching up is, in general, quite hard to do.
(Look through the git history between Dec 2015 and Apr 2016 for
TcHsType.splitTelescopeTvs!) Instead of trying, we just store the list
of type variables to bring into scope in the later passes when we create
a TcTyCon in getInitialKinds. Much easier this way! These tyvars are
brought into scope in kcTyClTyVars and tcTyClTyVars, both in TcHsType.
It is important that the scoped type variables not be zonked, as some
scoped type variables come into existence as SigTvs. If we zonk, the
Unique will change and the user-written occurrences won't match up with
what we expect.
In a TcTyCon, everything is zonked (except the scoped vars) after
the kind-checking pass.
************************************************************************
* *
TyConRepName
......@@ -1284,17 +1328,21 @@ mkTupleTyCon name binders res_kind arity tyvars con sort parent
-- TcErrors sometimes calls typeKind.
-- See also Note [Kind checking recursive type and class declarations]
-- in TcTyClsDecls.
mkTcTyCon :: Name -> [TyBinder] -> Kind -- ^ /result/ kind only
-> Bool -- ^ Can this be unsaturated?
mkTcTyCon :: Name -> [TyVar]
-> [TyBinder] -> Kind -- ^ /result/ kind only
-> Bool -- ^ Can this be unsaturated?
-> [TyVar] -- ^ Scoped type variables, see Note [TcTyCon]
-> TyCon
mkTcTyCon name binders res_kind unsat
mkTcTyCon name tvs binders res_kind unsat scoped_tvs
= TcTyCon { tyConUnique = getUnique name
, tyConName = name
, tyConTyVars = tvs
, tyConBinders = binders
, tyConResKind = res_kind
, tyConKind = mkForAllTys binders res_kind
, tyConUnsat = unsat
, tyConArity = length binders }
, tyConArity = length binders
, tcTyConScopedTyVars = scoped_tvs }
-- | Create an unlifted primitive 'TyCon', such as @Int#@
mkPrimTyCon :: Name -> [TyBinder]
......@@ -1407,8 +1455,9 @@ isAbstractTyCon _ = False
-- Used when recovering from errors
makeTyConAbstract :: TyCon -> TyCon
makeTyConAbstract tc
= mkTcTyCon (tyConName tc) (tyConBinders tc) (tyConResKind tc)
(mightBeUnsaturatedTyCon tc)
= mkTcTyCon (tyConName tc) (tyConTyVars tc)
(tyConBinders tc) (tyConResKind tc)
(mightBeUnsaturatedTyCon tc) [{- no scoped vars -}]
-- | Does this 'TyCon' represent something that cannot be defined in Haskell?
isPrimTyCon :: TyCon -> Bool
......
<interactive>:2:1: error:
• Kind variable ‘k’ is implicitly bound in datatype
‘D1’, but does not appear as the kind of any
of its type variables. Perhaps you meant
to bind it (with TypeInType) explicitly somewhere?
• In the data declaration for ‘D1’
Kind variable ‘k’ is implicitly bound in datatype
‘D1’, but does not appear as the kind of any
of its type variables. Perhaps you meant
to bind it explicitly somewhere?
{-# LANGUAGE RankNTypes, DataKinds, PolyKinds, GADTs, TypeFamilies, UndecidableInstances #-}
module NotInScope where
import Data.Proxy
type KindOf (a :: k) = ('KProxy :: KProxy k)
data TyFun :: * -> * -> *
type family Apply (f :: TyFun k1 k2 -> *) (x :: k1) :: k2
data Lgo2 l1
l2
l3
(l4 :: b)
(l5 :: TyFun [a] b)
= forall (arg :: [a]) . KindOf (Apply (Lgo2 l1 l2 l3 l4) arg) ~ KindOf (Lgo l1 l2 l3 l4 arg) =>
Lgo2KindInference
data Lgo1 l1
l2
l3
(l4 :: TyFun b (TyFun [a] b -> *))
= forall (arg :: b) . KindOf (Apply (Lgo1 l1 l2 l3) arg) ~ KindOf (Lgo2 l1 l2 l3 arg) =>
Lgo1KindInference
type family Lgo f
z0
xs0
(a1 :: b)
(a2 :: [a]) :: b where
Lgo f z0 xs0 z '[] = z
Lgo f z0 xs0 z ('(:) x xs) = Apply (Apply (Lgo1 f z0 xs0) (Apply (Apply f z) x)) xs
......@@ -146,3 +146,4 @@ test('T11611', normal, compile_fail, [''])
test('T11648', normal, compile, [''])
test('T11648b', normal, compile_fail, [''])
test('KindVType', normal, compile_fail, [''])
test('T11821', normal, compile, [''])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment