diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2012-03-02 16:32:58 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2012-03-02 16:32:58 +0000 |
commit | 3bf54e78cfd4b94756e3f21c00ae187f80c3341d (patch) | |
tree | 0cf67e783bc0bc8d6db57152f339509bc7065876 /compiler/parser | |
parent | 0bc6055bdc140b35c563c0fc9a7a1b2ca92494cc (diff) | |
download | haskell-3bf54e78cfd4b94756e3f21c00ae187f80c3341d.tar.gz |
Hurrah! This major commit adds support for scoped kind variables,
which (finally) fills out the functionality of polymorphic kinds.
It also fixes numerous bugs.
Main changes are:
Renaming stuff
~~~~~~~~~~~~~~
* New type in HsTypes:
data HsBndrSig sig = HsBSig sig [Name]
which is used for type signatures in patterns, and kind signatures
in types. So when you say
f (x :: [a]) = x ++ x
or
data T (f :: k -> *) (x :: *) = MkT (f x)
the signatures in both cases are a HsBndrSig.
* The [Name] in HsBndrSig records the variables bound by the
pattern, that is 'a' in the first example, 'k' in the second,
and nothing in the third. The renamer initialises the field.
* As a result I was able to get rid of
RnHsSyn.extractHsTyNames :: LHsType Name -> NameSet
and its friends altogether. Deleted the entire module!
This led to some knock-on refactoring; in particular the
type renamer now returns the free variables just like the
term renamer.
Kind-checking types: mainly TcHsType
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A major change is that instead of kind-checking types in two
passes, we now do one. Under the old scheme, the first pass did
kind-checking and (hackily) annotated the HsType with the
inferred kinds; and the second pass desugared the HsType to a
Type. But now that we have kind variables inside types, the
first pass (TcHsType.tc_hs_type) can go straight to Type, and
zonking will squeeze out any kind unification variables later.
This is much nicer, but it was much more fiddly than I had expected.
The nastiest corner is this: it's very important that tc_hs_type
uses lazy constructors to build the returned type. See
Note [Zonking inside the knot] in TcHsType.
Type-checking type and class declarations: mainly TcTyClsDecls
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I did tons of refactoring in TcTyClsDecls. Simpler and nicer now.
Typechecking bindings: mainly TcBinds
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I rejigged (yet again) the handling of type signatures in TcBinds.
It's a bit simpler now. The main change is that tcTySigs goes
right through to a TcSigInfo in one step; previously it was split
into two, part here and part later.
Unsafe coercions
~~~~~~~~~~~~~~~~
Usually equality coercions have exactly the same kind on both
sides. But we do allow an *unsafe* coercion between Int# and Bool,
say, used in
case error Bool "flah" of { True -> 3#; False -> 0# }
-->
(error Bool "flah") |> unsafeCoerce Bool Int#
So what is the instantiation of (~#) here?
unsafeCoerce Bool Int# :: (~#) ??? Bool Int#
I'm using OpenKind here for now, but it's un-satisfying that
the lhs and rhs of the ~ don't have precisely the same kind.
More minor
~~~~~~~~~~
* HsDecl.TySynonym has its free variables attached, which makes
the cycle computation in TcTyDecls.mkSynEdges easier.
* Fixed a nasty reversed-comparison bug in FamInstEnv:
@@ -490,7 +490,7 @@ lookup_fam_inst_env' match_fun one_sided ie fam tys
n_tys = length tys
extra_tys = drop arity tys
(match_tys, add_extra_tys)
- | arity > n_tys = (take arity tys, \res_tys -> res_tys ++ extra_tys)
+ | arity < n_tys = (take arity tys, \res_tys -> res_tys ++ extra_tys)
| otherwise = (tys, \res_tys -> res_tys)
Diffstat (limited to 'compiler/parser')
-rw-r--r-- | compiler/parser/Parser.y.pp | 5 | ||||
-rw-r--r-- | compiler/parser/ParserCore.y | 4 | ||||
-rw-r--r-- | compiler/parser/RdrHsSyn.lhs | 8 |
3 files changed, 11 insertions, 6 deletions
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp index ff98b748c9..8de1e0b03f 100644 --- a/compiler/parser/Parser.y.pp +++ b/compiler/parser/Parser.y.pp @@ -871,7 +871,7 @@ rule_var_list :: { [RuleBndr RdrName] } rule_var :: { RuleBndr RdrName } : varid { RuleBndr $1 } - | '(' varid '::' ctype ')' { RuleBndrSig $2 $4 } + | '(' varid '::' ctype ')' { RuleBndrSig $2 (HsBSig $4 placeHolderBndrs) } ----------------------------------------------------------------------------- -- Warnings and deprecations (c.f. rules) @@ -1102,7 +1102,7 @@ tv_bndrs :: { [LHsTyVarBndr RdrName] } tv_bndr :: { LHsTyVarBndr RdrName } : tyvar { L1 (UserTyVar (unLoc $1) placeHolderKind) } - | '(' tyvar '::' kind ')' { LL (KindedTyVar (unLoc $2) $4 placeHolderKind) } + | '(' tyvar '::' kind ')' { LL (KindedTyVar (unLoc $2) (HsBSig $4 placeHolderBndrs) placeHolderKind) } fds :: { Located [Located (FunDep RdrName)] } : {- empty -} { noLoc [] } @@ -1135,6 +1135,7 @@ akind :: { LHsKind RdrName } : '*' { L1 $ HsTyVar (nameRdrName liftedTypeKindTyConName) } | '(' kind ')' { LL $ HsParTy $2 } | pkind { $1 } + | tyvar { L1 $ HsTyVar (unLoc $1) } pkind :: { LHsKind RdrName } -- promoted type, see Note [Promotion] : qtycon { L1 $ HsTyVar $ unLoc $1 } diff --git a/compiler/parser/ParserCore.y b/compiler/parser/ParserCore.y index 80d49430eb..872bcdefc0 100644 --- a/compiler/parser/ParserCore.y +++ b/compiler/parser/ParserCore.y @@ -375,7 +375,9 @@ ifaceUnliftedTypeKind = ifaceTcType (IfaceTc unliftedTypeKindTyConName) ifaceArrow ifT1 ifT2 = IfaceFunTy ifT1 ifT2 toHsTvBndr :: IfaceTvBndr -> LHsTyVarBndr RdrName -toHsTvBndr (tv,k) = noLoc $ KindedTyVar (mkRdrUnqual (mkTyVarOccFS tv)) (toHsKind k) placeHolderKind +toHsTvBndr (tv,k) = noLoc $ KindedTyVar (mkRdrUnqual (mkTyVarOccFS tv)) bsig placeHolderKind + where + bsig = HsBSig (toHsKind k) placeHolderBndrs ifaceExtRdrName :: Name -> RdrName ifaceExtRdrName name = mkOrig (nameModule name) (nameOccName name) diff --git a/compiler/parser/RdrHsSyn.lhs b/compiler/parser/RdrHsSyn.lhs index 59e6727535..be1f5c4f4b 100644 --- a/compiler/parser/RdrHsSyn.lhs +++ b/compiler/parser/RdrHsSyn.lhs @@ -218,7 +218,9 @@ mkTySynonym :: SrcSpan mkTySynonym loc is_family lhs rhs = do { (tc, tparams) <- checkTyClHdr lhs ; (tyvars, typats) <- checkTParams is_family lhs tparams - ; return (L loc (TySynonym tc tyvars typats rhs)) } + ; return (L loc (TySynonym { tcdLName = tc + , tcdTyVars = tyvars, tcdTyPats = typats + , tcdSynRhs = rhs, tcdFVs = placeHolderNames })) } mkTyFamily :: SrcSpan -> FamilyFlavour @@ -499,7 +501,7 @@ checkTyVars tycl_hdr tparms = mapM chk tparms where -- Check that the name space is correct! chk (L l (HsKindSig (L _ (HsTyVar tv)) k)) - | isRdrTyVar tv = return (L l (KindedTyVar tv k placeHolderKind)) + | isRdrTyVar tv = return (L l (KindedTyVar tv (HsBSig k placeHolderBndrs) placeHolderKind)) chk (L l (HsTyVar tv)) | isRdrTyVar tv = return (L l (UserTyVar tv placeHolderKind)) chk t@(L l _) @@ -636,7 +638,7 @@ checkAPat dynflags loc e0 = case e0 of let t' = case t of L _ (HsForAllTy Implicit _ (L _ []) ty) -> ty other -> other - return (SigPatIn e t') + return (SigPatIn e (HsBSig t' placeHolderBndrs)) -- n+k patterns OpApp (L nloc (HsVar n)) (L _ (HsVar plus)) _ |