X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Frename%2FRnSource.lhs;h=7573f5ef26b04c2e0f429c1f22c53d8ac91de11f;hp=08e68606250f76f84bb004b1e4291c737a087fc3;hb=6a05ec5ef5373f61b7f9f5bdc344483417fa801b;hpb=374c57e586a2951377f041b9c449fd50a07c3f36 diff --git a/compiler/rename/RnSource.lhs b/compiler/rename/RnSource.lhs index 08e6860..7573f5e 100644 --- a/compiler/rename/RnSource.lhs +++ b/compiler/rename/RnSource.lhs @@ -4,9 +4,16 @@ \section[RnSource]{Main pass of renamer} \begin{code} +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module RnSource ( rnSrcDecls, addTcgDUs, - rnTyClDecls, checkModDeprec, + rnTyClDecls, rnSplice, checkTH ) where @@ -16,35 +23,40 @@ import {-# SOURCE #-} RnExpr( rnLExpr ) import HsSyn import RdrName ( RdrName, isRdrDataCon, elemLocalRdrEnv, - globalRdrEnvElts, GlobalRdrElt(..), isLocalGRE ) + globalRdrEnvElts, GlobalRdrElt(..), isLocalGRE, rdrNameOcc ) import RdrHsSyn ( extractGenericPatTyVars, extractHsRhoRdrTyVars ) import RnHsSyn import RnTypes ( rnLHsType, rnLHsTypes, rnHsSigType, rnHsTypeFVs, rnContext ) -import RnBinds ( rnTopBinds, rnMethodBinds, renameSigs, mkSigTvFn ) +import RnBinds ( rnTopBindsLHS, rnTopBindsRHS, rnMethodBinds, renameSigs, mkSigTvFn, + makeMiniFixityEnv) import RnEnv ( lookupLocalDataTcNames, lookupLocatedTopBndrRn, lookupLocatedOccRn, - lookupOccRn, lookupTopBndrRn, newLocalsRn, + lookupOccRn, newLocalsRn, bindLocatedLocalsFV, bindPatSigTyVarsFV, bindTyVarsRn, extendTyVarEnvFVRn, - bindLocalNames, checkDupNames, mapFvRn + bindLocalNames, checkDupNames, mapFvRn, lookupGreLocalRn, ) +import RnNames (importsFromLocalDecls, extendRdrEnvRn) +import HscTypes (GenAvailInfo(..)) import RnHsDoc ( rnHsDoc, rnMbLHsDoc ) import TcRnMonad -import HscTypes ( FixityEnv, FixItem(..), - Deprecations, Deprecs(..), DeprecTxt, plusDeprecs ) +import HscTypes ( FixityEnv, FixItem(..), Deprecations(..), plusDeprecs ) import Class ( FunDep ) import Name ( Name, nameOccName ) import NameSet import NameEnv -import OccName ( occEnvElts ) +import UniqFM +import OccName import Outputable import SrcLoc ( Located(..), unLoc, noLoc ) import DynFlags ( DynFlag(..) ) import Maybes ( seqMaybe ) -import Maybe ( isNothing, isJust ) +import Maybe ( isNothing ) import Monad ( liftM, when ) import BasicTypes ( Boxity(..) ) + +import ListSetOps (findDupsEq, mkLookupFun) \end{code} @rnSourceDecl@ `renames' declarations. @@ -64,94 +76,145 @@ Checks the @(..)@ etc constraints in the export list. \begin{code} -rnSrcDecls :: HsGroup RdrName -> RnM (TcGblEnv, HsGroup Name) - -rnSrcDecls (HsGroup { hs_valds = val_decls, - hs_tyclds = tycl_decls, - hs_instds = inst_decls, - hs_derivds = deriv_decls, - hs_fixds = fix_decls, - hs_depds = deprec_decls, - hs_fords = foreign_decls, - hs_defds = default_decls, - hs_ruleds = rule_decls, - hs_docs = docs }) - - = do { -- Deal with deprecations (returns only the extra deprecations) - deprecs <- rnSrcDeprecDecls deprec_decls ; - updGblEnv (\gbl -> gbl { tcg_deprecs = tcg_deprecs gbl `plusDeprecs` deprecs }) - $ do { - - -- Deal with top-level fixity decls - -- (returns the total new fixity env) - rn_fix_decls <- rnSrcFixityDecls fix_decls ; - fix_env <- rnSrcFixityDeclsEnv rn_fix_decls ; - updGblEnv (\gbl -> gbl { tcg_fix_env = fix_env }) - $ do { - - -- Rename other declarations - traceRn (text "Start rnmono") ; - (rn_val_decls, bind_dus) <- rnTopBinds val_decls ; - traceRn (text "finish rnmono" <+> ppr rn_val_decls) ; - - -- You might think that we could build proper def/use information - -- for type and class declarations, but they can be involved - -- in mutual recursion across modules, and we only do the SCC - -- analysis for them in the type checker. - -- So we content ourselves with gathering uses only; that - -- means we'll only report a declaration as unused if it isn't - -- mentioned at all. Ah well. - traceRn (text "Start rnTyClDecls") ; - (rn_tycl_decls, src_fvs1) - <- mapFvRn (wrapLocFstM rnTyClDecl) tycl_decls ; - traceRn (text "finish rnTyClDecls") ; - (rn_inst_decls, src_fvs2) - <- mapFvRn (wrapLocFstM rnSrcInstDecl) inst_decls ; - (rn_deriv_decls, src_fvs_deriv) - <- mapFvRn (wrapLocFstM rnSrcDerivDecl) deriv_decls ; - (rn_rule_decls, src_fvs3) - <- mapFvRn (wrapLocFstM rnHsRuleDecl) rule_decls ; - (rn_foreign_decls, src_fvs4) - <- mapFvRn (wrapLocFstM rnHsForeignDecl) foreign_decls ; - (rn_default_decls, src_fvs5) - <- mapFvRn (wrapLocFstM rnDefaultDecl) default_decls ; - - rn_docs <- rnDocEntities docs ; - - let { - rn_group = HsGroup { hs_valds = rn_val_decls, +-- brings the binders of the group into scope in the appropriate places; +-- does NOT assume that anything is in scope already +-- +-- the Bool determines whether (True) names in the group shadow existing +-- Unquals in the global environment (used in Template Haskell) or +-- (False) whether duplicates are reported as an error +rnSrcDecls :: Bool -> HsGroup RdrName -> RnM (TcGblEnv, HsGroup Name) + +rnSrcDecls shadowP group@(HsGroup {hs_valds = val_decls, + hs_tyclds = tycl_decls, + hs_instds = inst_decls, + hs_derivds = deriv_decls, + hs_fixds = fix_decls, + hs_depds = deprec_decls, + hs_fords = foreign_decls, + hs_defds = default_decls, + hs_ruleds = rule_decls, + hs_docs = docs }) + = do { + -- (A) Process the fixity declarations, creating a mapping from + -- FastStrings to FixItems. + -- Also checks for duplcates. + local_fix_env <- makeMiniFixityEnv fix_decls; + + -- (B) Bring top level binders (and their fixities) into scope, + -- except for the value bindings, which get brought in below. + inNewEnv (importsFromLocalDecls shadowP group local_fix_env) $ \ tcg_env -> do { + + failIfErrsM ; -- No point in continuing if (say) we have duplicate declarations + + -- (C) Extract the mapping from data constructors to field names and + -- extend the record field env. + -- This depends on the data constructors and field names being in + -- scope from (B) above + inNewEnv (extendRecordFieldEnv tycl_decls) $ \ tcg_env -> do { + + -- (D) Rename the left-hand sides of the value bindings. + -- This depends on everything from (B) being in scope, + -- and on (C) for resolving record wild cards. + -- It uses the fixity env from (A) to bind fixities for view patterns. + new_lhs <- rnTopBindsLHS local_fix_env val_decls ; + -- bind the LHSes (and their fixities) in the global rdr environment + let { lhs_binders = map unLoc $ collectHsValBinders new_lhs; + lhs_avails = map Avail lhs_binders + } ; + inNewEnv (extendRdrEnvRn shadowP (tcg_rdr_env tcg_env, tcg_fix_env tcg_env) + lhs_avails local_fix_env + >>= \ (new_rdr_env, new_fix_env) -> + return (tcg_env { tcg_rdr_env = new_rdr_env, + tcg_fix_env = new_fix_env + })) $ \tcg_env -> do { + + -- Now everything is in scope, as the remaining renaming assumes. + + -- (E) Rename type and class decls + -- (note that value LHSes need to be in scope for default methods) + -- + -- You might think that we could build proper def/use information + -- for type and class declarations, but they can be involved + -- in mutual recursion across modules, and we only do the SCC + -- analysis for them in the type checker. + -- So we content ourselves with gathering uses only; that + -- means we'll only report a declaration as unused if it isn't + -- mentioned at all. Ah well. + traceRn (text "Start rnTyClDecls") ; + (rn_tycl_decls, src_fvs1) <- rnList rnTyClDecl tycl_decls ; + + -- (F) Rename Value declarations right-hand sides + traceRn (text "Start rnmono") ; + (rn_val_decls, bind_dus) <- rnTopBindsRHS lhs_binders new_lhs ; + traceRn (text "finish rnmono" <+> ppr rn_val_decls) ; + + -- (G) Rename Fixity and deprecations + + -- rename fixity declarations and error if we try to + -- fix something from another module (duplicates were checked in (A)) + rn_fix_decls <- rnSrcFixityDecls fix_decls ; + -- rename deprec decls; + -- check for duplicates and ensure that deprecated things are defined locally + -- at the moment, we don't keep these around past renaming + rn_deprecs <- rnSrcDeprecDecls deprec_decls ; + + -- (H) Rename Everything else + + (rn_inst_decls, src_fvs2) <- rnList rnSrcInstDecl inst_decls ; + (rn_rule_decls, src_fvs3) <- rnList rnHsRuleDecl rule_decls ; + (rn_foreign_decls, src_fvs4) <- rnList rnHsForeignDecl foreign_decls ; + (rn_default_decls, src_fvs5) <- rnList rnDefaultDecl default_decls ; + (rn_deriv_decls, src_fvs6) <- rnList rnSrcDerivDecl deriv_decls ; + -- Haddock docs; no free vars + rn_docs <- mapM (wrapLocM rnDocDecl) docs ; + + -- (I) Compute the results and return + let {rn_group = HsGroup { hs_valds = rn_val_decls, hs_tyclds = rn_tycl_decls, hs_instds = rn_inst_decls, - hs_derivds = rn_deriv_decls, + hs_derivds = rn_deriv_decls, hs_fixds = rn_fix_decls, - hs_depds = [], + hs_depds = [], -- deprecs are returned in the tcg_env (see below) + -- not in the HsGroup hs_fords = rn_foreign_decls, hs_defds = rn_default_decls, hs_ruleds = rn_rule_decls, - hs_docs = rn_docs } ; + hs_docs = rn_docs } ; - other_fvs = plusFVs [src_fvs1, src_fvs2, src_fvs_deriv, src_fvs3, - src_fvs4, src_fvs5] ; - src_dus = bind_dus `plusDU` usesOnly other_fvs + other_fvs = plusFVs [src_fvs1, src_fvs2, src_fvs6, src_fvs3, + src_fvs4, src_fvs5] ; + src_dus = bind_dus `plusDU` usesOnly other_fvs; -- Note: src_dus will contain *uses* for locally-defined types -- and classes, but no *defs* for them. (Because rnTyClDecl -- returns only the uses.) This is a little -- surprising but it doesn't actually matter at all. - } ; - traceRn (text "finish rnSrc" <+> ppr rn_group) ; - traceRn (text "finish Dus" <+> ppr src_dus ) ; - tcg_env <- getGblEnv ; - return (tcg_env `addTcgDUs` src_dus, rn_group) - }}} + final_tcg_env = let tcg_env' = (tcg_env `addTcgDUs` src_dus) + in -- we return the deprecs in the env, not in the HsGroup above + tcg_env' { tcg_deprecs = tcg_deprecs tcg_env' `plusDeprecs` rn_deprecs }; + } ; + + traceRn (text "finish rnSrc" <+> ppr rn_group) ; + traceRn (text "finish Dus" <+> ppr src_dus ) ; + return (final_tcg_env , rn_group) + }}}} + +-- some utils because we do this a bunch above +-- compute and install the new env +inNewEnv :: TcM TcGblEnv -> (TcGblEnv -> TcM a) -> TcM a +inNewEnv env cont = do e <- env + setGblEnv e $ cont e rnTyClDecls :: [LTyClDecl RdrName] -> RnM [LTyClDecl Name] -rnTyClDecls tycl_decls = do - (decls', fvs) <- mapFvRn (wrapLocFstM rnTyClDecl) tycl_decls - return decls' +-- Used for external core +rnTyClDecls tycl_decls = do (decls', fvs) <- rnList rnTyClDecl tycl_decls + return decls' addTcgDUs :: TcGblEnv -> DefUses -> TcGblEnv addTcgDUs tcg_env dus = tcg_env { tcg_dus = tcg_dus tcg_env `plusDU` dus } + +rnList :: (a -> RnM (b, FreeVars)) -> [Located a] -> RnM ([Located b], FreeVars) +rnList f xs = mapFvRn (wrapLocFstM f) xs \end{code} @@ -162,21 +225,6 @@ addTcgDUs tcg_env dus = tcg_env { tcg_dus = tcg_dus tcg_env `plusDU` dus } %********************************************************* \begin{code} -rnDocEntities :: [DocEntity RdrName] -> RnM [DocEntity Name] -rnDocEntities ents - = ifErrsM (return []) $ - -- Yuk: stop if we have found errors. Otherwise - -- the rnDocEntity stuff reports the errors again. - mapM rnDocEntity ents - -rnDocEntity :: DocEntity RdrName -> RnM (DocEntity Name) -rnDocEntity (DocEntity docdecl) = do - rn_docdecl <- rnDocDecl docdecl - return (DocEntity rn_docdecl) -rnDocEntity (DeclEntity name) = do - rn_name <- lookupTopBndrRn name - return (DeclEntity rn_name) - rnDocDecl :: DocDecl RdrName -> RnM (DocDecl Name) rnDocDecl (DocCommentNext doc) = do rn_doc <- rnHsDoc doc @@ -201,48 +249,24 @@ rnDocDecl (DocGroup lev doc) = do \begin{code} rnSrcFixityDecls :: [LFixitySig RdrName] -> RnM [LFixitySig Name] +-- Rename the fixity decls, so we can put +-- the renamed decls in the renamed syntax tree +-- Errors if the thing being fixed is not defined locally. rnSrcFixityDecls fix_decls - = do fix_decls <- mapM rnFixityDecl fix_decls - return (concat fix_decls) - -rnFixityDecl :: LFixitySig RdrName -> RnM [LFixitySig Name] -rnFixityDecl (L loc (FixitySig (L nameLoc rdr_name) fixity)) - = setSrcSpan nameLoc $ + = do fix_decls <- mapM rn_decl fix_decls + return (concat fix_decls) + where + rn_decl :: LFixitySig RdrName -> RnM [LFixitySig Name] -- GHC extension: look up both the tycon and data con - -- for con-like things + -- for con-like things; hence returning a list -- If neither are in scope, report an error; otherwise -- add both to the fixity env - do names <- lookupLocalDataTcNames rdr_name - return [ L loc (FixitySig (L nameLoc name) fixity) - | name <- names ] - -rnSrcFixityDeclsEnv :: [LFixitySig Name] -> RnM FixityEnv -rnSrcFixityDeclsEnv fix_decls - = getGblEnv `thenM` \ gbl_env -> - foldlM rnFixityDeclEnv (tcg_fix_env gbl_env) - fix_decls `thenM` \ fix_env -> - traceRn (text "fixity env" <+> pprFixEnv fix_env) `thenM_` - returnM fix_env - -rnFixityDeclEnv :: FixityEnv -> LFixitySig Name -> RnM FixityEnv -rnFixityDeclEnv fix_env (L loc (FixitySig (L nameLoc name) fixity)) - = case lookupNameEnv fix_env name of - Just (FixItem _ _ loc') - -> do addLocErr (L nameLoc name) (dupFixityDecl loc') - return fix_env - Nothing - -> return (extendNameEnv fix_env name fix_item) - where fix_item = FixItem (nameOccName name) fixity nameLoc - -pprFixEnv :: FixityEnv -> SDoc -pprFixEnv env - = pprWithCommas (\ (FixItem n f _) -> ppr f <+> ppr n) - (nameEnvElts env) - -dupFixityDecl loc rdr_name - = vcat [ptext SLIT("Multiple fixity declarations for") <+> quotes (ppr rdr_name), - ptext SLIT("also at ") <+> ppr loc - ] + rn_decl (L loc (FixitySig (L name_loc rdr_name) fixity)) + = setSrcSpan name_loc $ + -- this lookup will fail if the definition isn't local + do names <- lookupLocalDataTcNames rdr_name + return [ L loc (FixitySig (L name_loc name) fixity) + | name <- names ] \end{code} @@ -252,27 +276,39 @@ dupFixityDecl loc rdr_name %* * %********************************************************* -For deprecations, all we do is check that the names are in scope. +Check that the deprecated names are defined, are defined locally, and +that there are no duplicate deprecations. + It's only imported deprecations, dealt with in RnIfaces, that we gather them together. \begin{code} +-- checks that the deprecations are defined locally, and that there are no duplicates rnSrcDeprecDecls :: [LDeprecDecl RdrName] -> RnM Deprecations rnSrcDeprecDecls [] = returnM NoDeprecs -rnSrcDeprecDecls decls - = mappM (addLocM rn_deprec) decls `thenM` \ pairs_s -> - returnM (DeprecSome (mkNameEnv (concat pairs_s))) +rnSrcDeprecDecls decls + = do { -- check for duplicates + ; mappM_ (\ (lrdr:lrdr':_) -> addLocErr lrdr (dupDeprecDecl lrdr')) deprec_rdr_dups + ; mappM (addLocM rn_deprec) decls `thenM` \ pairs_s -> + returnM (DeprecSome ((concat pairs_s))) } where rn_deprec (Deprecation rdr_name txt) + -- ensures that the names are defined locally = lookupLocalDataTcNames rdr_name `thenM` \ names -> - returnM [(name, (nameOccName name, txt)) | name <- names] + returnM [(nameOccName name, txt) | name <- names] + + -- look for duplicates among the OccNames; + -- we check that the names are defined above + -- invt: the lists returned by findDupsEq always have at least two elements + deprec_rdr_dups = findDupsEq (\ x -> \ y -> rdrNameOcc (unLoc x) == rdrNameOcc (unLoc y)) + (map (\ (L loc (Deprecation rdr_name _)) -> L loc rdr_name) decls) + +dupDeprecDecl (L loc _) rdr_name + = vcat [ptext SLIT("Multiple deprecation declarations for") <+> quotes (ppr rdr_name), + ptext SLIT("also at ") <+> ppr loc] -checkModDeprec :: Maybe DeprecTxt -> Deprecations --- Check for a module deprecation; done once at top level -checkModDeprec Nothing = NoDeprecs -checkModDeprec (Just txt) = DeprecAll txt \end{code} %********************************************************* @@ -304,7 +340,7 @@ rnHsForeignDecl (ForeignImport name ty spec) rnHsForeignDecl (ForeignExport name ty spec) = lookupLocatedOccRn name `thenM` \ name' -> rnHsTypeFVs (fo_decl_msg name) ty `thenM` \ (ty', fvs) -> - returnM (ForeignExport name' ty' spec, fvs ) + returnM (ForeignExport name' ty' spec, fvs `addOneFV` unLoc name') -- NB: a foreign export is an *occurrence site* for name, so -- we add it to the free-variable list. It might, for example, -- be imported from another module @@ -380,26 +416,15 @@ rnSrcInstDecl (InstDecl inst_ty mbinds uprags ats) Renaming of the associated types in instances. -* We raise an error if we encounter a kind signature in an instance. - \begin{code} rnATInsts :: [LTyClDecl RdrName] -> RnM ([LTyClDecl Name], FreeVars) -rnATInsts atDecls = - mapFvRn (wrapLocFstM rnATInst) atDecls +rnATInsts atDecls = rnList rnATInst atDecls where - rnATInst tydecl@TyFunction {} = - do - addErr noKindSig - rnTyClDecl tydecl + rnATInst tydecl@TyData {} = rnTyClDecl tydecl rnATInst tydecl@TySynonym {} = rnTyClDecl tydecl - rnATInst tydecl@TyData {} = - do - checkM (not . isKindSigDecl $ tydecl) $ addErr noKindSig - rnTyClDecl tydecl - rnATInst _ = - panic "RnSource.rnATInsts: not a type declaration" - -noKindSig = text "Instances cannot have kind signatures" + rnATInst tydecl = + pprPanic "RnSource.rnATInsts: invalid AT instance" + (ppr (tcdName tydecl)) \end{code} For the method bindings in class and instance decls, we extend the @@ -407,11 +432,11 @@ type variable environment iff -fglasgow-exts \begin{code} extendTyVarEnvForMethodBinds tyvars thing_inside - = doptM Opt_GlasgowExts `thenM` \ opt_GlasgowExts -> - if opt_GlasgowExts then - extendTyVarEnvFVRn (map hsLTyVarName tyvars) thing_inside - else - thing_inside + = do { scoped_tvs <- doptM Opt_ScopedTypeVariables + ; if scoped_tvs then + extendTyVarEnvFVRn (map hsLTyVarName tyvars) thing_inside + else + thing_inside } \end{code} %********************************************************* @@ -422,11 +447,10 @@ extendTyVarEnvForMethodBinds tyvars thing_inside \begin{code} rnSrcDerivDecl :: DerivDecl RdrName -> RnM (DerivDecl Name, FreeVars) -rnSrcDerivDecl (DerivDecl ty n) +rnSrcDerivDecl (DerivDecl ty) = do ty' <- rnLHsType (text "a deriving decl") ty - n' <- lookupLocatedOccRn n - let fvs = extractHsTyNames ty' `addOneFV` unLoc n' - return (DerivDecl ty' n', fvs) + let fvs = extractHsTyNames ty' + return (DerivDecl ty', fvs) \end{code} %********************************************************* @@ -558,17 +582,21 @@ rnTyClDecl (ForeignType {tcdLName = name, tcdFoType = fo_type, tcdExtName = ext_ returnM (ForeignType {tcdLName = name', tcdFoType = fo_type, tcdExtName = ext_name}, emptyFVs) +-- all flavours of type family declarations ("type family", "newtype fanily", +-- and "data family") +rnTyClDecl (tydecl@TyFamily {}) = + rnFamily tydecl bindTyVarsRn + +-- "data", "newtype", "data instance, and "newtype instance" declarations rnTyClDecl (tydecl@TyData {tcdND = new_or_data, tcdCtxt = context, tcdLName = tycon, tcdTyVars = tyvars, tcdTyPats = typatsMaybe, tcdCons = condecls, tcdKindSig = sig, tcdDerivs = derivs}) - | isKindSigDecl tydecl -- kind signature of indexed type - = rnTySig tydecl bindTyVarsRn | is_vanilla -- Normal Haskell data type decl = ASSERT( isNothing sig ) -- In normal H98 form, kind signature on the -- data type is syntactically illegal bindTyVarsRn data_doc tyvars $ \ tyvars' -> - do { tycon' <- if isIdxTyDecl tydecl + do { tycon' <- if isFamInstDecl tydecl then lookupLocatedOccRn tycon -- may be imported family else lookupLocatedTopBndrRn tycon ; context' <- rnContext data_doc context @@ -584,14 +612,14 @@ rnTyClDecl (tydecl@TyData {tcdND = new_or_data, tcdCtxt = context, extractHsCtxtTyNames context' `plusFV` plusFVs (map conDeclFVs condecls') `plusFV` deriv_fvs `plusFV` - (if isIdxTyDecl tydecl + (if isFamInstDecl tydecl then unitFV (unLoc tycon') -- type instance => use else emptyFVs)) } | otherwise -- GADT = ASSERT( none typatsMaybe ) -- GADTs cannot have type patterns for now - do { tycon' <- if isIdxTyDecl tydecl + do { tycon' <- if isFamInstDecl tydecl then lookupLocatedOccRn tycon -- may be imported family else lookupLocatedTopBndrRn tycon ; checkTc (null (unLoc context)) (badGadtStupidTheta tycon) @@ -609,7 +637,7 @@ rnTyClDecl (tydecl@TyData {tcdND = new_or_data, tcdCtxt = context, tcdCons = condecls', tcdDerivs = derivs'}, plusFVs (map conDeclFVs condecls') `plusFV` deriv_fvs `plusFV` - (if isIdxTyDecl tydecl + (if isFamInstDecl tydecl then unitFV (unLoc tycon') -- type instance => use else emptyFVs)) } @@ -632,13 +660,11 @@ rnTyClDecl (tydecl@TyData {tcdND = new_or_data, tcdCtxt = context, rn_derivs (Just ds) = rnLHsTypes data_doc ds `thenM` \ ds' -> returnM (Just ds', extractHsTyNames_s ds') -rnTyClDecl (tydecl@TyFunction {}) = - rnTySig tydecl bindTyVarsRn - +-- "type" and "type instance" declarations rnTyClDecl tydecl@(TySynonym {tcdLName = name, tcdTyVars = tyvars, tcdTyPats = typatsMaybe, tcdSynRhs = ty}) = bindTyVarsRn syn_doc tyvars $ \ tyvars' -> - do { name' <- if isIdxTyDecl tydecl + do { name' <- if isFamInstDecl tydecl then lookupLocatedOccRn name -- may be imported family else lookupLocatedTopBndrRn name ; typats' <- rnTyPats syn_doc typatsMaybe @@ -647,7 +673,7 @@ rnTyClDecl tydecl@(TySynonym {tcdLName = name, tcdTyVars = tyvars, tcdTyPats = typats', tcdSynRhs = ty'}, delFVs (map hsLTyVarName tyvars') $ fvs `plusFV` - (if isIdxTyDecl tydecl + (if isFamInstDecl tydecl then unitFV (unLoc name') -- type instance => use else emptyFVs)) } @@ -699,10 +725,8 @@ rnTyClDecl (ClassDecl {tcdCtxt = context, tcdLName = cname, ; gen_tyvars <- newLocalsRn gen_rdr_tyvars_w_locs ; rnMethodBinds (unLoc cname') (mkSigTvFn sigs') gen_tyvars mbinds } - -- Sigh. Check the Haddock docs after the methods, to avoid duplicate errors - -- Example: class { op :: a->a; op2 x = x } - -- Don't want a duplicate complait about op2 - ; docs' <- bindLocalNames (map hsLTyVarName tyvars') $ rnDocEntities docs + -- Haddock docs + ; docs' <- mapM (wrapLocM rnDocDecl) docs ; return (ClassDecl { tcdCtxt = context', tcdLName = cname', tcdTyVars = tyvars', tcdFDs = fds', tcdSigs = sigs', @@ -755,7 +779,7 @@ rnConDecl (ConDecl name expl tvs cxt details res_ty mb_doc) -- For GADT syntax, the tvs are all the quantified tyvars -- Hence the 'filter' in the ResTyH98 case only ; let not_in_scope = not . (`elemLocalRdrEnv` name_env) . unLoc - arg_tys = hsConArgs details + arg_tys = hsConDeclArgTys details implicit_tvs = case res_ty of ResTyH98 -> filter not_in_scope $ get_rdr_tvs arg_tys @@ -768,7 +792,7 @@ rnConDecl (ConDecl name expl tvs cxt details res_ty mb_doc) ; bindTyVarsRn doc tvs' $ \new_tyvars -> do { new_context <- rnContext doc cxt - ; new_details <- rnConDetails doc details + ; new_details <- rnConDeclDetails doc details ; (new_details', new_res_ty) <- rnConResult doc new_details res_ty ; return (ConDecl new_name expl new_tyvars new_context new_details' new_res_ty mb_doc') }} where @@ -786,88 +810,65 @@ rnConResult doc details (ResTyGADT ty) = do RecCon fields -> return (details, ResTyGADT ty') InfixCon {} -> panic "rnConResult" -rnConDetails doc (PrefixCon tys) +rnConDeclDetails doc (PrefixCon tys) = mappM (rnLHsType doc) tys `thenM` \ new_tys -> returnM (PrefixCon new_tys) -rnConDetails doc (InfixCon ty1 ty2) +rnConDeclDetails doc (InfixCon ty1 ty2) = rnLHsType doc ty1 `thenM` \ new_ty1 -> rnLHsType doc ty2 `thenM` \ new_ty2 -> returnM (InfixCon new_ty1 new_ty2) -rnConDetails doc (RecCon fields) - = checkDupNames doc field_names `thenM_` - mappM (rnField doc) fields `thenM` \ new_fields -> - returnM (RecCon new_fields) - where - field_names = [ name | HsRecField name _ _ <- fields ] +rnConDeclDetails doc (RecCon fields) + = do { checkDupNames doc (map cd_fld_name fields) + ; new_fields <- mappM (rnField doc) fields + ; return (RecCon new_fields) } --- Document comments are renamed to Nothing here -rnField doc (HsRecField name ty haddock_doc) +rnField doc (ConDeclField name ty haddock_doc) = lookupLocatedTopBndrRn name `thenM` \ new_name -> rnLHsType doc ty `thenM` \ new_ty -> rnMbLHsDoc haddock_doc `thenM` \ new_haddock_doc -> - returnM (HsRecField new_name new_ty new_haddock_doc) + returnM (ConDeclField new_name new_ty new_haddock_doc) --- Rename kind signatures (signatures of indexed data types/newtypes and --- signatures of type functions) +-- Rename family declarations -- -- * This function is parametrised by the routine handling the index -- variables. On the toplevel, these are defining occurences, whereas they -- are usage occurences for associated types. -- -rnTySig :: TyClDecl RdrName - -> (SDoc -> [LHsTyVarBndr RdrName] -> - ([LHsTyVarBndr Name] -> RnM (TyClDecl Name, FreeVars)) -> - RnM (TyClDecl Name, FreeVars)) - -> RnM (TyClDecl Name, FreeVars) - -rnTySig (tydecl@TyData {tcdCtxt = context, tcdLName = tycon, - tcdTyVars = tyvars, tcdTyPats = mb_typats, - tcdCons = condecls, tcdKindSig = sig, - tcdDerivs = derivs}) +rnFamily :: TyClDecl RdrName + -> (SDoc -> [LHsTyVarBndr RdrName] -> + ([LHsTyVarBndr Name] -> RnM (TyClDecl Name, FreeVars)) -> + RnM (TyClDecl Name, FreeVars)) + -> RnM (TyClDecl Name, FreeVars) + +rnFamily (tydecl@TyFamily {tcdFlavour = flavour, + tcdLName = tycon, tcdTyVars = tyvars}) bindIdxVars = - ASSERT( null condecls ) -- won't have constructors - ASSERT( isNothing mb_typats ) -- won't have type patterns - ASSERT( isNothing derivs ) -- won't have deriving - ASSERT( isJust sig ) -- will have kind signature - do { checkM (not . null $ tyvars) $ addErr needOneIdx -- #indexes >= 1 - ; bindIdxVars (ksig_doc tycon) tyvars $ \tyvars' -> do { + do { checkM (isDataFlavour flavour -- for synonyms, + || not (null tyvars)) $ addErr needOneIdx -- #indexes >= 1 + ; bindIdxVars (family_doc tycon) tyvars $ \tyvars' -> do { ; tycon' <- lookupLocatedTopBndrRn tycon - ; context' <- rnContext (ksig_doc tycon) context - ; returnM (TyData {tcdND = tcdND tydecl, tcdCtxt = context', - tcdLName = tycon', tcdTyVars = tyvars', - tcdTyPats = Nothing, tcdKindSig = sig, - tcdCons = [], tcdDerivs = Nothing}, - delFVs (map hsLTyVarName tyvars') $ - extractHsCtxtTyNames context') - } } - where - -rnTySig (tydecl@TyFunction {tcdLName = tycon, tcdTyVars = tyvars, - tcdKind = sig}) - bindIdxVars = - do { checkM (not . null $ tyvars) $ addErr needOneIdx -- #indexes >= 1 - ; bindIdxVars (ksig_doc tycon) tyvars $ \tyvars' -> do { - ; tycon' <- lookupLocatedTopBndrRn tycon - ; returnM (TyFunction {tcdLName = tycon', tcdTyVars = tyvars', - tcdIso = tcdIso tydecl, tcdKind = sig}, + ; returnM (TyFamily {tcdFlavour = flavour, tcdLName = tycon', + tcdTyVars = tyvars', tcdKind = tcdKind tydecl}, emptyFVs) } } + where + isDataFlavour DataFamily = True + isDataFlavour _ = False -ksig_doc tycon = text "In the kind signature for" <+> quotes (ppr tycon) -needOneIdx = text "Kind signature requires at least one type index" +family_doc tycon = text "In the family declaration for" <+> quotes (ppr tycon) +needOneIdx = text "Type family declarations requires at least one type index" -- Rename associated type declarations (in classes) -- --- * This can be kind signatures and (default) type function equations. +-- * This can be family declarations and (default) type instances -- rnATs :: [LTyClDecl RdrName] -> RnM ([LTyClDecl Name], FreeVars) rnATs ats = mapFvRn (wrapLocFstM rn_at) ats where - rn_at (tydecl@TyData {}) = rnTySig tydecl lookupIdxVars - rn_at (tydecl@TyFunction {}) = rnTySig tydecl lookupIdxVars - rn_at (tydecl@TySynonym {}) = + rn_at (tydecl@TyFamily {}) = rnFamily tydecl lookupIdxVars + rn_at (tydecl@TySynonym {}) = do checkM (isNothing (tcdTyPats tydecl)) $ addErr noPatterns rnTyClDecl tydecl @@ -925,6 +926,41 @@ badDataCon name %********************************************************* %* * +\subsection{Support code for type/data declarations} +%* * +%********************************************************* + +Get the mapping from constructors to fields for this module. +It's convenient to do this after the data type decls have been renamed +\begin{code} +extendRecordFieldEnv :: [LTyClDecl RdrName] -> TcM TcGblEnv +extendRecordFieldEnv decls + = do { tcg_env <- getGblEnv + ; field_env' <- foldrM get (tcg_field_env tcg_env) decls + ; return (tcg_env { tcg_field_env = field_env' }) } + where + -- we want to lookup: + -- (a) a datatype constructor + -- (b) a record field + -- knowing that they're from this module. + -- lookupLocatedTopBndrRn does this, because it does a lookupGreLocalRn, + -- which keeps only the local ones. + lookup x = do { x' <- lookupLocatedTopBndrRn x + ; return $ unLoc x'} + + get (L _ (TyData { tcdCons = cons })) env = foldrM get_con env cons + get other env = return env + + get_con (L _ (ConDecl { con_name = con, con_details = RecCon flds })) env + = do { con' <- lookup con + ; flds' <- mappM lookup (map cd_fld_name flds) + ; return $ extendNameEnv env con' flds' } + get_con other env + = return env +\end{code} + +%********************************************************* +%* * \subsection{Support code to rename types} %* * %*********************************************************