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/rename/RnNames.lhs | |
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/rename/RnNames.lhs')
-rw-r--r-- | compiler/rename/RnNames.lhs | 80 |
1 files changed, 13 insertions, 67 deletions
diff --git a/compiler/rename/RnNames.lhs b/compiler/rename/RnNames.lhs index b1a61db2a2..553c3ef81a 100644 --- a/compiler/rename/RnNames.lhs +++ b/compiler/rename/RnNames.lhs @@ -7,7 +7,7 @@ module RnNames ( rnImports, getLocalNonValBinders, rnExports, extendGlobalRdrEnvRn, - gresFromAvails, lookupTcdName, + gresFromAvails, reportUnusedNames, finishWarnings, ) where @@ -528,6 +528,18 @@ getLocalNonValBinders fixity_env ; names@(main_name : _) <- mapM newTopSrcBinder bndrs ; return (AvailTC main_name names) } + new_assoc :: LInstDecl RdrName -> RnM [AvailInfo] + new_assoc (L _ (FamInstDecl d)) + = do { avail <- new_ti Nothing d + ; return [avail] } + new_assoc (L _ (ClsInstDecl inst_ty _ _ ats)) + | Just (_, _, L loc cls_rdr, _) <- splitLHsInstDeclTy_maybe inst_ty + = do { cls_nm <- setSrcSpan loc $ lookupGlobalOccRn cls_rdr + ; mapM (new_ti (Just cls_nm) . unLoc) ats } + | otherwise + = return [] -- Do not crash on ill-formed instances + -- Eg instance !Show Int Trac #3811c + new_ti :: Maybe Name -> FamInstDecl RdrName -> RnM AvailInfo new_ti mb_cls ti_decl -- ONLY for type/data instances = ASSERT( isFamInstDecl ti_decl ) @@ -535,37 +547,6 @@ getLocalNonValBinders fixity_env ; sub_names <- mapM newTopSrcBinder (hsTyClDeclBinders ti_decl) ; return (AvailTC (unLoc main_name) sub_names) } -- main_name is not bound here! - - new_assoc :: LInstDecl RdrName -> RnM [AvailInfo] - new_assoc (L _ (FamInstDecl d)) - = do { avail <- new_ti Nothing d - ; return [avail] } - new_assoc (L _ (ClsInstDecl inst_ty _ _ ats)) - = do { mb_cls_nm <- get_cls_parent inst_ty - ; mapM (new_ti mb_cls_nm . unLoc) ats } - where - get_cls_parent inst_ty - | Just (_, _, L loc cls_rdr, _) <- splitLHsInstDeclTy_maybe inst_ty - = setSrcSpan loc $ do { nm <- lookupGlobalOccRn cls_rdr; return (Just nm) } - | otherwise - = return Nothing - -lookupTcdName :: Maybe Name -> TyClDecl RdrName -> RnM (Located Name) --- Used for TyData and TySynonym only, --- both ordinary ones and family instances --- See Note [Family instance binders] -lookupTcdName mb_cls tc_decl - | not (isFamInstDecl tc_decl) -- The normal case - = ASSERT2( isNothing mb_cls, ppr tc_rdr ) -- Parser prevents this - lookupLocatedTopBndrRn tc_rdr - - | Just cls <- mb_cls -- Associated type; c.f RnBinds.rnMethodBind - = wrapLocM (lookupInstDeclBndr cls (ptext (sLit "associated type"))) tc_rdr - - | otherwise -- Family instance; tc_rdr is an *occurrence* - = lookupLocatedOccRn tc_rdr - where - tc_rdr = tcdLName tc_decl \end{code} Note [Looking up family names in family instances] @@ -586,41 +567,6 @@ Solution is simple: process the type family declarations first, extend the environment, and then process the type instances. -Note [Family instance binders] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Consider - data family F a - data instance F T = X1 | X2 - -The 'data instance' decl has an *occurrence* of F (and T), and *binds* -X1 and X2. (This is unlike a normal data type declaration which would -bind F too.) So we want an AvailTC F [X1,X2]. - -Now consider a similar pair: - class C a where - data G a - instance C S where - data G S = Y1 | Y2 - -The 'data G S' *binds* Y1 and Y2, and has an *occurrence* of G. - -But there is a small complication: in an instance decl, we don't use -qualified names on the LHS; instead we use the class to disambiguate. -Thus: - module M where - import Blib( G ) - class C a where - data G a - instance C S where - data G S = Y1 | Y2 -Even though there are two G's in scope (M.G and Blib.G), the occurence -of 'G' in the 'instance C S' decl is unambiguous, becuase C has only -one associated type called G. This is exactly what happens for methods, -and it is only consistent to do the same thing for types. That's the -role of the function lookupTcdName; the (Maybe Name) give the class of -the encloseing instance decl, if any. - - %************************************************************************ %* * \subsection{Filtering imports} |