import NameSet
import OccName ( OccName,
mkDFunOcc,
- occNameFlavour, moduleIfaceFlavour
+ occNameFlavour
)
+import Module ( moduleIfaceFlavour )
import TyCon ( TyCon )
import FiniteMap
import Unique ( Unique, Uniquable(..), unboundKey )
import Util ( removeDups, equivClasses, thenCmp )
import List ( nub )
import Maybes ( mapMaybe )
-import Char ( isAlphanum )
\end{code}
%*********************************************************
\begin{code}
-newImportedGlobalName :: Module -> OccName
- -> RnM s d Name
+newImportedGlobalName :: Module -> OccName -> RnM s d Name
newImportedGlobalName mod occ
= -- First check the cache
getNameSupplyRn `thenRn` \ (us, inst_ns, cache) ->
let
key = (mod,occ)
- mod_hif = moduleIfaceFlavour mod
in
case lookupFM cache key of
Nothing -> -- Miss in the cache!
-- Build a new original name, and put it in the cache
getOmitQualFn `thenRn` \ omit_fn ->
+ setModuleFlavourRn mod `thenRn` \ mod' ->
let
(us', us1) = splitUniqSupply us
uniq = uniqFromSupply us1
- name = mkGlobalName uniq mod occ (NonLocalDef ImplicitImport (omit_fn name))
+ name = mkGlobalName uniq mod' occ (NonLocalDef ImplicitImport (omit_fn name))
-- For in-scope things we improve the provenance
-- in RnNames.importsFromImportDecl
new_cache = addToFM cache key name
combine_globals ns_old ns_new -- ns_new is often short
= foldr add ns_old ns_new
where
- add n ns | all (no_conflict n) ns_old = map choose ns -- Eliminate duplicates
- | otherwise = n:ns
+ add n ns | any (is_duplicate n) ns_old = map choose ns -- Eliminate duplicates
+ | otherwise = n:ns
where
choose n' | n==n' && better_provenance n n' = n
| otherwise = n'
(NonLocalDef (UserImport _ _ _ ) _, NonLocalDef ImplicitImport _) -> True
other -> False
-no_conflict :: Name -> Name -> Bool
-no_conflict n1 n2 | isLocallyDefined n1 && isLocallyDefined n2 = False
- | otherwise = n1 == n2
- -- We complain of a conflict if one RdrName maps to two different Names,
- -- OR if one RdrName maps to the same *locally-defined* Name. The latter
- -- case is to catch two separate, local definitions of the same thing.
+is_duplicate :: Name -> Name -> Bool
+is_duplicate n1 n2 | isLocallyDefined n1 && isLocallyDefined n2 = False
+ | otherwise = n1 == n2
+ -- We treat two bindings of a locally-defined name as a duplicate,
+ -- because they might be two separate, local defns and we want to report
+ -- and error for that, *not* eliminate a duplicate.
+
+ -- On the other hand, if you import the same name from two different
+ -- import statements, we *do* want to eliminate the duplicate, not report
+ -- an error.
--
-- If a module imports itself then there might be a local defn and an imported
-- defn of the same name; in this case the names will compare as equal, but
warnUnusedTopNames names
| not opt_WarnUnusedBinds && not opt_WarnUnusedImports = returnRn () -- Don't force ns unless necessary
- | otherwise = warnUnusedBinds names
+ | otherwise = warnUnusedBinds (\ is_local -> not is_local) names
warnUnusedLocalBinds ns
| not opt_WarnUnusedBinds = returnRn ()
- | otherwise = warnUnusedBinds ns
+ | otherwise = warnUnusedBinds (\ is_local -> is_local) ns
warnUnusedMatches names
- | opt_WarnUnusedMatches = warnUnusedGroup names
+ | opt_WarnUnusedMatches = warnUnusedGroup (const True) names
| otherwise = returnRn ()
-------------------------
-warnUnusedBinds :: [Name] -> RnM s d ()
-warnUnusedBinds names
- = mapRn warnUnusedGroup groups `thenRn_`
+warnUnusedBinds :: (Bool -> Bool) -> [Name] -> RnM s d ()
+warnUnusedBinds warn_when_local names
+ = mapRn (warnUnusedGroup warn_when_local) groups `thenRn_`
returnRn ()
where
-- Group by provenance
-------------------------
-warnUnusedGroup :: [Name] -> RnM s d ()
-warnUnusedGroup []
+warnUnusedGroup :: (Bool -> Bool) -> [Name] -> RnM s d ()
+warnUnusedGroup _ []
= returnRn ()
-warnUnusedGroup names
- | is_local && not opt_WarnUnusedBinds = returnRn ()
- | not is_local && not opt_WarnUnusedImports = returnRn ()
+warnUnusedGroup emit_warning names
+ | not (emit_warning is_local) = returnRn ()
| otherwise
= pushSrcLocRn def_loc $
addWarnRn $