import HsSyn ( IE(..), ieName, ImportDecl(..), LImportDecl,
ForeignDecl(..), HsGroup(..), HsValBinds(..),
Sig(..), collectHsBindLocatedBinders, tyClDeclNames,
- instDeclATs, isIdxTyDecl,
+ instDeclATs, isFamInstDecl,
LIE )
import RnEnv
import RnHsDoc ( rnHsDoc )
import IfaceEnv ( ifaceExportNames )
-import LoadIface ( loadSrcInterface )
+import LoadIface ( loadSrcInterface, loadSysInterface )
import TcRnMonad hiding (LIE)
import PrelNames
let
imp_mod = mi_module iface
deprecs = mi_deprecs iface
- is_orph = mi_orphan iface
+ orph_iface = mi_orphan iface
has_finsts = mi_finsts iface
deps = mi_deps iface
let
-- Compute new transitive dependencies
- orphans | is_orph = ASSERT( not (imp_mod `elem` dep_orphs deps) )
- imp_mod : dep_orphs deps
- | otherwise = dep_orphs deps
+ orphans | orph_iface = ASSERT( not (imp_mod `elem` dep_orphs deps) )
+ imp_mod : dep_orphs deps
+ | otherwise = dep_orphs deps
finsts | has_finsts = ASSERT( not (imp_mod `elem` dep_finsts deps) )
imp_mod : dep_finsts deps
for_hs_bndrs = [nm | L _ (ForeignImport nm _ _) <- foreign_decls]
new_tc tc_decl
- | isIdxTyDecl (unLoc tc_decl)
+ | isFamInstDecl (unLoc tc_decl)
= do { main_name <- lookupFamInstDeclBndr mod main_rdr
; sub_names <- mappM (newTopSrcBinder mod) sub_rdrs
; return (AvailTC main_name sub_names) }
case gre_par gre of
ParentIs p -> mi_dep_fn iface p -- its parent*, is deprec'd
NoParent -> Nothing
- Nothing
- | isWiredInName name -> Nothing
- -- We have not necessarily loaded the .hi file for a
- -- wired-in name (yet), although we *could*.
- -- And we never deprecate them
-
- | otherwise -> pprPanic "lookupDeprec" (ppr name)
- -- By now all the interfaces should have been loaded
+
+ Nothing -> Nothing -- See Note [Used names with interface not loaded]
where
name = gre_name gre
\end{code}
+Note [Used names with interface not loaded]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+By now all the interfaces should have been loaded,
+because reportDeprecations happens after typechecking.
+However, it's still (just) possible to to find a used
+Name whose interface hasn't been loaded:
+
+a) It might be a WiredInName; in that case we may not load
+ its interface (although we could).
+
+b) It might be GHC.Real.fromRational, or GHC.Num.fromInteger
+ These are seen as "used" by the renamer (if -fno-implicit-prelude)
+ is on), but the typechecker may discard their uses
+ if in fact the in-scope fromRational is GHC.Read.fromRational,
+ (see tcPat.tcOverloadedLit), and the typechecker sees that the type
+ is fixed, say, to GHC.Base.Float (see Inst.lookupSimpleInst).
+ In that obscure case it won't force the interface in.
+
+In both cases we simply don't permit deprecations;
+this is, after all, wired-in stuff.
+
+
%*********************************************************
%* *
Unused names
warnDuplicateImports gres
= ifOptM Opt_WarnUnusedImports $
sequenceM_ [ warn name pr
- -- The 'head' picks the first offending group
- -- for this particular name
| GRE { gre_name = name, gre_prov = Imported imps } <- gres
, pr <- redundants imps ]
where
redundants imps
= [ (red_imp, cov_imp)
| red_imp <- imps
+ , isExplicitItem (is_item red_imp)
+ -- Complain only about redundant imports
+ -- mentioned explicitly by the user
, cov_imp <- take 1 (filter (covers red_imp) imps) ]
+ -- The 'take 1' picks the first offending group
+ -- for this particular name
-- "red_imp" is a putative redundant import
-- "cov_imp" potentially covers it
= False -- They bring into scope different qualified names
| not (is_qual red_decl) && is_qual cov_decl
= False -- Covering one doesn't bring unqualified name into scope
+ | otherwise
+ = not (isExplicitItem cov_item) -- Redundant one is selective and covering one isn't
+ || red_later -- or both are explicit; tie-break using red_later
+{-
| red_selective
= not cov_selective -- Redundant one is selective and covering one isn't
|| red_later -- Both are explicit; tie-break using red_later
= not cov_selective -- Neither import is selective
&& (is_mod red_decl == is_mod cov_decl) -- They import the same module
&& red_later -- Tie-break
+-}
where
red_loc = importSpecLoc red_imp
cov_loc = importSpecLoc cov_imp
red_later = red_loc > cov_loc
- cov_selective = selectiveImpItem cov_item
- red_selective = selectiveImpItem red_item
-
-selectiveImpItem :: ImpItemSpec -> Bool
-selectiveImpItem ImpAll = False
-selectiveImpItem (ImpSome {}) = True
-- ToDo: deal with original imports with 'qualified' and 'as M' clauses
printMinimalImports :: FiniteMap ModuleName AvailEnv -- Minimal imports
printMinimalImports imps
= ifOptM Opt_D_dump_minimal_imports $ do {
- mod_ies <- mappM to_ies (fmToList imps) ;
+ mod_ies <- initIfaceTcRn $ mappM to_ies (fmToList imps) ;
this_mod <- getModule ;
rdr_env <- getGlobalRdrEnv ;
ioToTcRn (do { h <- openFile (mkFilename this_mod) WriteMode ;
to_ies (mod, avail_env) = do ies <- mapM to_ie (availEnvElts avail_env)
returnM (mod, ies)
- to_ie :: AvailInfo -> RnM (IE Name)
+ to_ie :: AvailInfo -> IfG (IE Name)
-- The main trick here is that if we're importing all the constructors
-- we want to say "T(..)", but if we're importing only a subset we want
-- to say "T(A,B,C)". So we have to find out what the module exports.
to_ie (AvailTC n [m]) = ASSERT( n==m )
returnM (IEThingAbs n)
to_ie (AvailTC n ns)
- = loadSrcInterface doc n_mod False `thenM` \ iface ->
+ = loadSysInterface doc n_mod `thenM` \ iface ->
case [xs | (m,as) <- mi_exports iface,
- moduleName m == n_mod,
+ m == n_mod,
AvailTC x xs <- as,
x == nameOccName n] of
[xs] | all_used xs -> returnM (IEThingAll n)
where
all_used avail_occs = all (`elem` map nameOccName ns) avail_occs
doc = text "Compute minimal imports from" <+> ppr n
- n_mod = moduleName (nameModule n)
+ n_mod = nameModule n
\end{code}