[project @ 2003-12-19 10:34:51 by simonpj]
[ghc-hetmet.git] / ghc / compiler / rename / RnNames.lhs
index eb87208..38b3597 100644 (file)
@@ -12,18 +12,18 @@ module RnNames (
 #include "HsVersions.h"
 
 import CmdLineOpts     ( DynFlag(..) )
-import HsSyn           ( IE(..), ieName, ImportDecl(..),
+import HsSyn           ( IE(..), ieName, ImportDecl(..), LImportDecl,
                          ForeignDecl(..), HsGroup(..),
-                         collectLocatedHsBinders, tyClDeclNames 
+                         collectGroupBinders, tyClDeclNames 
                        )
-import RdrHsSyn                ( RdrNameIE, RdrNameImportDecl, main_RDR_Unqual )
 import RnEnv
 import IfaceEnv                ( lookupOrig, newGlobalBinder )
 import LoadIface       ( loadSrcInterface )
 import TcRnMonad
 
 import FiniteMap
-import PrelNames       ( pRELUDE_Name, isBuiltInSyntaxName, isUnboundName )
+import PrelNames       ( pRELUDE_Name, isBuiltInSyntaxName, isUnboundName,
+                         main_RDR_Unqual )
 import Module          ( Module, ModuleName, moduleName, mkPackageModule,
                          moduleNameUserString, isHomeModule,
                          unitModuleEnvByName, unitModuleEnv, 
@@ -32,7 +32,8 @@ import Name           ( Name, nameSrcLoc, nameOccName, nameModuleName,
                          nameParent, nameParent_maybe, isExternalName )
 import NameSet
 import NameEnv
-import OccName         ( OccName, srcDataName, isTcOcc )
+import OccName         ( OccName, srcDataName, isTcOcc, OccEnv, elemOccEnv,
+                         mkOccEnv, lookupOccEnv, emptyOccEnv, extendOccEnv )
 import HscTypes                ( GenAvailInfo(..), AvailInfo, Avails, GhciMode(..),
                          IsBootInterface, IfaceExport, 
                          availName, availNames, availsToNameSet, unQualInScope, 
@@ -46,9 +47,10 @@ import RdrName               ( RdrName, rdrNameOcc, setRdrNameSpace,
                          isLocalGRE, pprNameProvenance )
 import Outputable
 import Maybes          ( isJust, isNothing, catMaybes, mapCatMaybes )
-import SrcLoc          ( noSrcLoc )
+import SrcLoc          ( noSrcLoc, Located(..), mkGeneralSrcSpan,
+                         unLoc, noLoc )
 import ListSetOps      ( removeDups )
-import Util            ( sortLt, notNull )
+import Util            ( sortLt, notNull, isSingleton )
 import List            ( partition, insert )
 import IO              ( openFile, IOMode(..) )
 \end{code}
@@ -62,7 +64,7 @@ import IO             ( openFile, IOMode(..) )
 %************************************************************************
 
 \begin{code}
-rnImports :: [RdrNameImportDecl]
+rnImports :: [LImportDecl RdrName]
          -> RnM (GlobalRdrEnv, ImportAvails)
 
 rnImports imports
@@ -70,12 +72,11 @@ rnImports imports
                -- Do the non {- SOURCE -} ones first, so that we get a helpful
                -- warning for {- SOURCE -} ones that are unnecessary
        getModule                               `thenM` \ this_mod ->
-       getSrcLocM                              `thenM` \ loc ->
        doptM Opt_NoImplicitPrelude             `thenM` \ opt_no_prelude -> 
        let
-         all_imports        = mk_prel_imports this_mod loc opt_no_prelude ++ imports
+         all_imports        = mk_prel_imports this_mod opt_no_prelude ++ imports
          (source, ordinary) = partition is_source_import all_imports
-         is_source_import (ImportDecl _ is_boot _ _ _ _) = is_boot
+         is_source_import (L _ (ImportDecl _ is_boot _ _ _)) = is_boot
 
          get_imports = importsFromImportDecl this_mod
        in
@@ -97,39 +98,43 @@ rnImports imports
        -- NB: opt_NoImplicitPrelude is slightly different to import Prelude ();
        -- because the former doesn't even look at Prelude.hi for instance 
        -- declarations, whereas the latter does.
-    mk_prel_imports this_mod loc no_prelude
+    mk_prel_imports this_mod no_prelude
        |  moduleName this_mod == pRELUDE_Name
        || explicit_prelude_import
        || no_prelude
        = []
 
-       | otherwise = [preludeImportDecl loc]
+       | otherwise = [preludeImportDecl]
 
     explicit_prelude_import
-      = notNull [ () | (ImportDecl mod _ _ _ _ _) <- imports, 
-                      mod == pRELUDE_Name ]
+      = notNull [ () | L _ (ImportDecl mod _ _ _ _) <- imports, 
+                      unLoc mod == pRELUDE_Name ]
 
-preludeImportDecl loc
-  = ImportDecl pRELUDE_Name
+preludeImportDecl
+  = L loc $
+       ImportDecl (L loc pRELUDE_Name)
               False {- Not a boot interface -}
               False    {- Not qualified -}
               Nothing  {- No "as" -}
               Nothing  {- No import list -}
-              loc
+  where
+    loc = mkGeneralSrcSpan FSLIT("Implicit import declaration")
 \end{code}
        
 \begin{code}
 importsFromImportDecl :: Module
-                     -> RdrNameImportDecl
+                     -> LImportDecl RdrName
                      -> RnM (GlobalRdrEnv, ImportAvails)
 
 importsFromImportDecl this_mod
-       (ImportDecl imp_mod_name want_boot qual_only as_mod imp_details iloc)
-  = addSrcLoc iloc $
+       (L loc (ImportDecl loc_imp_mod_name want_boot qual_only as_mod imp_details))
+  = 
+    addSrcSpan loc $
 
        -- If there's an error in loadInterface, (e.g. interface
        -- file not found) we get lots of spurious errors from 'filterImports'
     let
+       imp_mod_name = unLoc loc_imp_mod_name
        this_mod_name = moduleName this_mod
        doc = ppr imp_mod_name <+> ptext SLIT("is directly imported")
     in
@@ -169,11 +174,19 @@ importsFromImportDecl this_mod
        --         import {-# SOURCE #-} A( AType )
        --
        -- then you'll get a 'B does not export AType' message.  Oh well.
+
+       qual_mod_name = case as_mod of
+                         Nothing           -> imp_mod_name
+                         Just another_name -> another_name
+       imp_spec  = ImportSpec { is_mod = imp_mod_name, is_qual = qual_only,  
+                                is_loc = loc, is_as = qual_mod_name }
+       mk_deprec = mi_dep_fn iface
     in
-    exportsToAvails filtered_exports                   `thenM` \ avails ->
 
-       -- Filter the imports according to the import list
-    filterImports imp_mod want_boot imp_details avails `thenM` \ (filtered_avails, explicits) ->
+       -- Get the total imports, and filter them according to the import list
+    exportsToAvails filtered_exports           `thenM` \ total_avails ->
+    filterImports iface imp_spec
+                 imp_details total_avails      `thenM` \ (avail_env, gbl_env) ->
 
     let
        -- Compute new transitive dependencies
@@ -204,24 +217,10 @@ importsFromImportDecl this_mod
                        _ -> Nothing            -- Everything is imported, 
                                                -- (or almost everything [hiding])
 
-       qual_mod_name = case as_mod of
-                         Nothing           -> imp_mod_name
-                         Just another_name -> another_name
-       
        -- unqual_avails is the Avails that are visible in *unqualified* form
        -- We need to know this so we know what to export when we see
        --      module M ( module P ) where ...
        -- Then we must export whatever came from P unqualified.
-       imp_spec  = ImportSpec { is_mod = imp_mod_name, is_qual = qual_only,  
-                                is_loc = iloc , is_as = qual_mod_name }
-       mk_deprec = mi_dep_fn iface
-       gres      = [ GRE { gre_name = name, 
-                           gre_prov = Imported [imp_spec] (name `elemNameSet` explicits),
-                           gre_deprec = mk_deprec name }
-                       | avail <- filtered_avails, name <- availNames avail ]
-       gbl_env   = mkGlobalRdrEnv gres
-                 
-       avail_env = mkAvailEnv filtered_avails
        imports   = ImportAvails { 
                        imp_qual     = unitModuleEnvByName qual_mod_name avail_env,
                        imp_env      = avail_env,
@@ -361,9 +360,8 @@ importsFromLocalDecls group
 %*                                                     *
 %*********************************************************
 
-@getLocalDeclBinders@ returns the names for a @RdrNameHsDecl@.  It's
-used for both source code (from @importsFromLocalDecls@) and interface
-files (@loadDecl@ calls @getTyClDeclBinders@).
+@getLocalDeclBinders@ returns the names for an @HsDecl@.  It's
+used for source code.
 
        *** See "THE NAMING STORY" in HsDecls ****
 
@@ -384,15 +382,15 @@ getLocalDeclBinders mod (HsGroup {hs_valds = val_decls,
     new_simple rdr_name = newTopSrcBinder mod Nothing rdr_name `thenM` \ name ->
                          returnM (Avail name)
 
-    val_hs_bndrs = collectLocatedHsBinders val_decls
-    for_hs_bndrs = [(nm,loc) | ForeignImport nm _ _ _ loc <- foreign_decls]
+    val_hs_bndrs = collectGroupBinders val_decls
+    for_hs_bndrs = [nm | L _ (ForeignImport nm _ _ _) <- foreign_decls]
 
     new_tc tc_decl 
        = newTopSrcBinder mod Nothing main_rdr                  `thenM` \ main_name ->
          mappM (newTopSrcBinder mod (Just main_name)) sub_rdrs `thenM` \ sub_names ->
          returnM (AvailTC main_name (main_name : sub_names))
        where
-         (main_rdr : sub_rdrs) = tyClDeclNames tc_decl
+         (main_rdr : sub_rdrs) = tyClDeclNames (unLoc tc_decl)
 \end{code}
 
 
@@ -406,77 +404,97 @@ getLocalDeclBinders mod (HsGroup {hs_valds = val_decls,
 available, and filters it through the import spec (if any).
 
 \begin{code}
-filterImports :: Module                                -- The module being imported
-             -> IsBootInterface                -- Tells whether it's a {-# SOURCE #-} import
-             -> Maybe (Bool, [RdrNameIE])      -- Import spec; True => hiding
+filterImports :: ModIface
+             -> ImportSpec                     -- The span for the entire import decl
+             -> Maybe (Bool, [Located (IE RdrName)])   -- Import spec; True => hiding
              -> [AvailInfo]                    -- What's available
-             -> RnM ([AvailInfo],              -- What's imported
-                      NameSet)                 -- What was imported explicitly
+             -> RnM (AvailEnv,                 -- What's imported
+                     GlobalRdrEnv)             -- ...in two forms
 
        -- Complains if import spec mentions things that the module doesn't export
         -- Warns/informs if import spec contains duplicates.
-filterImports mod from Nothing imports
-  = returnM (imports, emptyNameSet)
-
-filterImports mod from (Just (want_hiding, import_items)) total_avails
-  = mappM get_item import_items                `thenM` \ avails_w_explicits_s ->
+mkGenericRdrEnv iface imp_spec avails
+  = mkGlobalRdrEnv [ GRE { gre_name = name, gre_prov = Imported [imp_spec] False,
+                          gre_deprec = mi_dep_fn iface name }
+                  | avail <- avails, name <- availNames avail ]
+                       
+filterImports iface imp_spec Nothing total_avails
+  = returnM (mkAvailEnv total_avails, mkGenericRdrEnv iface imp_spec total_avails)
+
+filterImports iface imp_spec (Just (want_hiding, import_items)) total_avails
+  = mapAndUnzipM (addLocM get_item) import_items       `thenM` \ (avails, gres) ->
     let
-       (item_avails, explicits_s) = unzip (concat avails_w_explicits_s)
-       explicits                  = foldl addListToNameSet emptyNameSet explicits_s
+       all_avails = foldr plusAvailEnv     emptyAvailEnv     avails
+       rdr_env    = foldr plusGlobalRdrEnv emptyGlobalRdrEnv gres
     in
-    if want_hiding then
-       let     -- All imported; item_avails to be hidden
-          hidden = availsToNameSet item_avails
-          keep n = not (n `elemNameSet` hidden)
-       in
-       returnM (pruneAvails keep total_avails, emptyNameSet)
+    if not want_hiding then
+       returnM (all_avails, rdr_env)
     else
-       -- Just item_avails imported; nothing to be hidden
-       returnM (item_avails, explicits)
+    let        -- Hide stuff in all_avails
+          hidden = availsToNameSet (availEnvElts all_avails)
+          keep n = not (n `elemNameSet` hidden)
+          pruned_avails = pruneAvails keep total_avails
+    in
+    returnM (mkAvailEnv pruned_avails, mkGenericRdrEnv iface imp_spec pruned_avails)
   where
-    import_fm :: FiniteMap OccName AvailInfo
-    import_fm = listToFM [ (nameOccName name, avail) 
+    import_fm :: OccEnv AvailInfo
+    import_fm = mkOccEnv [ (nameOccName name, avail) 
                         | avail <- total_avails,
                           name  <- availNames avail]
        -- Even though availNames returns data constructors too,
        -- they won't make any difference because naked entities like T
        -- in an import list map to TcOccs, not VarOccs.
 
-    bale_out item = addErr (badImportItemErr mod from item)    `thenM_`
-                   returnM []
+    bale_out item = addErr (badImportItemErr iface imp_spec item)      `thenM_`
+                   returnM (emptyAvailEnv, emptyGlobalRdrEnv)
+
+    mk_deprec = mi_dep_fn iface
 
-    get_item :: RdrNameIE -> RnM [(AvailInfo, [Name])]
-       -- Empty list for a bad item.
-       -- Singleton is typical case.
+    succeed_with :: Bool -> AvailInfo -> RnM (AvailEnv, GlobalRdrEnv)
+    succeed_with all_explicit avail
+      = do { loc <- getSrcSpanM
+          ; returnM (unitAvailEnv avail, 
+                     mkGlobalRdrEnv (map (mk_gre loc) (availNames avail))) }
+      where
+       mk_gre loc name = GRE { gre_name = name, 
+                               gre_prov = Imported [this_imp_spec loc] (explicit name), 
+                               gre_deprec = mk_deprec name }
+       this_imp_spec loc = imp_spec { is_loc = loc }
+       explicit name = all_explicit || name == main_name
+       main_name = availName avail
+
+    get_item :: IE RdrName -> RnM (AvailEnv, GlobalRdrEnv)
+       -- Empty result for a bad item.
+       -- Singleton result is typical case.
        -- Can have two when we are hiding, and mention C which might be
        --      both a class and a data constructor.  
-       -- The [Name] is the list of explicitly-mentioned names
-    get_item item@(IEModuleContents _) = bale_out item
+    get_item item@(IEModuleContents _) 
+      = bale_out item
 
-    get_item item@(IEThingAll _)
+    get_item item@(IEThingAll tc)
       = case check_item item of
          Nothing                    -> bale_out item
          Just avail@(AvailTC _ [n]) ->         -- This occurs when you import T(..), but
                                                -- only export T abstractly.  The single [n]
                                                -- in the AvailTC is the type or class itself
-                                       ifOptM Opt_WarnMisc (addWarn (dodgyImportWarn mod item))        `thenM_`
-                                       returnM [(avail, [availName avail])]
-         Just avail                 -> returnM [(avail, [availName avail])]
+                                       ifOptM Opt_WarnMisc (addWarn (dodgyImportWarn tc))      `thenM_`
+                                       succeed_with False avail
+         Just avail                 -> succeed_with False avail
 
     get_item item@(IEThingAbs n)
       | want_hiding    -- hiding( C ) 
                        -- Here the 'C' can be a data constructor *or* a type/class
       = case catMaybes [check_item item, check_item (IEVar data_n)] of
-               []     -> bale_out item
-               avails -> returnM [(a, []) | a <- avails]
-                               -- The 'explicits' list is irrelevant when hiding
+         []     -> bale_out item
+         avails -> returnM (mkAvailEnv avails, emptyGlobalRdrEnv)
+                       -- The GlobalRdrEnv result is irrelevant when hiding
       where
        data_n = setRdrNameSpace n srcDataName
 
     get_item item
       = case check_item item of
          Nothing    -> bale_out item
-         Just avail -> returnM [(avail, availNames avail)]
+         Just avail -> succeed_with True avail
 
     check_item item
       | isNothing maybe_in_import_avails ||
@@ -488,7 +506,7 @@ filterImports mod from (Just (want_hiding, import_items)) total_avails
                
       where
        wanted_occ             = rdrNameOcc (ieName item)
-       maybe_in_import_avails = lookupFM import_fm wanted_occ
+       maybe_in_import_avails = lookupOccEnv import_fm wanted_occ
 
        Just avail             = maybe_in_import_avails
        maybe_filtered_avail   = filterAvail item avail
@@ -496,7 +514,7 @@ filterImports mod from (Just (want_hiding, import_items)) total_avails
 \end{code}
 
 \begin{code}
-filterAvail :: RdrNameIE       -- Wanted
+filterAvail :: IE RdrName      -- Wanted
            -> AvailInfo        -- Available
            -> Maybe AvailInfo  -- Resulting available; 
                                -- Nothing if (any of the) wanted stuff isn't there
@@ -558,23 +576,23 @@ type ExportAccum  -- The type of the accumulating parameter of
        ExportOccMap,           -- Tracks exported occurrence names
        AvailEnv)               -- The accumulated exported stuff, kept in an env
                                --   so we can common-up related AvailInfos
-emptyExportAccum = ([], emptyFM, emptyAvailEnv) 
+emptyExportAccum = ([], emptyOccEnv, emptyAvailEnv) 
 
-type ExportOccMap = FiniteMap OccName (Name, RdrNameIE)
+type ExportOccMap = OccEnv (Name, IE RdrName)
        -- Tracks what a particular exported OccName
        --   in an export list refers to, and which item
        --   it came from.  It's illegal to export two distinct things
        --   that have the same occurrence name
 
 
-exportsFromAvail :: Maybe Module       -- Nothing => no 'module M(..) where' header at all
-                -> Maybe [RdrNameIE]   -- Nothing => no explicit export list
+exportsFromAvail :: Bool  -- False => no 'module M(..) where' header at all
+                -> Maybe [Located (IE RdrName)] -- Nothing => no explicit export list
                 -> RnM Avails
        -- Complains if two distinct exports have same OccName
         -- Warns about identical exports.
        -- Complains about exports items not in scope
 
-exportsFromAvail maybe_mod exports
+exportsFromAvail explicit_mod exports
  = do { TcGblEnv { tcg_rdr_env = rdr_env, 
                   tcg_imports = imports } <- getGblEnv ;
 
@@ -586,13 +604,12 @@ exportsFromAvail maybe_mod exports
        --         in interactive mode
        ghci_mode <- getGhciMode ;
        let { real_exports 
-               = case maybe_mod of
-                   Just mod -> exports
-                   Nothing | ghci_mode == Interactive -> Nothing
-                           | otherwise                -> Just [IEVar main_RDR_Unqual] } ;
-
+               | explicit_mod             = exports
+               | ghci_mode == Interactive = Nothing
+               | otherwise                = Just [noLoc (IEVar main_RDR_Unqual)] } ;
        exports_from_avail real_exports rdr_env imports }
 
+
 exports_from_avail Nothing rdr_env
                   imports@(ImportAvails { imp_env = entity_avail_env })
  =     -- Export all locally-defined things
@@ -610,13 +627,15 @@ exports_from_avail Nothing rdr_env
 exports_from_avail (Just export_items) rdr_env
                   (ImportAvails { imp_qual = mod_avail_env, 
                                   imp_env  = entity_avail_env }) 
-  = foldlM exports_from_item emptyExportAccum
+  = foldlM (exports_from_litem) emptyExportAccum
            export_items                        `thenM` \ (_, _, export_avail_map) ->
     returnM (nameEnvElts export_avail_map)
 
   where
-    exports_from_item :: ExportAccum -> RdrNameIE -> RnM ExportAccum
+    exports_from_litem :: ExportAccum -> Located (IE RdrName) -> RnM ExportAccum
+    exports_from_litem acc = addLocM (exports_from_item acc)
 
+    exports_from_item :: ExportAccum -> IE RdrName -> RnM ExportAccum
     exports_from_item acc@(mods, occs, avails) ie@(IEModuleContents mod)
        | mod `elem` mods       -- Duplicate export of M
        = do { warn_dup_exports <- doptM Opt_WarnDuplicateExports ;
@@ -665,7 +684,7 @@ exports_from_avail (Just export_items) rdr_env
            Just export_avail ->        
 
                -- Phew!  It's OK!  Now to check the occurrence stuff!
-         warnIf (not (ok_item ie avail)) (dodgyExportWarn ie)  `thenM_`
+         checkForDodgyExport ie avail                          `thenM_`
           check_occs ie occs export_avail                      `thenM` \ occs' ->
          returnM (mods, occs', addAvail avails export_avail)
          }
@@ -688,22 +707,22 @@ in_scope :: GlobalRdrEnv -> Name -> Bool
 -- regardless of whether it's ambiguous or not
 in_scope env n = any unQualOK (lookupGRE_Name env n)
 
-
 -------------------------------
-ok_item (IEThingAll _) (AvailTC _ [n]) = False
+checkForDodgyExport :: IE RdrName -> AvailInfo -> RnM ()
+checkForDodgyExport (IEThingAll tc) (AvailTC _ [n]) = addWarn (dodgyExportWarn tc)
   -- This occurs when you import T(..), but
   -- only export T abstractly.  The single [n]
   -- in the AvailTC is the type or class itself
-ok_item _ _ = True
+checkForDodgyExport _ _ = return ()
 
 -------------------------------
-check_occs :: RdrNameIE -> ExportOccMap -> AvailInfo -> RnM ExportOccMap
+check_occs :: IE RdrName -> ExportOccMap -> AvailInfo -> RnM ExportOccMap
 check_occs ie occs avail 
   = foldlM check occs (availNames avail)
   where
     check occs name
-      = case lookupFM occs name_occ of
-         Nothing -> returnM (addToFM occs name_occ (name, ie))
+      = case lookupOccEnv occs name_occ of
+         Nothing -> returnM (extendOccEnv occs name_occ (name, ie))
 
          Just (name', ie') 
            | name == name'     -- Duplicate export
@@ -731,6 +750,7 @@ reportUnusedNames gbl_env
   = warnUnusedModules unused_imp_mods  `thenM_`
     warnUnusedTopBinds bad_locals      `thenM_`
     warnUnusedImports bad_imports      `thenM_`
+    warnDuplicateImports dup_imps      `thenM_`
     printMinimalImports minimal_imports
   where
     used_names, all_used_names :: NameSet
@@ -747,6 +767,7 @@ reportUnusedNames gbl_env
     defined_and_used, defined_but_not_used :: [GlobalRdrElt]
     (defined_and_used, defined_but_not_used) = partition is_used defined_names
 
+    dup_imps = filter isDupImport defined_and_used
     is_used gre = gre_name gre `elemNameSet` all_used_names
     
     -- Filter out the ones that are 
@@ -824,7 +845,7 @@ reportUnusedNames gbl_env
 
     -- unused_imp_mods are the directly-imported modules 
     -- that are not mentioned in minimal_imports1
-    -- [Note: not 'minimal_imports', because that includes direcly-imported
+    -- [Note: not 'minimal_imports', because that includes directly-imported
     --       modules even if we use nothing from them; see notes above]
     unused_imp_mods = [m | m <- direct_import_mods,
                       isNothing (lookupFM minimal_imports1 m),
@@ -838,6 +859,18 @@ reportUnusedNames gbl_env
     module_unused mod = mod `elem` unused_imp_mods
 
 
+isDupImport (GRE {gre_prov = Imported imp_spec True}) = not (isSingleton imp_spec)
+isDupImport other                                    = False
+                     
+warnDuplicateImports :: [GlobalRdrElt] -> RnM ()
+warnDuplicateImports gres
+  = ifOptM Opt_WarnUnusedImports (mapM_ warn gres)
+  where
+    warn (GRE { gre_name = name, gre_prov = Imported imps _ })
+       = addWarn ((quotes (ppr name) <+> ptext SLIT("is imported more than once:")) 
+              $$ nest 2 (vcat (map ppr imps)))
+                             
+
 -- ToDo: deal with original imports with 'qualified' and 'as M' clauses
 printMinimalImports :: FiniteMap ModuleName AvailEnv   -- Minimal imports
                    -> RnM ()
@@ -896,19 +929,18 @@ printMinimalImports imps
 %************************************************************************
 
 \begin{code}
-badImportItemErr mod from ie
-  = sep [ptext SLIT("Module"), quotes (ppr mod), source_import,
+badImportItemErr iface imp_spec ie
+  = sep [ptext SLIT("Module"), quotes (ppr (is_mod imp_spec)), source_import,
         ptext SLIT("does not export"), quotes (ppr ie)]
   where
-    source_import = case from of
-                     True  -> ptext SLIT("(hi-boot interface)")
-                     other -> empty
+    source_import | mi_boot iface = ptext SLIT("(hi-boot interface)")
+                 | otherwise     = empty
 
-dodgyImportWarn mod item = dodgyMsg (ptext SLIT("import")) item
-dodgyExportWarn     item = dodgyMsg (ptext SLIT("export")) item
+dodgyImportWarn item = dodgyMsg (ptext SLIT("import")) item
+dodgyExportWarn item = dodgyMsg (ptext SLIT("export")) item
 
-dodgyMsg kind item@(IEThingAll tc)
-  = sep [ ptext SLIT("The") <+> kind <+> ptext SLIT("item") <+> quotes (ppr item),
+dodgyMsg kind tc
+  = sep [ ptext SLIT("The") <+> kind <+> ptext SLIT("item") <+> quotes (ppr (IEThingAll tc)),
          ptext SLIT("suggests that") <+> quotes (ppr tc) <+> ptext SLIT("has constructor or class methods"),
          ptext SLIT("but it has none; it is a type synonym or abstract type or class") ]