import HsSyn ( IE(..), ieName, ImportDecl(..), LImportDecl,
ForeignDecl(..), HsGroup(..), HsValBinds(..),
Sig(..), collectHsBindLocatedBinders, tyClDeclNames,
- instDeclATs,
+ instDeclATs, isIdxTyDecl,
LIE )
import RnEnv
+import RnHsDoc ( rnHsDoc )
import IfaceEnv ( ifaceExportNames )
import LoadIface ( loadSrcInterface )
import TcRnMonad hiding (LIE)
import Module
import Name ( Name, nameSrcLoc, nameOccName, nameModule, isWiredInName,
nameParent, nameParent_maybe, isExternalName,
- isBuiltInSyntax )
+ isBuiltInSyntax, isTyConName )
import NameSet
import NameEnv
import OccName ( srcDataName, isTcOcc, pprNonVarNameSpace,
import Util ( notNull )
import List ( partition )
import IO ( openFile, IOMode(..) )
-import Monad ( liftM )
+import Monad ( when )
\end{code}
*** See "THE NAMING STORY" in HsDecls ****
-Associated data types: Instances declarations may contain definitions of
-associated data types whose data constructors we need to collect, too.
-However, we need to be careful with the handling of the data type constructor
-of each asscociated type, as it is already defined in the corresponding
-class. We make a new name for it, but don't return it in the 'AvailInfo' (to
-avoid raising a duplicate declaration error; see the helper
-'unavail_main_name').
+Instances of indexed types
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+Indexed data/newtype instances contain data constructors that we need to
+collect, too. Moreover, we need to descend into the data/newtypes instances
+of associated families.
+
+We need to be careful with the handling of the type constructor of each type
+instance as the family constructor is already defined, and we want to avoid
+raising a duplicate declaration error. So, we make a new name for it, but
+don't return it in the 'AvailInfo'.
\begin{code}
getLocalDeclBinders :: TcGblEnv -> HsGroup RdrName -> RnM [Name]
-getLocalDeclBinders gbl_env (HsGroup {hs_valds = ValBindsIn val_decls val_sigs,
+getLocalDeclBinders gbl_env (HsGroup {hs_valds = ValBindsIn val_decls val_sigs,
hs_tyclds = tycl_decls,
hs_instds = inst_decls,
hs_fords = foreign_decls })
for_hs_bndrs = [nm | L _ (ForeignImport nm _ _) <- foreign_decls]
new_tc tc_decl
+ | isIdxTyDecl (unLoc tc_decl)
+ = do { main_name <- lookupFamInstDeclBndr mod main_rdr
+ ; sub_names <-
+ mappM (newTopSrcBinder mod (Just main_name)) sub_rdrs
+ ; return sub_names } -- main_name is not declared here!
+ | otherwise
= do { main_name <- newTopSrcBinder mod Nothing main_rdr
- ; sub_names <- mappM (newTopSrcBinder mod (Just main_name)) sub_rdrs
+ ; sub_names <-
+ mappM (newTopSrcBinder mod (Just main_name)) sub_rdrs
; return (main_name : sub_names) }
- where
- (main_rdr : sub_rdrs) = tyClDeclNames (unLoc tc_decl)
+ where
+ (main_rdr : sub_rdrs) = tyClDeclNames (unLoc tc_decl)
inst_ats inst_decl
- = mappM (liftM tail . new_tc) (instDeclATs (unLoc inst_decl))
- -- drop main_rdr (already declared in class)
+ = mappM new_tc (instDeclATs (unLoc inst_decl))
\end{code}
= succeed_with True [name]
get_item (IEThingWith name names)
- = succeed_with True (name:names)
+ = do { optIdxTypes <- doptM Opt_IndexedTypes
+ ; when (not optIdxTypes && any isTyConName names) $
+ addErr (typeItemErr (head . filter isTyConName $ names )
+ (text "in import list"))
+ ; succeed_with True (name:names) }
get_item (IEVar name)
= succeed_with True [name]
-
+ get_item (IEGroup _ _)
+ = succeed_with False []
+ get_item (IEDoc _)
+ = succeed_with False []
+ get_item (IEDocNamed _)
+ = succeed_with False []
\end{code}
-> RnM (Maybe [LIE Name])
rnExports Nothing = return Nothing
rnExports (Just exports)
- = do TcGblEnv { tcg_imports = ImportAvails { imp_env = imp_env } } <- getGblEnv
- let sub_env :: NameEnv [Name] -- Classify each name by its parent
- sub_env = mkSubNameEnv (foldUFM unionNameSets emptyNameSet imp_env)
- rnExport (IEVar rdrName)
- = do name <- lookupGlobalOccRn rdrName
- return (IEVar name)
- rnExport (IEThingAbs rdrName)
- = do name <- lookupGlobalOccRn rdrName
- return (IEThingAbs name)
- rnExport (IEThingAll rdrName)
- = do name <- lookupGlobalOccRn rdrName
- return (IEThingAll name)
- rnExport ie@(IEThingWith rdrName rdrNames)
- = do name <- lookupGlobalOccRn rdrName
- if isUnboundName name
- then return (IEThingWith name [])
- else do
- let env = mkOccEnv [(nameOccName s, s) | s <- subNames sub_env name]
- mb_names = map (lookupOccEnv env . rdrNameOcc) rdrNames
- if any isNothing mb_names
- then do addErr (exportItemErr ie)
- return (IEThingWith name [])
- else return (IEThingWith name (catMaybes mb_names))
- rnExport (IEModuleContents mod)
- = return (IEModuleContents mod)
- rn_exports <- mapM (wrapLocM rnExport) exports
- return (Just rn_exports)
+ = do TcGblEnv { tcg_imports = ImportAvails { imp_env = imp_env } } <- getGblEnv
+ let sub_env :: NameEnv [Name] -- Classify each name by its parent
+ sub_env = mkSubNameEnv (foldUFM unionNameSets emptyNameSet imp_env)
+ rnExport (IEVar rdrName)
+ = do name <- lookupGlobalOccRn rdrName
+ return (IEVar name)
+ rnExport (IEThingAbs rdrName)
+ = do name <- lookupGlobalOccRn rdrName
+ return (IEThingAbs name)
+ rnExport (IEThingAll rdrName)
+ = do name <- lookupGlobalOccRn rdrName
+ return (IEThingAll name)
+ rnExport ie@(IEThingWith rdrName rdrNames)
+ = do name <- lookupGlobalOccRn rdrName
+ if isUnboundName name
+ then return (IEThingWith name [])
+ else do
+ let env = mkOccEnv [(nameOccName s, s) | s <- subNames sub_env name]
+ mb_names = map (lookupOccEnv env . rdrNameOcc) rdrNames
+ if any isNothing mb_names
+ then do addErr (exportItemErr ie)
+ return (IEThingWith name [])
+ else do let names = catMaybes mb_names
+ optIdxTypes <- doptM Opt_IndexedTypes
+ when (not optIdxTypes && any isTyConName names) $
+ addErr (typeItemErr ( head
+ . filter isTyConName
+ $ names )
+ (text "in export list"))
+ return (IEThingWith name names)
+ rnExport (IEModuleContents mod)
+ = return (IEModuleContents mod)
+ rnExport (IEGroup lev doc)
+ = do rn_doc <- rnHsDoc doc
+ return (IEGroup lev rn_doc)
+ rnExport (IEDoc doc)
+ = do rn_doc <- rnHsDoc doc
+ return (IEDoc rn_doc)
+ rnExport (IEDocNamed str)
+ = return (IEDocNamed str)
+
+ rn_exports <- mapM (wrapLocM rnExport) exports
+ return (Just rn_exports)
+
+filterOutDocs = filter notDoc
+ where
+ notDoc (L _ (IEGroup _ _)) = False
+ notDoc (L _ (IEDoc _)) = False
+ notDoc (L _ (IEDocNamed _)) = False
+ notDoc _ = True
mkExportNameSet :: Bool -- False => no 'module M(..) where' header at all
-> Maybe ([LIE Name], [LIE RdrName]) -- Nothing => no explicit export list
return (Just ([noLoc (IEVar mainName)]
,[noLoc (IEVar main_RDR_Unqual)]))
-- ToDo: the 'noLoc' here is unhelpful if 'main' turns out to be out of scope
- exports_from_avail real_exports rdr_env imports
+
+ -- we don't want to include Haddock comments
+ let real_exports' = fmap (\(a,b) -> (filterOutDocs a, filterOutDocs b)) real_exports
+
+ exports_from_avail real_exports' rdr_env imports
exports_from_avail Nothing rdr_env imports
= sep [ ptext SLIT("The export item") <+> quotes (ppr export_item),
ptext SLIT("attempts to export constructors or class methods that are not visible here") ]
+typeItemErr name wherestr
+ = sep [ ptext SLIT("Using 'type' tag on") <+> quotes (ppr name) <+> wherestr,
+ ptext SLIT("Use -findexed-types to enable this extension") ]
+
exportClashErr global_env name1 name2 ie1 ie2
= vcat [ ptext SLIT("Conflicting exports for") <+> quotes (ppr occ) <> colon
, ppr_export ie1 name1