[project @ 2001-12-07 07:37:43 by sof]
[ghc-hetmet.git] / ghc / compiler / rename / RnEnv.lhs
index 8f53698..affbcc9 100644 (file)
@@ -11,9 +11,11 @@ module RnEnv where           -- Export everything
 import {-# SOURCE #-} RnHiFiles
 
 import HsSyn
-import RdrHsSyn                ( RdrNameIE )
+import RdrHsSyn                ( RdrNameIE, RdrNameHsType, extractHsTyRdrTyVars )
 import RdrName         ( RdrName, rdrNameModule, rdrNameOcc, isQual, isUnqual, isOrig,
-                         mkRdrUnqual, mkRdrQual, lookupRdrEnv, foldRdrEnv
+                         mkRdrUnqual, mkRdrQual, 
+                         lookupRdrEnv, foldRdrEnv, rdrEnvToList, elemRdrEnv,
+                         unqualifyRdrName
                        )
 import HsTypes         ( hsTyVarName, replaceTyVarName )
 import HscTypes                ( Provenance(..), pprNameProvenance, hasBetterProv,
@@ -24,9 +26,9 @@ import HscTypes               ( Provenance(..), pprNameProvenance, hasBetterProv,
                          extendLocalRdrEnv
                        )
 import RnMonad
-import Name            ( Name,
+import Name            ( Name, 
                          getSrcLoc, nameIsLocalOrFrom,
-                         mkLocalName, mkGlobalName,
+                         mkLocalName, mkGlobalName, nameModule,
                          mkIPName, nameOccName, nameModule_maybe,
                          setNameModuleAndLoc
                        )
@@ -35,7 +37,7 @@ import NameSet
 import OccName         ( OccName, occNameUserString, occNameFlavour )
 import Module          ( ModuleName, moduleName, mkVanillaModule, 
                          mkSysModuleNameFS, moduleNameFS, WhereFrom(..) )
-import PrelNames       ( mkUnboundName, syntaxList, SyntaxMap, vanillaSyntaxMap,
+import PrelNames       ( mkUnboundName, 
                          derivingOccurrences,
                          mAIN_Name, pREL_MAIN_Name, 
                          ioTyConName, intTyConName, 
@@ -51,9 +53,9 @@ import SrcLoc         ( SrcLoc, noSrcLoc )
 import Outputable
 import ListSetOps      ( removeDups, equivClasses )
 import Util            ( sortLt )
+import BasicTypes      ( mapIPName )
 import List            ( nub )
 import UniqFM          ( lookupWithDefaultUFM )
-import Maybes          ( orElse )
 import CmdLineOpts
 import FastString      ( FastString )
 \end{code}
@@ -79,7 +81,7 @@ newTopBinder mod rdr_name loc
        -- There should never be a qualified name in a binding position (except in instance decls)
        -- The parser doesn't check this because the same parser parses instance decls
     (if isQual rdr_name then
-       qualNameErr (text "its declaration") (rdr_name,loc)
+       qualNameErr (text "In its declaration") (rdr_name,loc)
      else
        returnRn ()
     )                          `thenRn_`
@@ -160,21 +162,24 @@ newGlobalName mod_name occ
                     name       = mkGlobalName uniq mod occ noSrcLoc
                     new_cache  = addToFM cache key name
 
-newIPName rdr_name
+newIPName rdr_name_ip
   = getNameSupplyRn            `thenRn` \ name_supply ->
     let
        ipcache = nsIPs name_supply
     in
     case lookupFM ipcache key of
-       Just name -> returnRn name
-       Nothing   -> setNameSupplyRn (name_supply {nsUniqs = us', nsIPs = new_ipcache}) `thenRn_`
-                    returnRn name
+       Just name_ip -> returnRn name_ip
+       Nothing      -> setNameSupplyRn new_ns  `thenRn_`
+                       returnRn name_ip
                  where
                     (us', us1)  = splitUniqSupply (nsUniqs name_supply)
                     uniq        = uniqFromSupply us1
-                    name        = mkIPName uniq key
-                    new_ipcache = addToFM ipcache key name
-    where key = (rdrNameOcc rdr_name)
+                    name_ip     = mapIPName mk_name rdr_name_ip
+                    mk_name rdr_name = mkIPName uniq (rdrNameOcc rdr_name)
+                    new_ipcache = addToFM ipcache key name_ip
+                    new_ns      = name_supply {nsUniqs = us', nsIPs = new_ipcache}
+    where 
+       key = rdr_name_ip       -- Ensures that ?x and %x get distinct Names
 \end{code}
 
 %*********************************************************
@@ -239,6 +244,31 @@ lookupTopBndrRn rdr_name
 lookupSigOccRn :: RdrName -> RnMS Name
 lookupSigOccRn = lookupBndrRn
 
+-- lookupInstDeclBndr is used for the binders in an 
+-- instance declaration.   Here we use the class name to
+-- disambiguate.  
+
+lookupInstDeclBndr :: Name -> RdrName -> RnMS Name
+       -- We use the selector name as the binder
+lookupInstDeclBndr cls_name rdr_name
+  | isOrig rdr_name    -- Occurs in derived instances, where we just
+                       -- refer diectly to the right method
+  = lookupOrigName rdr_name
+
+  | otherwise  
+  = getGlobalAvails    `thenRn` \ avail_env ->
+    case lookupNameEnv avail_env cls_name of
+         -- class not in scope; don't fail as later checks will catch this,
+         -- but just return (bogus) name. Icky.
+       Nothing -> returnRn (mkUnboundName rdr_name)
+       Just (AvailTC _ ns) -> case [n | n <- ns, nameOccName n == occ] of
+                               (n:ns)-> ASSERT( null ns ) returnRn n
+                               []    -> failWithRn (mkUnboundName rdr_name)
+                                                   (unknownNameErr rdr_name)
+       other               -> pprPanic "lookupInstDeclBndr" (ppr cls_name)
+  where
+    occ = rdrNameOcc rdr_name
+
 -- lookupOccRn looks up an occurrence of a RdrName
 lookupOccRn :: RdrName -> RnMS Name
 lookupOccRn rdr_name
@@ -287,7 +317,7 @@ lookupQualifiedName rdr_name
        mod = rdrNameModule rdr_name
        occ = rdrNameOcc rdr_name
    in
-   loadInterface (ppr rdr_name) mod ImportBySystem `thenRn` \ iface ->
+   loadInterface (ppr rdr_name) mod ImportByUser `thenRn` \ iface ->
    case  [ name | (_,avails) <- mi_exports iface,
           avail             <- avails,
           name              <- availNames avail,
@@ -409,38 +439,47 @@ ubiquitousNames
        --        free var at every function application!)
 \end{code}
 
-\begin{code}
-rnSyntaxNames :: GlobalRdrEnv -> FreeVars -> RnMG (FreeVars, SyntaxMap)
--- Look up the re-bindable syntactic sugar names
--- Any errors arising from these lookups may surprise the
--- programmer, since they aren't explicitly mentioned, and
--- the src line will be unhelpful (ToDo)
+%************************************************************************
+%*                                                                     *
+\subsection{Re-bindable desugaring names}
+%*                                                                     *
+%************************************************************************
 
-rnSyntaxNames gbl_env source_fvs
+Haskell 98 says that when you say "3" you get the "fromInteger" from the
+Standard Prelude, regardless of what is in scope.   However, to experiment
+with having a language that is less coupled to the standard prelude, we're
+trying a non-standard extension that instead gives you whatever "Prelude.fromInteger"
+happens to be in scope.  Then you can
+       import Prelude ()
+       import MyPrelude as Prelude
+to get the desired effect.
+
+At the moment this just happens for
+  * fromInteger, fromRational on literals (in expressions and patterns)
+  * negate (in expressions)
+  * minus  (arising from n+k patterns)
+
+We store the relevant Name in the HsSyn tree, in 
+  * HsIntegral/HsFractional    
+  * NegApp
+  * NPlusKPatIn
+respectively.  Initially, we just store the "standard" name (PrelNames.fromIntegralName,
+fromRationalName etc), but the renamer changes this to the appropriate user
+name if Opt_NoImplicitPrelude is on.  That is what lookupSyntaxName does.
+
+\begin{code}
+lookupSyntaxName :: Name       -- The standard name
+                -> RnMS Name   -- Possibly a non-standard name
+lookupSyntaxName std_name
   = doptRn Opt_NoImplicitPrelude       `thenRn` \ no_prelude -> 
     if not no_prelude then
-       returnRn (source_fvs, vanillaSyntaxMap)
+       returnRn std_name       -- Normal case
     else
-
-       -- There's a -fno-implicit-prelude flag,
-       -- so build the re-mapping function
     let
-       reqd_syntax_list = filter is_reqd syntaxList
-       is_reqd (n,_)    = n `elemNameSet` source_fvs
-       lookup (n,rn)    = lookupSrcName gbl_env rn     `thenRn` \ rn' ->
-                          returnRn (n,rn')
+       rdr_name = mkRdrUnqual (nameOccName std_name)
+       -- Get the similarly named thing from the local environment
     in
-    mapRn lookup reqd_syntax_list      `thenRn` \ rn_syntax_list ->
-    let
-       -- Delete the proxies and add the actuals
-       proxies = map fst rn_syntax_list
-       actuals = map snd rn_syntax_list
-       new_source_fvs = (proxies `delFVs` source_fvs) `plusFV` mkFVs actuals
-
-       syntax_env   = mkNameEnv rn_syntax_list
-       syntax_map n = lookupNameEnv syntax_env n `orElse` n
-    in   
-    returnRn (new_source_fvs, syntax_map)
+    lookupOccRn rdr_name
 \end{code}
 
 
@@ -472,31 +511,34 @@ bindLocatedLocalsRn :: SDoc       -- Documentation string for error message
                    -> RnMS a
 bindLocatedLocalsRn doc_str rdr_names_w_loc enclosed_scope
   = getModeRn                          `thenRn` \ mode ->
-    getLocalNameEnv                    `thenRn` \ name_env ->
+    getLocalNameEnv                    `thenRn` \ local_env ->
+    getGlobalNameEnv                   `thenRn` \ global_env ->
 
        -- Check for duplicate names
     checkDupOrQualNames doc_str rdr_names_w_loc        `thenRn_`
 
        -- Warn about shadowing, but only in source modules
+    let
+      check_shadow (rdr_name,loc)
+       |  rdr_name `elemRdrEnv` local_env 
+       || rdr_name `elemRdrEnv` global_env 
+       = pushSrcLocRn loc $ addWarnRn (shadowedNameWarn rdr_name)
+        | otherwise 
+       = returnRn ()
+    in
+
     (case mode of
        SourceMode -> ifOptRn Opt_WarnNameShadowing     $
-                     mapRn_ (check_shadow name_env) rdr_names_w_loc
+                     mapRn_ check_shadow rdr_names_w_loc
        other      -> returnRn ()
     )                                  `thenRn_`
-       
+
     newLocalsRn rdr_names_w_loc                `thenRn` \ names ->
     let
-       new_local_env = addListToRdrEnv name_env (map fst rdr_names_w_loc `zip` names)
+       new_local_env = addListToRdrEnv local_env (map fst rdr_names_w_loc `zip` names)
     in
     setLocalNameEnv new_local_env (enclosed_scope names)
 
-  where
-    check_shadow name_env (rdr_name,loc)
-       = case lookupRdrEnv name_env rdr_name of
-               Nothing   -> returnRn ()
-               Just name -> pushSrcLocRn loc $
-                            addWarnRn (shadowedNameWarn rdr_name)
-
 bindCoreLocalRn :: RdrName -> (Name -> RnMS a) -> RnMS a
   -- A specialised variant when renaming stuff from interface
   -- files (of which there is a lot)
@@ -581,32 +623,29 @@ bindTyVars2Rn doc_str tyvar_names enclosed_scope
     bindLocatedLocalsRn doc_str located_tyvars $ \ names ->
     enclosed_scope names (zipWith replaceTyVarName tyvar_names names)
 
-bindTyVarsFVRn :: SDoc -> [HsTyVarBndr RdrName]
-             -> ([HsTyVarBndr Name] -> RnMS (a, FreeVars))
-             -> RnMS (a, FreeVars)
-bindTyVarsFVRn doc_str rdr_names enclosed_scope
-  = bindTyVars2Rn doc_str rdr_names    $ \ names tyvars ->
-    enclosed_scope tyvars              `thenRn` \ (thing, fvs) ->
-    returnRn (thing, delListFromNameSet fvs names)
+bindPatSigTyVars :: [RdrNameHsType]
+                -> RnMS (a, FreeVars)
+                -> RnMS (a, FreeVars)
+  -- Find the type variables in the pattern type 
+  -- signatures that must be brought into scope
 
-bindTyVarsFV2Rn :: SDoc -> [HsTyVarBndr RdrName]
-             -> ([Name] -> [HsTyVarBndr Name] -> RnMS (a, FreeVars))
-             -> RnMS (a, FreeVars)
-bindTyVarsFV2Rn doc_str rdr_names enclosed_scope
-  = bindTyVars2Rn doc_str rdr_names    $ \ names tyvars ->
-    enclosed_scope names tyvars                `thenRn` \ (thing, fvs) ->
-    returnRn (thing, delListFromNameSet fvs names)
-
-bindNakedTyVarsFVRn :: SDoc -> [RdrName]
-                   -> ([Name] -> RnMS (a, FreeVars))
-                   -> RnMS (a, FreeVars)
-bindNakedTyVarsFVRn doc_str tyvar_names enclosed_scope
-  = getSrcLocRn                                        `thenRn` \ loc ->
+bindPatSigTyVars tys enclosed_scope
+  = getLocalNameEnv                    `thenRn` \ name_env ->
+    getSrcLocRn                                `thenRn` \ loc ->
     let
-       located_tyvars = [(tv, loc) | tv <- tyvar_names] 
+       forall_tyvars  = nub [ tv | ty <- tys,
+                                   tv <- extractHsTyRdrTyVars ty, 
+                                   not (tv `elemFM` name_env)
+                        ]
+               -- The 'nub' is important.  For example:
+               --      f (x :: t) (y :: t) = ....
+               -- We don't want to complain about binding t twice!
+
+       located_tyvars = [(tv, loc) | tv <- forall_tyvars] 
+       doc_sig        = text "In a pattern type-signature"
     in
-    bindLocatedLocalsRn doc_str located_tyvars $ \ names ->
-    enclosed_scope names                       `thenRn` \ (thing, fvs) ->
+    bindLocatedLocalsRn doc_sig located_tyvars $ \ names ->
+    enclosed_scope                             `thenRn` \ (thing, fvs) ->
     returnRn (thing, delListFromNameSet fvs names)
 
 
@@ -640,48 +679,58 @@ checkDupNames doc_str rdr_names_w_loc
 \begin{code}
 mkGlobalRdrEnv :: ModuleName           -- Imported module (after doing the "as M" name change)
               -> Bool                  -- True <=> want unqualified import
-              -> Bool                  -- True <=> want qualified import
-              -> [AvailInfo]           -- What's to be hidden (but only the unqualified 
-                                       --      version is hidden)
               -> (Name -> Provenance)
-              -> Avails                -- Whats imported and how
+              -> Avails                -- Whats imported
+              -> Avails                -- What's to be hidden
+                                       -- I.e. import (imports - hides)
               -> Deprecations
               -> GlobalRdrEnv
 
-mkGlobalRdrEnv this_mod unqual_imp qual_imp hides 
-              mk_provenance avails deprecs
-  = gbl_env2
+mkGlobalRdrEnv this_mod unqual_imp mk_provenance avails hides deprecs
+  = gbl_env3
   where
        -- Make the name environment.  We're talking about a 
        -- single module here, so there must be no name clashes.
        -- In practice there only ever will be if it's the module
        -- being compiled.
 
-       -- Add the things that are available
+       -- Add qualified names for the things that are available
+       -- (Qualified names are always imported)
     gbl_env1 = foldl add_avail emptyRdrEnv avails
 
-       -- Delete things that are hidden
+       -- Delete (qualified names of) things that are hidden
     gbl_env2 = foldl del_avail gbl_env1 hides
 
+       -- Add unqualified names
+    gbl_env3 | unqual_imp = foldl add_unqual gbl_env2 (rdrEnvToList gbl_env2)
+            | otherwise  = gbl_env2
+
+    add_unqual env (qual_name, elts)
+       = foldl add_one env elts
+       where
+         add_one env elt = addOneToGlobalRdrEnv env unqual_name elt
+         unqual_name     = unqualifyRdrName qual_name
+       -- The qualified import should only have added one 
+       -- binding for each qualified name!  But if there's an error in
+       -- the module (multiple bindings for the same name) we may get
+       -- duplicates.  So the simple thing is to do the fold.
+
+    del_avail env avail 
+       = foldl delOneFromGlobalRdrEnv env rdr_names
+       where
+         rdr_names = map (mkRdrQual this_mod . nameOccName)
+                         (availNames avail)
+
+
     add_avail :: GlobalRdrEnv -> AvailInfo -> GlobalRdrEnv
     add_avail env avail = foldl add_name env (availNames avail)
 
-    add_name env name
-       | qual_imp && unqual_imp = env3
-       | unqual_imp             = env2
-       | qual_imp               = env1
-       | otherwise              = env
+    add_name env name  -- Add qualified name only
+       = addOneToGlobalRdrEnv env  (mkRdrQual this_mod occ) elt
        where
-         env1 = addOneToGlobalRdrEnv env  (mkRdrQual this_mod occ) elt
-         env2 = addOneToGlobalRdrEnv env  (mkRdrUnqual occ)        elt
-         env3 = addOneToGlobalRdrEnv env1 (mkRdrUnqual occ)        elt
          occ  = nameOccName name
          elt  = GRE name (mk_provenance name) (lookupDeprec deprecs name)
 
-    del_avail env avail = foldl delOneFromGlobalRdrEnv env rdr_names
-                       where
-                         rdr_names = map (mkRdrUnqual . nameOccName) (availNames avail)
-
 mkIfaceGlobalRdrEnv :: [(ModuleName,Avails)] -> GlobalRdrEnv
 -- Used to construct a GlobalRdrEnv for an interface that we've
 -- read from a .hi file.  We can't construct the original top-level
@@ -690,8 +739,8 @@ mkIfaceGlobalRdrEnv :: [(ModuleName,Avails)] -> GlobalRdrEnv
 mkIfaceGlobalRdrEnv m_avails
   = foldl add emptyRdrEnv m_avails
   where
-    add env (mod,avails) = plusGlobalRdrEnv env (mkGlobalRdrEnv mod True False [] 
-                                                               (\n -> LocalDef) avails NoDeprecs)
+    add env (mod,avails) = plusGlobalRdrEnv env (mkGlobalRdrEnv mod True 
+                                                               (\n -> LocalDef) avails [] NoDeprecs)
                -- The NoDeprecs is a bit of a hack I suppose
 \end{code}
 
@@ -773,7 +822,6 @@ plusAvail a1 a2 = pprPanic "RnEnv.plusAvail" (hsep [ppr a1,ppr a2])
 addAvail :: AvailEnv -> AvailInfo -> AvailEnv
 addAvail avails avail = extendNameEnv_C plusAvail avails (availName avail) avail
 
-emptyAvailEnv = emptyNameEnv
 unitAvailEnv :: AvailInfo -> AvailEnv
 unitAvailEnv a = unitNameEnv (availName a) a
 
@@ -974,16 +1022,14 @@ unknownNameErr name
 
 qualNameErr descriptor (name,loc)
   = pushSrcLocRn loc $
-    addErrRn (hsep [ ptext SLIT("Invalid use of qualified name"), 
-                    quotes (ppr name),
-                    ptext SLIT("in"),
+    addErrRn (vcat [ ptext SLIT("Invalid use of qualified name") <+> quotes (ppr name),
                     descriptor])
 
 dupNamesErr descriptor ((name,loc) : dup_things)
   = pushSrcLocRn loc $
     addErrRn ((ptext SLIT("Conflicting definitions for") <+> quotes (ppr name))
              $$ 
-             (ptext SLIT("in") <+> descriptor))
+             descriptor)
 
 warnDeprec :: Name -> DeprecTxt -> RnM d ()
 warnDeprec name txt
@@ -992,3 +1038,4 @@ warnDeprec name txt
                     quotes (ppr name) <+> text "is deprecated:", 
                     nest 4 (ppr txt) ])
 \end{code}
+