+ -- This environment is how we map names mentioned in the import
+ -- list to the actual Name they correspond to, and the name family
+ -- that the Name belongs to (the AvailInfo). The situation is
+ -- complicated by associated families, which introduce a three-level
+ -- hierachy, where class = grand parent, assoc family = parent, and
+ -- data constructors = children. The occ_env entries for associated
+ -- families needs to capture all this information; hence, we have the
+ -- third component of the environment that gives the class name (=
+ -- grand parent) in case of associated families.
+ --
+ -- 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, -- the name
+ AvailInfo, -- the export item providing the name
+ Maybe Name) -- the parent of associated types
+ occ_env = mkOccEnv_C combine [ (nameOccName n, (n, a, Nothing))
+ | a <- all_avails, n <- availNames a]
+ where
+ -- we know that (1) there are at most entries for one name, (2) their
+ -- first component is identical, (3) they are for tys/cls, and (4) one
+ -- entry has the name in its parent position (the other doesn't)
+ combine (name, AvailTC p1 subs1, Nothing)
+ (_ , AvailTC p2 subs2, Nothing)
+ = let
+ (parent, subs) = if p1 == name then (p2, subs1) else (p1, subs2)
+ in
+ (name, AvailTC name subs, Just parent)
+
+ lookup_lie :: Bool -> LIE RdrName -> TcRn [(LIE Name, AvailInfo)]
+ lookup_lie opt_typeFamilies (L loc ieRdr)
+ = do
+ stuff <- setSrcSpan loc $
+ case lookup_ie opt_typeFamilies 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. Moreover, when we import
+ -- data constructors of an associated family, we need separate
+ -- AvailInfos for the data constructors and the family (as they have
+ -- different parents). See the discussion at occ_env.
+ lookup_ie :: Bool -> IE RdrName -> MaybeErr Message [(IE Name,AvailInfo)]
+ lookup_ie opt_typeFamilies 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@(AvailTC name2 subs), mb_parent) <- lookup_name tc
+ case mb_parent of
+ -- non-associated ty/cls
+ Nothing -> return [(IEThingAll name, avail)]
+ -- associated ty
+ Just parent -> return [(IEThingAll name,
+ AvailTC name2 (subs \\ [name])),
+ (IEThingAll name, AvailTC parent [name])]
+
+ 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 [mkIEThingAbs name | name <- names]
+ | otherwise
+ -> do nameAvail <- lookup_name tc
+ return [mkIEThingAbs nameAvail]
+
+ IEThingWith tc ns -> do
+ (name, AvailTC name2 subnames, mb_parent) <- lookup_name tc
+ let
+ env = mkOccEnv [(nameOccName s, s) | s <- subnames]
+ 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 type families
+ when (not opt_typeFamilies && any isTyConName children) $
+ Failed (typeItemErr (head . filter isTyConName $ children)
+ (text "in import list"))
+ case mb_parent of
+ -- non-associated ty/cls
+ Nothing -> return [(IEThingWith name children,
+ AvailTC name (name:children))]
+ -- associated ty
+ Just parent -> return [(IEThingWith name children,
+ AvailTC name children),
+ (IEThingWith name children,
+ AvailTC parent [name])]
+
+ _other -> Failed illegalImportItemErr
+ -- could be IEModuleContents, IEGroup, IEDoc, IEDocNamed
+ -- all errors.