FIX #2197: an update frame might point to an IND_OLDGEN
[ghc-hetmet.git] / compiler / rename / RnEnv.lhs
index 508bea6..f6f725f 100644 (file)
@@ -25,16 +25,19 @@ module RnEnv (
        getLookupOccRn,
 
        newLocalsRn, newIPNameRn,
-       bindLocalNames, bindLocalNamesFV, bindLocalNamesFV_WithFixities,
+       bindLocalNames, bindLocalNamesFV, 
+       MiniFixityEnv, emptyFsEnv, extendFsEnv, lookupFsEnv,
+       bindLocalNamesFV_WithFixities,
        bindLocatedLocalsFV, bindLocatedLocalsRn,
        bindSigTyVarsFV, bindPatSigTyVars, bindPatSigTyVarsFV,
        bindTyVarsRn, extendTyVarEnvFVRn,
-       bindLocalFixities,
 
-       checkDupNames, checkShadowing, mapFvRn, mapFvRnCPS,
+       checkDupRdrNames, checkDupNames, checkShadowedNames, 
+       checkDupAndShadowedRdrNames,
+       mapFvRn, mapFvRnCPS,
        warnUnusedMatches, warnUnusedModules, warnUnusedImports, 
        warnUnusedTopBinds, warnUnusedLocalBinds,
-       dataTcOccs, unknownNameErr,
+       dataTcOccs, unknownNameErr
     ) where
 
 #include "HsVersions.h"
@@ -45,30 +48,20 @@ import HsSyn                ( FixitySig(..), HsExpr(..), SyntaxExpr, SyntaxTable,
                          LHsTyVarBndr, LHsType, 
                          Fixity, hsLTyVarLocNames, replaceTyVarName )
 import RdrHsSyn                ( extractHsTyRdrTyVars )
-import RdrName         ( RdrName, isQual, isUnqual, isOrig_maybe,
-                         isQual_maybe,
-                         mkRdrUnqual, setRdrNameSpace, rdrNameOcc,
-                         pprGlobalRdrEnv, lookupGRE_RdrName, 
-                         isExact_maybe, isSrcRdrName,
-                         Parent(..),
-                         GlobalRdrElt(..), GlobalRdrEnv, lookupGlobalRdrEnv, 
-                         isLocalGRE, extendLocalRdrEnv, elemLocalRdrEnv, lookupLocalRdrEnv,
-                         Provenance(..), pprNameProvenance,
-                         importSpecLoc, importSpecModule
-                       )
+import RdrName
 import HscTypes                ( availNames, ModIface(..), FixItem(..), lookupFixity)
 import TcEnv           ( tcLookupDataCon )
 import TcRnMonad
 import Name            ( Name, nameIsLocalOrFrom, mkInternalName, isWiredInName,
-                         nameSrcLoc, nameOccName, nameModule, isExternalName )
+                         nameSrcLoc, nameSrcSpan, nameOccName, nameModule, isExternalName )
 import NameSet
 import NameEnv
-import UniqFM
+import LazyUniqFM
 import DataCon         ( dataConFieldLabels )
-import OccName         ( tcName, isDataOcc, pprNonVarNameSpace, occNameSpace,
-                         reportIfUnused, occNameFS )
+import OccName
 import Module          ( Module, ModuleName )
