+ -- This environment is how we map names mentioned in the import
+ -- list to the actual Name they correspond to, and the family
+ -- that the Name belongs to (an AvailInfo).
+ --
+ -- This env will have entries for data constructors too,
+ -- they won't make any difference because naked entities like T
+ -- in an import list map to TcOccs, not VarOccs.
+ occ_env :: OccEnv (Name,AvailInfo)
+ occ_env = mkOccEnv [ (nameOccName n, (n,a))
+ | a <- all_avails, n <- availNames a ]
+
+ lookup_lie :: Bool -> LIE RdrName -> TcRn [(LIE Name, AvailInfo)]
+ lookup_lie opt_indexedtypes (L loc ieRdr)
+ = do
+ stuff <- setSrcSpan loc $
+ case lookup_ie opt_indexedtypes ieRdr of
+ Failed err -> addErr err >> return []
+ Succeeded a -> return a
+ checkDodgyImport stuff
+ return [ (L loc ie, avail) | (ie,avail) <- stuff ]
+ where
+ -- Warn when importing T(..) if T was exported abstractly
+ checkDodgyImport stuff
+ | IEThingAll n <- ieRdr, (_, AvailTC _ [one]):_ <- stuff
+ = ifOptM Opt_WarnDodgyImports (addWarn (dodgyImportWarn n))
+ -- NB. use the RdrName for reporting the warning
+ checkDodgyImport _
+ = return ()
+
+ -- For each import item, we convert its RdrNames to Names,
+ -- and at the same time construct an AvailInfo corresponding
+ -- to what is actually imported by this item.
+ -- Returns Nothing on error.
+ -- We return a list here, because in the case of an import
+ -- item like C, if we are hiding, then C refers to *both* a
+ -- type/class and a data constructor.
+ lookup_ie :: Bool -> IE RdrName -> MaybeErr Message [(IE Name,AvailInfo)]
+ lookup_ie opt_indexedtypes ie
+ = let bad_ie = Failed (badImportItemErr iface decl_spec ie)
+
+ lookup_name rdrName =
+ case lookupOccEnv occ_env (rdrNameOcc rdrName) of
+ Nothing -> bad_ie
+ Just n -> return n
+ in
+ case ie of
+ IEVar n -> do
+ (name,avail) <- lookup_name n
+ return [(IEVar name, trimAvail avail name)]
+
+ IEThingAll tc -> do
+ (name,avail) <- lookup_name tc
+ return [(IEThingAll name, avail)]
+
+ IEThingAbs tc
+ | want_hiding -- hiding ( C )
+ -- Here the 'C' can be a data constructor
+ -- *or* a type/class, or even both
+ -> let tc_name = lookup_name tc
+ dc_name = lookup_name (setRdrNameSpace tc srcDataName)
+ in
+ case catMaybeErr [ tc_name, dc_name ] of
+ [] -> bad_ie
+ names -> return [ (IEThingAbs n, trimAvail av n)
+ | (n,av) <- names ]
+ | otherwise
+ -> do (name,avail) <- lookup_name tc
+ return [(IEThingAbs name, AvailTC name [name])]
+
+ IEThingWith n ns -> do
+ (name,avail) <- lookup_name n
+ case avail of
+ AvailTC nm subnames | nm == name -> do
+ let env = mkOccEnv [ (nameOccName s, s)
+ | s <- subnames ]
+ let mb_children = map (lookupOccEnv env . rdrNameOcc) ns
+ children <-
+ if any isNothing mb_children
+ then bad_ie
+ else return (catMaybes mb_children)
+ -- check for proper import of indexed types
+ when (not opt_indexedtypes && any isTyConName children) $
+ Failed (typeItemErr (head . filter isTyConName
+ $ children )
+ (text "in import list"))
+ return [(IEThingWith name children, AvailTC name (name:children))]
+
+ _otherwise -> bad_ie
+
+ _other -> Failed illegalImportItemErr
+ -- could be IEModuleContents, IEGroup, IEDoc, IEDocNamed
+ -- all errors.
+
+catMaybeErr :: [MaybeErr err a] -> [a]
+catMaybeErr ms = [ a | Succeeded a <- ms ]
+\end{code}