summaryrefslogtreecommitdiff
path: root/compiler/rename/RnNames.lhs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2012-03-02 16:32:58 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2012-03-02 16:32:58 +0000
commit3bf54e78cfd4b94756e3f21c00ae187f80c3341d (patch)
tree0cf67e783bc0bc8d6db57152f339509bc7065876 /compiler/rename/RnNames.lhs
parent0bc6055bdc140b35c563c0fc9a7a1b2ca92494cc (diff)
downloadhaskell-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.lhs80
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}