-import PrelNames       ( mkUnboundName, rOOT_MAIN, iNTERACTIVE, consDataConKey, hasKey )
+import PrelNames       ( mkUnboundName, rOOT_MAIN, iNTERACTIVE, 
+                         consDataConKey, hasKey, forall_tv_RDR )
 import UniqSupply
 import BasicTypes      ( IPName, mapIPName, Fixity )
 import SrcLoc          ( SrcSpan, srcSpanStart, Located(..), eqLocated, unLoc,
@@ -78,9 +71,30 @@ import Util
 import Maybes
 import ListSetOps      ( removeDups )
 import List            ( nubBy )
-import Monad           ( when )
 import DynFlags
 import FastString
+import Control.Monad
+\end{code}
+
+\begin{code}
+-- XXX
+thenM :: Monad a => a b -> (b -> a c) -> a c
+thenM = (>>=)
+
+thenM_ :: Monad a => a b -> a c -> a c
+thenM_ = (>>)
+
+returnM :: Monad m => a -> m a
+returnM = return
+
+mappM :: (Monad m) => (a -> m b) -> [a] -> m [b]
+mappM = mapM
+
+mappM_ :: (Monad m) => (a -> m b) -> [a] -> m ()
+mappM_ = mapM_
+
+checkM :: Monad m => Bool -> m () -> m ()
+checkM = unless
 \end{code}
 
 %*********************************************************
@@ -356,7 +370,7 @@ lookupFamInstDeclBndr mod lrdr_name@(L _ rdr_name)
 getLookupOccRn :: RnM (Name -> Maybe Name)
 getLookupOccRn
   = getLocalRdrEnv                     `thenM` \ local_env ->
-    return (lookupLocalRdrEnv local_env . mkRdrUnqual . nameOccName)
+    return (lookupLocalRdrOcc local_env . nameOccName)
 
 lookupLocatedOccRn :: Located RdrName -> RnM (Located Name)
 lookupLocatedOccRn = wrapLocM lookupOccRn
@@ -514,57 +528,36 @@ lookupQualifiedName rdr_name
 %*********************************************************
 
 \begin{code}
-lookupLocalDataTcNames :: RdrName -> RnM [Name]
--- GHC extension: look up both the tycon and data con 
--- for con-like things
--- Complain if neither is in scope
-lookupLocalDataTcNames rdr_name
-  | Just n <- isExact_maybe rdr_name   
-       -- Special case for (:), which doesn't get into the GlobalRdrEnv
-  = return [n] -- For this we don't need to try the tycon too
-  | otherwise
-  = do { mb_gres <- mapM lookupGreLocalRn (dataTcOccs rdr_name)
-       ; case [gre_name gre | Just gre <- mb_gres] of
-           [] -> do { 
-                      -- run for error reporting
-                    ; unboundName rdr_name
-                     ; return [] }
-           names -> return names
-    }
+--------------------------------
+type FastStringEnv a = UniqFM a                -- Keyed by FastString
+
+
+emptyFsEnv  :: FastStringEnv a
+lookupFsEnv :: FastStringEnv a -> FastString -> Maybe a
+extendFsEnv :: FastStringEnv a -> FastString -> a -> FastStringEnv a
+
+emptyFsEnv  = emptyUFM
+lookupFsEnv = lookupUFM
+extendFsEnv = addToUFM
 
 --------------------------------
-bindLocalFixities :: [FixitySig RdrName] -> (UniqFM (Located Fixity) -> RnM a) -> RnM a
--- Used for nested fixity decls:
---   bind the names that are in scope already;
---   pass the rest to the continuation for later
---      as a FastString->(Located Fixity) map
---
--- No need to worry about type constructors here,
--- Should check for duplicates?
-bindLocalFixities fixes thing_inside
-  | null fixes = thing_inside emptyUFM
-  | otherwise  = do ls <- mappM rn_sig fixes
-                    let (now, later) = nowAndLater ls
-                    extendFixityEnv now $ thing_inside later
-  where
-    rn_sig (FixitySig lv@(L loc v) fix) = do
-      vopt <- lookupBndrRn_maybe v
-      case vopt of 
-        Just new_v -> returnM (Left (new_v, (FixItem (rdrNameOcc v) fix)))
-        Nothing -> returnM (Right (occNameFS $ rdrNameOcc v, (L loc fix)))
-
-    nowAndLater (ls :: [Either (Name, FixItem) (FastString, Located Fixity)]) = 
-        foldr (\ cur -> \ (now, later) ->
-                        case cur of 
-                          Left (n, f) -> ((n, f) : now, later)
-                          Right (fs, f) -> (now, addToUFM later fs f))
-              ([], emptyUFM) ls
+type MiniFixityEnv = FastStringEnv (Located Fixity)
+       -- Mini fixity env for the names we're about 
+       -- to bind, in a single binding group
+       --
+       -- It is keyed by the *FastString*, not the *OccName*, because
+       -- the single fixity decl       infix 3 T
+       -- affects both the data constructor T and the type constrctor T
+       --
+       -- We keep the location so that if we find
+       -- a duplicate, we can report it sensibly
 
+--------------------------------
 -- Used for nested fixity decls to bind names along with their fixities.
 -- the fixities are given as a UFM from an OccName's FastString to a fixity decl
 -- Also check for unused binders
 bindLocalNamesFV_WithFixities :: [Name]
-                             -> UniqFM (Located Fixity)
+                             -> MiniFixityEnv
                              -> RnM (a, FreeVars) -> RnM (a, FreeVars)
 bindLocalNamesFV_WithFixities names fixities thing_inside
   = bindLocalNamesFV names $
@@ -575,7 +568,7 @@ bindLocalNamesFV_WithFixities names fixities thing_inside
     boundFixities = foldr 
                         (\ name -> \ acc -> 
                          -- check whether this name has a fixity decl
-                          case lookupUFM fixities (occNameFS (nameOccName name)) of
+                          case lookupFsEnv fixities (occNameFS (nameOccName name)) of
                                Just (L _ fix) -> (name, FixItem (nameOccName name) fix) : acc
                                Nothing -> acc) [] names
     -- bind the names; extend the fixity env; do the thing inside
@@ -635,6 +628,24 @@ lookupTyFixityRn :: Located Name -> RnM Fixity
 lookupTyFixityRn (L loc n) = lookupFixityRn n
 
 ---------------
+lookupLocalDataTcNames :: RdrName -> RnM [Name]
+-- GHC extension: look up both the tycon and data con 
+-- for con-like things
+-- Complain if neither is in scope
+lookupLocalDataTcNames rdr_name
+  | Just n <- isExact_maybe rdr_name   
+       -- Special case for (:), which doesn't get into the GlobalRdrEnv
+  = return [n] -- For this we don't need to try the tycon too
+  | otherwise
+  = do { mb_gres <- mapM lookupGreLocalRn (dataTcOccs rdr_name)
+       ; case [gre_name gre | Just gre <- mb_gres] of
+           [] -> do { 
+                      -- run for error reporting
+                    ; unboundName rdr_name
+                     ; return [] }
+           names -> return names
+    }
+
 dataTcOccs :: RdrName -> [RdrName]
 -- If the input is a data constructor, return both it and a type
 -- constructor.  This is useful when we aren't sure which we are
@@ -744,16 +755,21 @@ newLocalsRn rdr_names_w_loc
                        -- lookupRdrEnv doesn't even attempt to look up a qualified RdrName
                      mkInternalName uniq (rdrNameOcc rdr_name) loc
 
+---------------------
+checkDupAndShadowedRdrNames :: SDoc -> [Located RdrName] -> RnM ()
+checkDupAndShadowedRdrNames doc loc_rdr_names
+  = do { checkDupRdrNames doc loc_rdr_names
+       ; envs <- getRdrEnvs
+       ; checkShadowedNames doc envs 
+               [(loc,rdrNameOcc rdr) | L loc rdr <- loc_rdr_names] }
+
+---------------------
 bindLocatedLocalsRn :: SDoc    -- Documentation string for error message
                        -> [Located RdrName]
                    -> ([Name] -> RnM a)
                    -> RnM a
 bindLocatedLocalsRn doc_str rdr_names_w_loc enclosed_scope
-  =    -- Check for duplicate names
-    checkDupNames doc_str rdr_names_w_loc      `thenM_`
-
-       -- Warn about shadowing
-    checkShadowing doc_str rdr_names_w_loc     `thenM_`
+  = checkDupAndShadowedRdrNames doc_str rdr_names_w_loc        `thenM_`
 
        -- Make fresh Names and extend the environment
     newLocalsRn rdr_names_w_loc                `thenM` \names ->
@@ -839,31 +855,41 @@ extendTyVarEnvFVRn :: [Name] -> RnM (a, FreeVars) -> RnM (a, FreeVars)
 extendTyVarEnvFVRn tyvars thing_inside = bindLocalNamesFV tyvars thing_inside
 
 -------------------------------------
+checkDupRdrNames :: SDoc
+                -> [Located RdrName]
+                -> RnM ()
+checkDupRdrNames doc_str rdr_names_w_loc
+  =    -- Check for duplicated names in a binding group
+    mappM_ (dupNamesErr getLoc doc_str) dups
+  where
+    (_, dups) = removeDups (\n1 n2 -> unLoc n1 `compare` unLoc n2) rdr_names_w_loc
+
 checkDupNames :: SDoc
-             -> [Located RdrName]
+             -> [Name]
              -> RnM ()
-checkDupNames doc_str rdr_names_w_loc
+checkDupNames doc_str names
   =    -- Check for duplicated names in a binding group
-    mappM_ (dupNamesErr doc_str) dups
+    mappM_ (dupNamesErr nameSrcSpan doc_str) dups
   where
-    (_, dups) = removeDups (\n1 n2 -> unLoc n1 `compare` unLoc n2) rdr_names_w_loc
+    (_, dups) = removeDups (\n1 n2 -> nameOccName n1 `compare` nameOccName n2) names
 
 -------------------------------------
-checkShadowing doc_str loc_rdr_names
-  = traceRn (text "shadow" <+> ppr loc_rdr_names) `thenM_`
-    getLocalRdrEnv             `thenM` \ local_env ->
-    getGlobalRdrEnv            `thenM` \ global_env ->
-    let
-      check_shadow (L loc rdr_name)
+checkShadowedNames :: SDoc -> (GlobalRdrEnv, LocalRdrEnv) -> [(SrcSpan,OccName)] -> RnM ()
+checkShadowedNames doc_str (global_env,local_env) loc_rdr_names
+  = ifOptM Opt_WarnNameShadowing $ 
+    do { traceRn (text "shadow" <+> ppr loc_rdr_names)
+       ; mappM_ check_shadow loc_rdr_names }
+  where
+    check_shadow (loc, occ)
        | Just n <- mb_local = complain [ptext SLIT("bound at") <+> ppr (nameSrcLoc n)]
        | not (null gres)    = complain (map pprNameProvenance gres)
        | otherwise          = return ()
        where
-         complain pp_locs = addWarnAt loc (shadowedNameWarn doc_str rdr_name pp_locs)
-         mb_local = lookupLocalRdrEnv local_env rdr_name
-          gres     = lookupGRE_RdrName rdr_name global_env
-    in
-    ifOptM Opt_WarnNameShadowing (mappM_ check_shadow loc_rdr_names)
+         complain pp_locs = addWarnAt loc (shadowedNameWarn doc_str occ pp_locs)
+         mb_local = lookupLocalRdrOcc local_env occ
+          gres     = lookupGRE_RdrName (mkRdrUnqual occ) global_env
+               -- Make an Unqualified RdrName and look that up, so that
+               -- we don't find any GREs that are in scope qualified-only
 \end{code}
 
 
@@ -918,19 +944,13 @@ warnUnusedImports, warnUnusedTopBinds :: [GlobalRdrElt] -> RnM ()
 warnUnusedImports gres  = ifOptM Opt_WarnUnusedImports (warnUnusedGREs gres)
 warnUnusedTopBinds gres = ifOptM Opt_WarnUnusedBinds   (warnUnusedGREs gres)
 
-warnUnusedLocalBinds, warnUnusedMatches :: [Name] -> RnM (a, FreeVars) -> RnM (a, FreeVars)
+warnUnusedLocalBinds, warnUnusedMatches :: [Name] -> FreeVars -> RnM ()
 warnUnusedLocalBinds = check_unused Opt_WarnUnusedBinds
 warnUnusedMatches    = check_unused Opt_WarnUnusedMatches
 
-check_unused :: DynFlag -> [Name] -> RnM (a, FreeVars) -> RnM (a, FreeVars)
-check_unused flag names thing_inside
- =  do { (res, res_fvs) <- thing_inside
-       
-       -- Warn about unused names
-       ; ifOptM flag (warnUnusedLocals (filterOut (`elemNameSet` res_fvs) names))
-
-       -- And return
-       ; return (res, res_fvs) }
+check_unused :: DynFlag -> [Name] -> FreeVars -> RnM ()
+check_unused flag bound_names used_names
+ = ifOptM flag (warnUnusedLocals (filterOut (`elemNameSet` used_names) bound_names))
 
 -------------------------
 --     Helpers
@@ -981,16 +1001,21 @@ addNameClashErrRn rdr_name names
     msgs = [ptext SLIT("    or") <+> mk_ref np | np <- nps]
     mk_ref gre = quotes (ppr (gre_name gre)) <> comma <+> pprNameProvenance gre
 
-shadowedNameWarn doc rdr_name shadowed_locs
-  = sep [ptext SLIT("This binding for") <+> quotes (ppr rdr_name)
+shadowedNameWarn doc occ shadowed_locs
+  = sep [ptext SLIT("This binding for") <+> quotes (ppr occ)
            <+> ptext SLIT("shadows the existing binding") <> plural shadowed_locs,
         nest 2 (vcat shadowed_locs)]
     $$ doc
 
 unknownNameErr rdr_name
-  = sep [ptext SLIT("Not in scope:"), 
-        nest 2 $ pprNonVarNameSpace (occNameSpace (rdrNameOcc rdr_name))
-                 <+> quotes (ppr rdr_name)]
+  = vcat [ hang (ptext SLIT("Not in scope:")) 
+             2 (pprNonVarNameSpace (occNameSpace (rdrNameOcc rdr_name))
+                         <+> quotes (ppr rdr_name))
+        , extra ]
+  where
+    extra | rdr_name == forall_tv_RDR 
+         = ptext SLIT("Perhaps you intended to use -XRankNTypes or similar flag")
+         | otherwise = empty
 
 unknownSubordinateErr doc op   -- Doc is "method of class" or 
                                -- "field of constructor"
@@ -1000,14 +1025,13 @@ badOrigBinding name
   = ptext SLIT("Illegal binding of built-in syntax:") <+> ppr (rdrNameOcc name)
        -- The rdrNameOcc is because we don't want to print Prelude.(,)
 
-dupNamesErr :: SDoc -> [Located RdrName] -> RnM ()
-dupNamesErr descriptor located_names
+dupNamesErr :: Outputable n => (n -> SrcSpan) -> SDoc -> [n] -> RnM ()
+dupNamesErr get_loc descriptor names
   = addErrAt big_loc $
-    vcat [ptext SLIT("Conflicting definitions for") <+> quotes (ppr name1),
+    vcat [ptext SLIT("Conflicting definitions for") <+> quotes (ppr (head names)),
          locations, descriptor]
   where
-    L _ name1 = head located_names
-    locs      = map getLoc located_names
+    locs      = map get_loc names
     big_loc   = foldr1 combineSrcSpans locs
     one_line  = isOneLineSpan big_loc
     locations | one_line  = empty