import RnNames ( getGlobalNames )
import RnSource ( rnSourceDecls, rnDecl )
import RnIfaces ( getImportedInstDecls, importDecl, getImportVersions,
- getImportedRules, loadHomeInterface, getSlurped
+ getImportedRules, loadHomeInterface, getSlurped, removeContext
)
import RnEnv ( availName, availNames, availsToNameSet,
- warnUnusedTopNames, mapFvRn,
+ warnUnusedTopNames, mapFvRn, lookupImplicitOccRn,
FreeVars, plusFVs, plusFV, unitFV, emptyFVs, isEmptyFVs
)
import Module ( Module, ModuleName, pprModule, mkSearchPath, mkThisModule )
import Name ( Name, isLocallyDefined,
NamedThing(..), ImportReason(..), Provenance(..),
- pprOccName, getNameProvenance,
+ pprOccName, nameOccName,
+ getNameProvenance,
maybeWiredInTyConName, maybeWiredInIdName, isWiredInName
)
import Id ( idType )
import NameSet
import PrelMods ( mAIN_Name, pREL_MAIN_Name )
import TysWiredIn ( unitTyCon, intTyCon, doubleTyCon, boolTyCon )
-import PrelInfo ( ioTyCon_NAME, thinAirIdNames )
+import PrelInfo ( ioTyCon_NAME, numClass_RDR, thinAirIdNames, derivingOccurrences )
import Type ( namesOfType, funTyCon )
import ErrUtils ( pprBagOfErrors, pprBagOfWarnings,
doIfSet, dumpIfSet, ghcExit
import Bag ( isEmptyBag, bagToList )
import FiniteMap ( fmToList, delListFromFM, addToFM, sizeFM, eltsFM )
import UniqSupply ( UniqSupply )
+import UniqFM ( lookupUFM )
import Util ( equivClasses )
import Maybes ( maybeToBool )
import Outputable
) `thenRn` \ (rn_local_decls, source_fvs) ->
-- SLURP IN ALL THE NEEDED DECLARATIONS
+ implicitFVs mod_name rn_local_decls `thenRn` \ implicit_fvs ->
let
- real_source_fvs = implicitFVs mod_name `plusFV` source_fvs
+ real_source_fvs = implicit_fvs `plusFV` source_fvs
-- It's important to do the "plus" this way round, so that
-- when compiling the prelude, locally-defined (), Bool, etc
-- override the implicit ones.
mentioned explicitly, but which might be needed by the type checker.
\begin{code}
-implicitFVs mod_name
- = implicit_main `plusFV`
- mkNameSet default_tys `plusFV`
- mkNameSet thinAirIdNames
+implicitFVs mod_name decls
+ = mapRn lookupImplicitOccRn implicit_occs `thenRn` \ implicit_names ->
+ returnRn (implicit_main `plusFV`
+ mkNameSet default_tys `plusFV`
+ mkNameSet thinAirIdNames `plusFV`
+ mkNameSet implicit_names)
+
where
-- Add occurrences for Int, Double, and (), because they
-- are the types to which ambigious type variables may be defaulted by
implicit_main | mod_name == mAIN_Name
|| mod_name == pREL_MAIN_Name = unitFV ioTyCon_NAME
| otherwise = emptyFVs
+
+ -- Now add extra "occurrences" for things that
+ -- the deriving mechanism, or defaulting, will later need in order to
+ -- generate code
+ implicit_occs = foldr ((++) . get) [] decls
+
+ get (DefD _) = [numClass_RDR]
+ get (TyClD (TyData _ _ _ _ _ (Just deriv_classes) _ _))
+ = concat (map get_deriv deriv_classes)
+ get other = []
+
+ get_deriv cls = case lookupUFM derivingOccurrences cls of
+ Nothing -> []
+ Just occs -> occs
\end{code}
\begin{code}
isOrphanDecl (InstD (InstDecl inst_ty _ _ _ _))
- = not (foldNameSet ((||) . isLocallyDefined) False (extractHsTyNames inst_ty))
+ = not (foldNameSet ((||) . isLocallyDefined) False (extractHsTyNames (removeContext inst_ty)))
+ -- The 'removeContext' is because of
+ -- instance Foo a => Baz T where ...
+ -- The decl is an orphan if Baz and T are both not locally defined,
+ -- even if Foo *is* locally defined
+
isOrphanDecl (RuleD (RuleDecl _ _ _ lhs _ _))
= check lhs
where
\begin{code}
reportUnusedNames gbl_env avail_env (ExportEnv export_avails _) mentioned_names
- | not (opt_WarnUnusedBinds || opt_WarnUnusedImports)
- = returnRn ()
-
- | otherwise
= let
used_names = mentioned_names `unionNameSets` availsToNameSet export_avails
-- Filter out the ones only defined implicitly
bad_guys = filter reportableUnusedName defined_but_not_used
in
- warnUnusedTopNames bad_guys `thenRn_`
- returnRn ()
+ warnUnusedTopNames bad_guys
reportableUnusedName :: Name -> Bool
reportableUnusedName name
-- Report unused explicit imports
explicitlyImported other = False
-- Don't report others
-
+
rnStats :: [RenamedHsDecl] -> RnMG ()
rnStats imp_decls
| opt_D_dump_rn_trace ||
)
import NameSet
import OccName ( OccName,
- mkDFunOcc,
+ mkDFunOcc, occNameUserString,
occNameFlavour
)
import TysWiredIn ( tupleTyCon, unboxedTupleTyCon, listTyCon )
The name cache should have the correct provenance, though.
\begin{code}
-lookupImplicitOccRn :: RdrName -> RnMS Name
+lookupImplicitOccRn :: RdrName -> RnM d Name
lookupImplicitOccRn rdr_name = mkImportedGlobalFromRdrName rdr_name
\end{code}
warnUnusedGroup :: (Bool -> Bool) -> [Name] -> RnM d ()
warnUnusedGroup emit_warning names
+ | null filtered_names = returnRn ()
| not (emit_warning is_local) = returnRn ()
| otherwise
- = case filter isReportable names of
- [] -> returnRn ()
- repnames -> warn repnames
+ = pushSrcLocRn def_loc $
+ addWarnRn $
+ sep [msg <> colon, nest 4 (fsep (punctuate comma (map ppr filtered_names)))]
where
- warn repnames = pushSrcLocRn def_loc $
- addWarnRn $
- sep [msg <> colon, nest 4 (fsep (punctuate comma (map ppr repnames)))]
-
- name1 = head names
-
- (is_local, def_loc, msg)
- = case getNameProvenance name1 of
+ filtered_names = filter reportable names
+ name1 = head filtered_names
+ (is_local, def_loc, msg)
+ = case getNameProvenance name1 of
LocalDef loc _ -> (True, loc, text "Defined but not used")
NonLocalDef (UserImport mod loc _) _ ->
(True, loc, text "Imported from" <+> quotes (ppr mod) <+>
text "but not used")
other -> (False, getSrcLoc name1, text "Strangely defined but not used")
- isReportable = not . startsWithUnderscore . occNameUserString . nameOccName
- -- Haskell 98 encourages compilers to suppress warnings about
- -- unused names in a pattern if they start with "_".
- startsWithUnderscore ('_' : _) = True
- -- Suppress warnings for names starting with an underscore
- startsWithUnderscore other = False
+ reportable name = case occNameUserString (nameOccName name) of
+ ('_' : _) -> False
+ _other -> True
+ -- Haskell 98 encourages compilers to suppress warnings about
+ -- unused names in a pattern if they start with "_".
\end{code}
\begin{code}
import OccName ( mkDefaultMethodOcc )
import BasicTypes ( TopLevelFlag(..) )
import FiniteMap ( elemFM )
-import PrelInfo ( derivingOccurrences, numClass_RDR,
- deRefStablePtr_NAME, makeStablePtr_NAME,
- bindIO_NAME
+import PrelInfo ( derivableClassKeys,
+ deRefStablePtr_NAME, makeStablePtr_NAME, bindIO_NAME
)
import Bag ( bagToList )
import List ( partition, nub )
import Outputable
import SrcLoc ( SrcLoc )
import CmdLineOpts ( opt_WarnUnusedMatches ) -- Warn of unused for-all'd tyvars
+import Unique ( Uniquable(..) )
import UniqFM ( lookupUFM )
import Maybes ( maybeToBool, catMaybes )
import Util
rnDecl (DefD (DefaultDecl tys src_loc))
= pushSrcLocRn src_loc $
rnHsTypes doc_str tys `thenRn` \ (tys', fvs) ->
- lookupImplicitOccRn numClass_RDR `thenRn` \ num ->
- returnRn (DefD (DefaultDecl tys' src_loc), fvs `addOneFV` num)
+ returnRn (DefD (DefaultDecl tys' src_loc), fvs)
where
doc_str = text "a `default' declaration"
\end{code}
rnDerivs Nothing -- derivs not specified
= returnRn (Nothing, emptyFVs)
-rnDerivs (Just ds)
- = mapFvRn rn_deriv ds `thenRn` \ (derivs, fvs) ->
- returnRn (Just derivs, fvs)
+rnDerivs (Just clss)
+ = mapRn do_one clss `thenRn` \ clss' ->
+ returnRn (Just clss', mkNameSet clss')
where
- rn_deriv clas
- = lookupOccRn clas `thenRn` \ clas_name ->
-
- -- Now add extra "occurrences" for things that
- -- the deriving mechanism will later need in order to
- -- generate code for this class.
- case lookupUFM derivingOccurrences clas_name of
- Nothing -> addErrRn (derivingNonStdClassErr clas_name) `thenRn_`
- returnRn (clas_name, unitFV clas_name)
-
- Just occs -> mapRn lookupImplicitOccRn occs `thenRn` \ names ->
- returnRn (clas_name, mkNameSet (clas_name : names))
+ do_one cls = lookupOccRn cls `thenRn` \ clas_name ->
+ checkRn (getUnique clas_name `elem` derivableClassKeys)
+ (derivingNonStdClassErr clas_name) `thenRn_`
+ returnRn clas_name
\end{code}
\begin{code}