\section[HscTypes]{Types for the per-module compiler}
\begin{code}
+{-# OPTIONS -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
+-- for details
+
module HscTypes (
-- * Sessions and compilation state
Session(..), withSession, modifySession,
import {-# SOURCE #-} InteractiveEval ( Resume )
#endif
-import RdrName ( GlobalRdrEnv, emptyGlobalRdrEnv, GlobalRdrElt(..),
- mkRdrUnqual, ImpDeclSpec(..), Provenance(..),
- ImportSpec(..), lookupGlobalRdrEnv, lookupGRE_RdrName )
+import RdrName
import Name ( Name, NamedThing, getName, nameOccName, nameModule )
import NameEnv
import NameSet
import TyCon
import DataCon ( DataCon, dataConImplicitIds )
import PrelNames ( gHC_PRIM )
-import Packages ( PackageId )
+import Packages hiding ( Version(..) )
import DynFlags ( DynFlags(..), isOneShot, HscTarget (..) )
import DriverPhases ( HscSource(..), isHsBoot, hscSourceString, Phase )
import BasicTypes ( Version, initialVersion, IPName,
import UniqSupply ( UniqSupply )
import FastString ( FastString )
import StringBuffer ( StringBuffer )
+import Util
import System.Time ( ClockTime )
import Data.IORef
md_insts :: ![Instance], -- Dfun-ids for the instances in this module
md_fam_insts :: ![FamInst],
md_rules :: ![CoreRule], -- Domain may include Ids from other modules
- md_modBreaks :: !ModBreaks, -- Breakpoint information for this module
md_vect_info :: !VectInfo -- Vectorisation information
}
md_insts = [],
md_rules = [],
md_fam_insts = [],
- md_modBreaks = emptyModBreaks,
md_vect_info = noVectInfo
}
mg_usages :: ![Usage], -- Version info for what it needed
mg_rdr_env :: !GlobalRdrEnv, -- Top-level lexical environment
- mg_fix_env :: !FixityEnv, -- Fixity env, for things declared in
- -- this module
-
- mg_inst_env :: InstEnv, -- Class instance enviroment fro
- -- *home-package* modules (including
- -- this one); c.f. tcg_inst_env
- mg_fam_inst_env :: FamInstEnv, -- Type-family instance enviroment
- -- for *home-package* modules (including
- -- this one); c.f. tcg_fam_inst_env
+ -- These fields all describe the things **declared in this module**
+ mg_fix_env :: !FixityEnv, -- Fixities
mg_types :: !TypeEnv,
mg_insts :: ![Instance], -- Instances
mg_fam_insts :: ![FamInst], -- Instances
mg_deprecs :: !Deprecations, -- Deprecations declared in the module
mg_hpc_info :: !HpcInfo, -- info about coverage tick boxes
mg_modBreaks :: !ModBreaks,
- mg_vect_info :: !VectInfo -- Pool of vectorised declarations
+ mg_vect_info :: !VectInfo, -- Pool of vectorised declarations
+
+ -- The next two fields are unusual, because they give instance
+ -- environments for *all* modules in the home package, including
+ -- this module, rather than for *just* this module.
+ -- Reason: when looking up an instance we don't want to have to
+ -- look at each module in the home package in turn
+ mg_inst_env :: InstEnv, -- Class instance enviroment fro
+ -- *home-package* modules (including
+ -- this one); c.f. tcg_inst_env
+ mg_fam_inst_env :: FamInstEnv -- Type-family instance enviroment
+ -- for *home-package* modules (including
+ -- this one); c.f. tcg_fam_inst_env
}
-- The ModGuts takes on several slightly different forms:
cg_foreign :: !ForeignStubs,
cg_dep_pkgs :: ![PackageId], -- Used to generate #includes for C code gen
- cg_hpc_info :: !HpcInfo -- info about coverage tick boxes
+ cg_hpc_info :: !HpcInfo, -- info about coverage tick boxes
+ cg_modBreaks :: !ModBreaks
}
-----------------------------------
-- "foreign exported" functions
[FastString] -- Headers that need to be included
-- into C code generated for this module
- [Id] -- Foreign-exported binders
- -- we have to generate code to register these
\end{code}
#endif
}
-icPrintUnqual :: InteractiveContext -> PrintUnqualified
-icPrintUnqual ictxt = mkPrintUnqualified (ic_rn_gbl_env ictxt)
+icPrintUnqual :: DynFlags -> InteractiveContext -> PrintUnqualified
+icPrintUnqual dflags ictxt = mkPrintUnqualified dflags (ic_rn_gbl_env ictxt)
extendInteractiveContext
%* *
%************************************************************************
+Deciding how to print names is pretty tricky. We are given a name
+P:M.T, where P is the package name, M is the defining module, and T is
+the occurrence name, and we have to decide in which form to display
+the name given a GlobalRdrEnv describing the current scope.
+
+Ideally we want to display the name in the form in which it is in
+scope. However, the name might not be in scope at all, and that's
+where it gets tricky. Here are the cases:
+
+ 1. T uniquely maps to P:M.T ---> "T"
+ 2. there is an X for which X.T uniquely maps to P:M.T ---> "X.T"
+ 3. there is no binding for "M.T" ---> "M.T"
+ 4. otherwise ---> "P:M.T"
+
+3 and 4 apply when P:M.T is not in scope. In these cases we want to
+refer to the name as "M.T", but "M.T" might mean something else in the
+current scope (e.g. if there's an "import X as M"), so to avoid
+confusion we avoid using "M.T" if there's already a binding for it.
+
+There's one further subtlety: if the module M cannot be imported
+because it is not exposed by any package, then we must refer to it as
+"P:M". This is handled by the qual_mod component of PrintUnqualified.
+
\begin{code}
-mkPrintUnqualified :: GlobalRdrEnv -> PrintUnqualified
-mkPrintUnqualified env = (qual_name, qual_mod)
+mkPrintUnqualified :: DynFlags -> GlobalRdrEnv -> PrintUnqualified
+mkPrintUnqualified dflags env = (qual_name, qual_mod)
where
qual_name mod occ -- The (mod,occ) pair is the original name of the thing
- | [gre] <- unqual_gres, right_name gre = Nothing
+ | [gre] <- unqual_gres, right_name gre = NameUnqual
-- If there's a unique entity that's in scope unqualified with 'occ'
-- AND that entity is the right one, then we can use the unqualified name
- | [gre] <- qual_gres = Just (get_qual_mod (gre_prov gre))
+ | [gre] <- qual_gres = NameQual (get_qual_mod (gre_prov gre))
- | null qual_gres = Just (moduleName mod)
- -- it isn't in scope at all, this probably shouldn't happen,
- -- but we'll qualify it by the original module anyway.
+ | null qual_gres =
+ if null (lookupGRE_RdrName (mkRdrQual (moduleName mod) occ) env)
+ then NameNotInScope1
+ else NameNotInScope2
| otherwise = panic "mkPrintUnqualified"
where
get_qual_mod LocalDef = moduleName mod
get_qual_mod (Imported is) = ASSERT( not (null is) ) is_as (is_decl (head is))
- qual_mod mod = Nothing -- For now, we never qualify module names with their packages
+ -- we can mention a module P:M without the P: qualifier iff
+ -- "import M" would resolve unambiguously to P:M. (if P is the
+ -- current package we can just assume it is unqualified).
+
+ qual_mod mod
+ | modulePackageId mod == thisPackage dflags = False
+
+ | [pkgconfig] <- [pkg | (pkg,exposed_module) <- lookup,
+ exposed pkg && exposed_module],
+ packageConfigId pkgconfig == modulePackageId mod
+ -- this says: we are given a module P:M, is there just one exposed package
+ -- that exposes a module M, and is it package P?
+ = False
+
+ | otherwise = True
+ where lookup = lookupModuleInAllPackages dflags (moduleName mod)
\end{code}
= DotO FilePath
| DotA FilePath
| DotDLL FilePath
- | BCOs CompiledByteCode
+ | BCOs CompiledByteCode ModBreaks
#ifndef GHCI
data CompiledByteCode = NoByteCode
ppr (DotA path) = text "DotA" <+> text path
ppr (DotDLL path) = text "DotDLL" <+> text path
#ifdef GHCI
- ppr (BCOs bcos) = text "BCOs" <+> ppr bcos
+ ppr (BCOs bcos _) = text "BCOs" <+> ppr bcos
#else
- ppr (BCOs bcos) = text "No byte code"
+ ppr (BCOs bcos _) = text "No byte code"
#endif
isObject (DotO _) = True
nameOfObject (DotDLL fn) = fn
nameOfObject other = pprPanic "nameOfObject" (ppr other)
-byteCodeOfObject (BCOs bc) = bc
-byteCodeOfObject other = pprPanic "byteCodeOfObject" (ppr other)
+byteCodeOfObject (BCOs bc _) = bc
+byteCodeOfObject other = pprPanic "byteCodeOfObject" (ppr other)
\end{code}
%************************************************************************