%
\begin{code}
module TcRnTypes(
- TcRn, TcM, RnM, -- The monad is opaque outside this module
+ TcRnIf, TcRn, TcM, RnM, IfM, IfL, IfG, -- The monad is opaque outside this module
+ TcRef,
- -- Standard monadic operations
- thenM, thenM_, returnM, failM,
-
- -- Non-standard operations
- runTcRn, fixM, tryM, ioToTcRn,
- newMutVar, readMutVar, writeMutVar,
- getEnv, setEnv, updEnv, unsafeInterleaveM, zapEnv,
-
-- The environment types
- Env(..), TopEnv(..), TcGblEnv(..),
- TcLclEnv(..), RnLclEnv(..),
+ Env(..),
+ TcGblEnv(..), TcLclEnv(..),
+ IfGblEnv(..), IfLclEnv(..),
-- Ranamer types
- RnMode(..), isInterfaceMode, isCmdLineMode,
EntityUsage, emptyUsages, ErrCtxt,
ImportAvails(..), emptyImportAvails, plusImportAvails,
plusAvail, pruneAvails,
AvailEnv, emptyAvailEnv, unitAvailEnv, plusAvailEnv,
mkAvailEnv, lookupAvailEnv, lookupAvailEnv_maybe, availEnvElts, addAvail,
- WhereFrom(..),
+ WhereFrom(..), mkModDeps,
-- Typechecker types
- TcTyThing(..),
+ TcTyThing(..), GadtRefinement,
-- Template Haskell
- Stage(..), topStage, topSpliceStage,
- Level, impLevel, topLevel,
+ ThStage(..), topStage, topSpliceStage,
+ ThLevel, impLevel, topLevel,
+
+ -- Arrows
+ ArrowCtxt(..), topArrowCtxt, ProcLevel, topProcLevel,
-- Insts
- Inst(..), InstOrigin(..), InstLoc(..), pprInstLoc, instLocSrcLoc,
+ Inst(..), InstOrigin(..), InstLoc(..), pprInstLoc,
+ instLocSrcLoc, instLocSrcSpan,
LIE, emptyLIE, unitLIE, plusLIE, consLIE,
plusLIEs, mkLIE, isEmptyLIE, lieToList, listToLIE,
-- Misc other types
- TcRef, TcId, TcIdSet
+ TcId, TcIdSet, TcDictBinds
) where
#include "HsVersions.h"
-import HsSyn ( PendingSplice, HsOverLit, MonoBinds, RuleDecl, ForeignDecl )
-import RnHsSyn ( RenamedHsExpr, RenamedPat, RenamedArithSeqInfo )
-import HscTypes ( GhciMode, ExternalPackageState, HomePackageTable,
- NameCache, GlobalRdrEnv, LocalRdrEnv, FixityEnv,
- TypeEnv, TyThing, Avails, GenAvailInfo(..), AvailInfo,
- availName, IsBootInterface, Deprecations,
- ExternalPackageState(..), emptyExternalPackageState )
+import HsSyn ( PendingSplice, HsOverLit, LRuleDecl, LForeignDecl,
+ ArithSeqInfo, DictBinds, LHsBinds )
+import HscTypes ( FixityEnv,
+ HscEnv, TypeEnv, TyThing,
+ GenAvailInfo(..), AvailInfo,
+ availName, IsBootInterface, Deprecations )
import Packages ( PackageName )
-import TcType ( TcTyVarSet, TcType, TcTauType, TcThetaType,
+import Type ( Type, TvSubstEnv )
+import TcType ( TcTyVarSet, TcType, TcTauType, TcThetaType, SkolemInfo,
TcPredType, TcKind, tcCmpPred, tcCmpType, tcCmpTypes )
import InstEnv ( DFunId, InstEnv )
+import IOEnv
+import RdrName ( GlobalRdrEnv, LocalRdrEnv )
import Name ( Name )
import NameEnv
-import NameSet ( NameSet, emptyNameSet )
-import Type ( Type )
-import Class ( Class )
+import NameSet ( NameSet, emptyNameSet, DefUses )
+import OccName ( OccEnv )
import Var ( Id, TyVar )
import VarEnv ( TidyEnv )
import Module
-import SrcLoc ( SrcLoc )
+import SrcLoc ( SrcSpan, SrcLoc, srcSpanStart )
import VarSet ( IdSet )
import ErrUtils ( Messages, Message )
-import CmdLineOpts ( DynFlags )
import UniqSupply ( UniqSupply )
import BasicTypes ( IPName )
import Util ( thenCmp )
import Bag
import Outputable
-import DATA_IOREF ( IORef, newIORef, readIORef, writeIORef )
-import UNSAFE_IO ( unsafeInterleaveIO )
-import FIX_IO ( fixIO )
-import EXCEPTION ( Exception(..) )
-import IO ( isUserError )
import Maybe ( mapMaybe )
import ListSetOps ( unionLists )
-import Panic ( tryJust )
\end{code}
-\begin{code}
-type TcRef a = IORef a
-type TcId = Id -- Type may be a TcType
-type TcIdSet = IdSet
-\end{code}
-
%************************************************************************
%* *
Standard monad definition for TcRn
%* *
%************************************************************************
-The monad itself has to be defined here,
-because it is mentioned by ErrCtxt
-
-\begin{code}
-newtype TcRn m a = TcRn (Env m -> IO a)
-unTcRn (TcRn f) = f
-
-type TcM a = TcRn TcLclEnv a
-type RnM a = TcRn RnLclEnv a
-
-returnM :: a -> TcRn m a
-returnM a = TcRn (\ env -> return a)
-
-thenM :: TcRn m a -> (a -> TcRn m b) -> TcRn m b
-thenM (TcRn m) f = TcRn (\ env -> do { r <- m env ;
- unTcRn (f r) env })
-
-thenM_ :: TcRn m a -> TcRn m b -> TcRn m b
-thenM_ (TcRn m) f = TcRn (\ env -> do { m env ; unTcRn f env })
-
-failM :: TcRn m a
-failM = TcRn (\ env -> ioError (userError "TcRn failure"))
-
-instance Monad (TcRn m) where
- (>>=) = thenM
- (>>) = thenM_
- return = returnM
- fail s = failM -- Ignore the string
-\end{code}
-
-
-%************************************************************************
-%* *
- Fundmantal combinators specific to the monad
-%* *
-%************************************************************************
-
-Running it
-
-\begin{code}
-runTcRn :: Env m -> TcRn m a -> IO a
-runTcRn env (TcRn m) = m env
-\end{code}
-
-The fixpoint combinator
-
-\begin{code}
-{-# NOINLINE fixM #-}
- -- Aargh! Not inlining fixTc alleviates a space leak problem.
- -- Normally fixTc is used with a lazy tuple match: if the optimiser is
- -- shown the definition of fixTc, it occasionally transforms the code
- -- in such a way that the code generator doesn't spot the selector
- -- thunks. Sigh.
-
-fixM :: (a -> TcRn m a) -> TcRn m a
-fixM f = TcRn (\ env -> fixIO (\ r -> unTcRn (f r) env))
-\end{code}
-
-Error recovery
-
-\begin{code}
-tryM :: TcRn m r -> TcRn m (Either Exception r)
--- Reflect exception into TcRn monad
-tryM (TcRn thing) = TcRn (\ env -> tryJust tc_errors (thing env))
- where
-#if __GLASGOW_HASKELL__ > 504 || __GLASGOW_HASKELL__ < 500
- tc_errors e@(IOException ioe) | isUserError ioe = Just e
-#elif __GLASGOW_HASKELL__ == 502
- tc_errors (UserError _) = Just e
-#else
- tc_errors e@(IOException ioe) | isUserError e = Just e
-#endif
- tc_errors _other = Nothing
- -- type checker failures show up as UserErrors only
-\end{code}
-
-Lazy interleave
-
-\begin{code}
-unsafeInterleaveM :: TcRn m a -> TcRn m a
-unsafeInterleaveM (TcRn m) = TcRn (\ env -> unsafeInterleaveIO (m env))
-\end{code}
-
-\end{code}
-
-Performing arbitrary I/O, plus the read/write var (for efficiency)
+The monad itself has to be defined here, because it is mentioned by ErrCtxt
\begin{code}
-ioToTcRn :: IO a -> TcRn m a
-ioToTcRn io = TcRn (\ env -> io)
+type TcRef a = IORef a
+type TcId = Id -- Type may be a TcType
+type TcIdSet = IdSet
+type TcDictBinds = DictBinds TcId -- Bag of dictionary bindings
-newMutVar :: a -> TcRn m (TcRef a)
-newMutVar val = TcRn (\ env -> newIORef val)
-writeMutVar :: TcRef a -> a -> TcRn m ()
-writeMutVar var val = TcRn (\ env -> writeIORef var val)
-readMutVar :: TcRef a -> TcRn m a
-readMutVar var = TcRn (\ env -> readIORef var)
+type TcRnIf a b c = IOEnv (Env a b) c
+type IfM lcl a = TcRnIf IfGblEnv lcl a -- Iface stuff
+type IfG a = IfM () a -- Top level
+type IfL a = IfM IfLclEnv a -- Nested
+type TcRn a = TcRnIf TcGblEnv TcLclEnv a
+type RnM a = TcRn a -- Historical
+type TcM a = TcRn a -- Historical
\end{code}
-Getting the environment
-
-\begin{code}
-getEnv :: TcRn m (Env m)
-{-# INLINE getEnv #-}
-getEnv = TcRn (\ env -> return env)
-
-setEnv :: Env n -> TcRn n a -> TcRn m a
-{-# INLINE setEnv #-}
-setEnv new_env (TcRn m) = TcRn (\ env -> m new_env)
-
-updEnv :: (Env m -> Env n) -> TcRn n a -> TcRn m a
-{-# INLINE updEnv #-}
-updEnv upd (TcRn m) = TcRn (\ env -> m (upd env))
-\end{code}
-
-\begin{code}
-zapEnv :: TcRn m a -> TcRn m a
-zapEnv act = TcRn $ \env@Env{ env_top=top, env_gbl=gbl, env_lcl=lcl } ->
- case top of {
- TopEnv{
- top_mode = mode,
- top_dflags = dflags,
- top_hpt = hpt,
- top_eps = eps,
- top_us = us
- } -> do
-
- eps_snap <- readIORef eps
- ref <- newIORef $! emptyExternalPackageState{ eps_PTE = eps_PTE eps_snap }
-
- let
- top' = TopEnv {
- top_mode = mode,
- top_dflags = dflags,
- top_hpt = hpt,
- top_eps = ref,
- top_us = us
- }
-
- type_env = tcg_type_env gbl
- mod = tcg_mod gbl
- gbl' = TcGblEnv {
- tcg_mod = mod,
- tcg_type_env = type_env
- }
-
- env' = Env {
- env_top = top',
- env_gbl = gbl',
- env_lcl = lcl
- -- leave the rest empty
- }
-
- case act of { TcRn f -> f env' }
- }
-\end{code}
%************************************************************************
%* *
%************************************************************************
\begin{code}
-data Env a -- Changes as we move into an expression
+data Env gbl lcl -- Changes as we move into an expression
= Env {
- env_top :: TopEnv, -- Top-level stuff that never changes
- -- Mainly a bunch of updatable refs
- -- Includes all info about imported things
- env_gbl :: TcGblEnv, -- Info about things defined at the top leve
- -- of the module being compiled
+ env_top :: HscEnv, -- Top-level stuff that never changes
+ -- Includes all info about imported things
- env_lcl :: a, -- Different for the type checker
- -- and the renamer
+ env_us :: TcRef UniqSupply, -- Unique supply for local varibles
- env_loc :: SrcLoc -- Source location
- }
+ env_gbl :: gbl, -- Info about things defined at the top level
+ -- of the module being compiled
-data TopEnv -- Built once at top level then does not change
- -- Concerns imported stuff
- -- Exceptions: error recovery points, meta computation points
- = TopEnv {
- top_mode :: GhciMode,
- top_dflags :: DynFlags,
-
- -- Stuff about imports
- top_eps :: TcRef ExternalPackageState,
- -- PIT, ImportedModuleInfo
- -- DeclsMap, IfaceRules, IfaceInsts, InstGates
- -- TypeEnv, InstEnv, RuleBase
- -- Mutable, because we demand-load declarations that extend the state
-
- top_hpt :: HomePackageTable,
- -- The home package table that we've accumulated while
- -- compiling the home package,
- -- *excluding* the module we are compiling right now.
- -- (In one-shot mode the current module is the only
- -- home-package module, so tc_hpt is empty. All other
- -- modules count as "external-package" modules.)
- -- tc_hpt is not mutable because we only demand-load
- -- external packages; the home package is eagerly
- -- loaded by the compilation manager.
-
- -- The global name supply
- top_nc :: TcRef NameCache, -- Maps original names to Names
- top_us :: TcRef UniqSupply, -- Unique supply for this module
- top_errs :: TcRef Messages
- }
+ env_lcl :: lcl -- Nested stuff; changes as we go into
+ -- an expression
+ }
-- TcGblEnv describes the top-level of the module at the
-- point at which the typechecker is finished work.
data TcGblEnv
= TcGblEnv {
- tcg_mod :: Module, -- Module being compiled
- tcg_usages :: TcRef EntityUsage, -- What version of what entities
- -- have been used from other home-pkg modules
+ tcg_mod :: Module, -- Module being compiled
tcg_rdr_env :: GlobalRdrEnv, -- Top level envt; used during renaming
- tcg_fix_env :: FixityEnv, -- Ditto
- tcg_default :: [Type], -- Types used for defaulting
+ tcg_default :: Maybe [Type], -- Types used for defaulting
+ -- Nothing => no 'default' decl
+
+ tcg_fix_env :: FixityEnv, -- Just for things in this module
tcg_type_env :: TypeEnv, -- Global type env for the module we are compiling now
-- All TyCons and Classes (for this module) end up in here right away,
--
-- (Ids defined in this module start in the local envt,
-- though they move to the global envt during zonking)
+
+ tcg_type_env_var :: TcRef TypeEnv,
+ -- Used only to initialise the interface-file
+ -- typechecker in initIfaceTcRn, so that it can see stuff
+ -- bound in this module when dealing with hi-boot recursions
+ -- Updated at intervals (e.g. after dealing with types and classes)
- tcg_inst_env :: TcRef InstEnv, -- Global instance env: a combination of
- -- tc_pcs, tc_hpt, *and* tc_insts
- -- This field is mutable so that it can be updated inside a
- -- Template Haskell splice, which might suck in some new
- -- instance declarations. This is a slightly different strategy
- -- than for the type envt, where we look up first in tcg_type_env
- -- and then in the mutable EPS, because the InstEnv for this module
- -- is constructed (in principle at least) only from the modules
- -- 'below' this one, so it's this-module-specific
- --
- -- On the other hand, a declaration quote [d| ... |] may introduce
- -- some new instance declarations that we *don't* want to persist
- -- outside the quote, so we tiresomely need to revert the InstEnv
- -- after finishing the quote (see TcSplice.tcBracket)
+ tcg_inst_env :: InstEnv, -- Instance envt for *home-package* modules
+ -- Includes the dfuns in tcg_insts
+ tcg_inst_uses :: TcRef NameSet, -- Home-package Dfuns actually used
+ -- Used to generate version dependencies
+ -- This records usages, rather like tcg_dus, but it has to
+ -- be a mutable variable so it can be augmented
+ -- when we look up an instance. These uses of dfuns are
+ -- rather like the free variables of the program, but
+ -- are implicit instead of explicit.
+
+ tcg_th_used :: TcRef Bool, -- True <=> Template Haskell syntax used
+ -- We need this so that we can generate a dependency on the
+ -- Template Haskell package, becuase the desugarer is going to
+ -- emit loads of references to TH symbols. It's rather like
+ -- tcg_inst_uses; the reference is implicit rather than explicit,
+ -- so we have to zap a mutable variable.
-- Now a bunch of things about this module that are simply
-- accumulated, but never consulted until the end.
-- Nevertheless, it's convenient to accumulate them along
-- with the rest of the info from this module.
- tcg_exports :: Avails, -- What is exported
- tcg_imports :: ImportAvails, -- Information about what was imported
- -- from where, including things bound
- -- in this module
+ tcg_exports :: NameSet, -- What is exported
+ tcg_imports :: ImportAvails, -- Information about what was imported
+ -- from where, including things bound
+ -- in this module
+
+ tcg_dus :: DefUses, -- What is defined in this module and what is used.
+ -- The latter is used to generate
+ -- (a) version tracking; no need to recompile if these
+ -- things have not changed version stamp
+ -- (b) unused-import info
+
+ tcg_keep :: NameSet, -- Set of names to keep alive, and to expose in the
+ -- interface file (but not to export to the user).
+ -- These are typically extra definitions generated from
+ -- data type declarations which would otherwise be
+ -- dropped as dead code.
-- The next fields accumulate the payload of the module
-- The binds, rules and foreign-decl fiels are collected
-- initially in un-zonked form and are finally zonked in tcRnSrcDecls
- tcg_binds :: MonoBinds Id, -- Value bindings in this module
+ tcg_binds :: LHsBinds Id, -- Value bindings in this module
tcg_deprecs :: Deprecations, -- ...Deprecations
tcg_insts :: [DFunId], -- ...Instances
- tcg_rules :: [RuleDecl Id], -- ...Rules
- tcg_fords :: [ForeignDecl Id] -- ...Foreign import & exports
+ tcg_rules :: [LRuleDecl Id], -- ...Rules
+ tcg_fords :: [LForeignDecl Id] -- ...Foreign import & exports
+ }
+\end{code}
+
+%************************************************************************
+%* *
+ The interface environments
+ Used when dealing with IfaceDecls
+%* *
+%************************************************************************
+
+\begin{code}
+data IfGblEnv
+ = IfGblEnv {
+ -- The type environment for the module being compiled,
+ -- in case the interface refers back to it via a reference that
+ -- was originally a hi-boot file.
+ -- We need the module name so we can test when it's appropriate
+ -- to look in this env.
+ if_rec_types :: Maybe (Module, IfG TypeEnv)
+ -- Allows a read effect, so it can be in a mutable
+ -- variable; c.f. handling the external package type env
+ -- Nothing => interactive stuff, no loops possible
+ }
+
+data IfLclEnv
+ = IfLclEnv {
+ -- The module for the current IfaceDecl
+ -- So if we see f = \x -> x
+ -- it means M.f = \x -> x, where M is the if_mod
+ if_mod :: ModuleName,
+
+ if_tv_env :: OccEnv TyVar, -- Nested tyvar bindings
+ if_id_env :: OccEnv Id -- Nested id binding
}
\end{code}
b) used in the ModDetails of this module
\begin{code}
-data TcLclEnv
+data TcLclEnv -- Changes as we move inside an expression
+ -- Discarded after typecheck/rename; not passed on to desugarer
= TcLclEnv {
- tcl_ctxt :: ErrCtxt, -- Error context
-
- tcl_level :: Stage, -- Template Haskell context
+ tcl_loc :: SrcSpan, -- Source span
+ tcl_ctxt :: ErrCtxt, -- Error context
+ tcl_errs :: TcRef Messages, -- Place to accumulate errors
+
+ tcl_th_ctxt :: ThStage, -- Template Haskell context
+ tcl_arrow_ctxt :: ArrowCtxt, -- Arrow-notation context
+
+ tcl_rdr :: LocalRdrEnv, -- Local name envt
+ -- Maintained during renaming, of course, but also during
+ -- type checking, solely so that when renaming a Template-Haskell
+ -- splice we have the right environment for the renamer.
+ --
+ -- Does *not* include global name envt; may shadow it
+ -- Includes both ordinary variables and type variables;
+ -- they are kept distinct because tyvar have a different
+ -- occurrence contructor (Name.TvOcc)
+ -- We still need the unsullied global name env so that
+ -- we can look up record field names
- tcl_env :: NameEnv TcTyThing, -- The local type environment: Ids and TyVars
- -- defined in this module
+ tcl_env :: NameEnv TcTyThing, -- The local type environment: Ids and TyVars
+ -- defined in this module
tcl_tyvars :: TcRef TcTyVarSet, -- The "global tyvars"
- -- Namely, the in-scope TyVars bound in tcl_lenv,
- -- plus the tyvars mentioned in the types of
- -- Ids bound in tcl_lenv
- -- Why mutable? see notes with tcGetGlobalTyVars
+ -- Namely, the in-scope TyVars bound in tcl_env,
+ -- plus the tyvars mentioned in the types of Ids bound in tcl_lenv
+ -- Why mutable? see notes with tcGetGlobalTyVars
- tcl_lie :: TcRef LIE -- Place to accumulate type constraints
+ tcl_lie :: TcRef LIE, -- Place to accumulate type constraints
+ tcl_gadt :: GadtRefinement -- The current type refinement for GADTs
+
+-----------------------------------------------------------
+-- Not yet; it's a new complication and I want to see whether it bites
+-- tcl_given :: [Inst] -- Insts available in the current context (see Note [Given Insts])
+-----------------------------------------------------------
}
-type Level = Int
+type GadtRefinement = TvSubstEnv -- Binds rigid type variables to their refinements
+
+{- Note [Given Insts]
+ ~~~~~~~~~~~~~~~~~~
+Because of GADTs, we have to pass inwards the Insts provided by type signatures
+and existential contexts. Consider
+ data T a where { T1 :: b -> b -> T [b] }
+ f :: Eq a => T a -> Bool
+ f (T1 x y) = [x]==[y]
+
+The constructor T1 binds an existential variable 'b', and we need Eq [b].
+Well, we have it, because Eq a refines to Eq [b], but we can only spot that if we
+pass it inwards.
+
+-}
-data Stage
+---------------------------
+-- Template Haskell levels
+---------------------------
+
+type ThLevel = Int -- Always >= 0
+
+data ThStage
= Comp -- Ordinary compiling, at level topLevel
- | Splice Level -- Inside a splice
- | Brack Level -- Inside brackets;
+ | Splice ThLevel -- Inside a splice
+ | Brack ThLevel -- Inside brackets;
(TcRef [PendingSplice]) -- accumulate pending splices here
(TcRef LIE) -- and type constraints here
-topStage, topSpliceStage :: Stage
+topStage, topSpliceStage :: ThStage
topStage = Comp
topSpliceStage = Splice (topLevel - 1) -- Stage for the body of a top-level splice
-impLevel, topLevel :: Level
+impLevel, topLevel :: ThLevel
topLevel = 1 -- Things defined at top level of this module
impLevel = 0 -- Imported things; they can be used inside a top level splice
--
-- g1 = $(map ...) is OK
-- g2 = $(f ...) is not OK; because we havn't compiled f yet
+
+---------------------------
+-- Arrow-notation stages
+---------------------------
+
+-- In arrow notation, a variable bound by a proc (or enclosed let/kappa)
+-- is not in scope to the left of an arrow tail (-<). For example
+--
+-- proc x -> (e1 -< e2)
+--
+-- Here, x is not in scope in e1, but it is in scope in e2. This can get
+-- a bit complicated:
+--
+-- let x = 3 in
+-- prox y -> (proc z -> e1) -< e2
+--
+-- Here, x and z are in scope in e1, but y is not. Here's how we track this:
+-- a) Assign an "proc level" to each proc, being the number of
+-- lexically-enclosing procs + 1.
+-- b) Assign to each local variable the proc-level of its lexically
+-- enclosing proc.
+-- c) Keep a list of out-of-scope procs. When moving to the left of
+-- an arrow-tail, add the proc-level of the immediately enclosing
+-- proc to the list.
+-- d) When looking up a variable, complain if its proc-level is in
+-- the banned list
+
+type ProcLevel = Int -- Always >= 0
+topProcLevel = 0 -- Not inside any proc
+
+data ArrowCtxt = ArrCtxt { proc_level :: ProcLevel, -- Current level
+ proc_banned :: [ProcLevel] } -- Out of scope proc-levels
+
+topArrowCtxt = ArrCtxt { proc_level = topProcLevel, proc_banned = [] }
+
+---------------------------
+-- TcTyThing
+---------------------------
+
data TcTyThing
- = AGlobal TyThing -- Used only in the return type of a lookup
- | ATcId TcId Level -- Ids defined in this module; may not be fully zonked
- | ATyVar TyVar -- Type variables
- | AThing TcKind -- Used temporarily, during kind checking
--- Here's an example of how the AThing guy is used
--- Suppose we are checking (forall a. T a Int):
--- 1. We first bind (a -> AThink kv), where kv is a kind variable.
--- 2. Then we kind-check the (T a Int) part.
--- 3. Then we zonk the kind variable.
--- 4. Now we know the kind for 'a', and we add (a -> ATyVar a::K) to the environment
+ = AGlobal TyThing -- Used only in the return type of a lookup
+ | ATcId TcId ThLevel ProcLevel -- Ids defined in this module; may not be fully zonked
+ | ATyVar TyVar -- Type variables
+ | AThing TcKind -- Used temporarily, during kind checking, for the
+ -- tycons and clases in this recursive group
instance Outputable TcTyThing where -- Debugging only
- ppr (AGlobal g) = text "AGlobal" <+> ppr g
- ppr (ATcId g l) = text "ATcId" <+> ppr g <+> ppr l
- ppr (ATyVar t) = text "ATyVar" <+> ppr t
- ppr (AThing k) = text "AThing" <+> ppr k
+ ppr (AGlobal g) = text "AGlobal" <+> ppr g
+ ppr (ATcId g tl pl) = text "ATcId" <+> ppr g <+> ppr tl <+> ppr pl
+ ppr (ATyVar t) = text "ATyVar" <+> ppr t
+ ppr (AThing k) = text "AThing" <+> ppr k
\end{code}
\begin{code}
%************************************************************************
%* *
- The local renamer environment
-%* *
-%************************************************************************
-
-\begin{code}
-data RnLclEnv
- = RnLclEnv {
- rn_mode :: RnMode,
- rn_lenv :: LocalRdrEnv -- Local name envt
- -- Does *not* include global name envt; may shadow it
- -- Includes both ordinary variables and type variables;
- -- they are kept distinct because tyvar have a different
- -- occurrence contructor (Name.TvOcc)
- -- We still need the unsullied global name env so that
- -- we can look up record field names
- }
-
-data RnMode = SourceMode -- Renaming source code
- | InterfaceMode Module -- Renaming interface declarations from M
- | CmdLineMode -- Renaming a command-line expression
-
-isInterfaceMode (InterfaceMode _) = True
-isInterfaceMode _ = False
-
-isCmdLineMode CmdLineMode = True
-isCmdLineMode _ = False
-\end{code}
-
-
-%************************************************************************
-%* *
EntityUsage
%* *
%************************************************************************
%************************************************************************
ImportAvails summarises what was imported from where, irrespective
-of whether the imported htings are actually used or not
+of whether the imported things are actually used or not
It is used * when processing the export list
* when constructing usage info for the inteface file
* to identify the list of directly imported modules
-- combine stuff coming from different (unqualified)
-- imports of the same module
- imp_mods :: ModuleEnv (Module, Bool),
+ imp_mods :: ModuleEnv (Module, Maybe Bool, SrcSpan),
-- Domain is all directly-imported modules
- -- Bool is True if there was an unrestricted import
- -- (i.e. not a selective list)
+ -- Maybe value answers the question "is the import restricted?"
+ -- Nothing => unrestricted import (e.g., "import Foo")
+ -- Just True => restricted import, at least one entity (e.g., "import Foo(x)")
+ -- Just False => fully restricted import (e.g., "import Foo ()")
+ --
+ -- A distinction is made between the first and the third in order
+ -- to more precisely emit warnings about unused imports.
+ --
-- We need the Module in the range because we can't get
-- the keys of a ModuleEnv
-- Used
-- Orphan modules below us in the import tree
}
+mkModDeps :: [(ModuleName, IsBootInterface)]
+ -> ModuleEnv (ModuleName, IsBootInterface)
+mkModDeps deps = foldl add emptyModuleEnv deps
+ where
+ add env elt@(m,_) = extendModuleEnvByName env m elt
+
emptyImportAvails :: ImportAvails
emptyImportAvails = ImportAvails { imp_env = emptyAvailEnv,
imp_qual = emptyModuleEnv,
\begin{code}
data WhereFrom
= ImportByUser IsBootInterface -- Ordinary user import (perhaps {-# SOURCE #-})
-
- | ImportForUsage IsBootInterface -- Import when chasing usage info from an interaface file
- -- Failure in this case is not an error
-
| ImportBySystem -- Non user import.
instance Outputable WhereFrom where
ppr (ImportByUser is_boot) | is_boot = ptext SLIT("{- SOURCE -}")
| otherwise = empty
- ppr (ImportForUsage is_boot) | is_boot = ptext SLIT("{- USAGE SOURCE -}")
- | otherwise = ptext SLIT("{- USAGE -}")
ppr ImportBySystem = ptext SLIT("{- SYSTEM -}")
\end{code}
\begin{code}
data Inst
= Dict
- Id
+ Name
TcPredType
InstLoc
-- type of (f tys dicts(from theta)) = tau
-- INVARIANT 2: tau must not be of form (Pred -> Tau)
- -- Reason: two methods are considerd equal if the
+ -- Reason: two methods are considered equal if the
-- base Id matches, and the instantiating types
-- match. The TcThetaType should then match too.
-- This only bites in the call to tcInstClassOp in TcClassDcl.mkMethodBind
| LitInst
- Id
+ Name
HsOverLit -- The literal from the occurrence site
-- INVARIANT: never a rebindable-syntax literal
-- Reason: tcSyntaxName does unification, and we
functions that deal with it.
\begin{code}
-data InstLoc = InstLoc InstOrigin SrcLoc ErrCtxt
+data InstLoc = InstLoc InstOrigin SrcSpan ErrCtxt
instLocSrcLoc :: InstLoc -> SrcLoc
-instLocSrcLoc (InstLoc _ src_loc _) = src_loc
+instLocSrcLoc (InstLoc _ src_span _) = srcSpanStart src_span
-data InstOrigin
- = OccurrenceOf Name -- Occurrence of an overloaded identifier
+instLocSrcSpan :: InstLoc -> SrcSpan
+instLocSrcSpan (InstLoc _ src_span _) = src_span
- | IPOcc (IPName Name) -- Occurrence of an implicit parameter
- | IPBind (IPName Name) -- Binding site of an implicit parameter
+data InstOrigin
+ = SigOrigin SkolemInfo -- Pattern, class decl, inst decl etc;
+ -- Places that bind type variables and introduce
+ -- available constraints
- | RecordUpdOrigin
+ | IPBindOrigin (IPName Name) -- Binding site of an implicit parameter
- | DataDeclOrigin -- Typechecking a data declaration
+ -------------------------------------------------------
+ -- The rest are all occurrences: Insts that are 'wanted'
+ -------------------------------------------------------
+ | OccurrenceOf Name -- Occurrence of an overloaded identifier
- | InstanceDeclOrigin -- Typechecking an instance decl
+ | IPOccOrigin (IPName Name) -- Occurrence of an implicit parameter
| LiteralOrigin HsOverLit -- Occurrence of a literal
- | PatOrigin RenamedPat
-
- | ArithSeqOrigin RenamedArithSeqInfo -- [x..], [x..y] etc
- | PArrSeqOrigin RenamedArithSeqInfo -- [:x..y:] and [:x,y..z:]
-
- | SignatureOrigin -- A dict created from a type signature
- | Rank2Origin -- A dict created when typechecking the argument
- -- of a rank-2 typed function
-
- | DoOrigin -- The monad for a do expression
+ | ArithSeqOrigin (ArithSeqInfo Name) -- [x..], [x..y] etc
+ | PArrSeqOrigin (ArithSeqInfo Name) -- [:x..y:] and [:x,y..z:]
- | ClassDeclOrigin -- Manufactured during a class decl
+ | InstSigOrigin -- A dict occurrence arising from instantiating
+ -- a polymorphic type during a subsumption check
- | InstanceSpecOrigin Class -- in a SPECIALIZE instance pragma
- Type
-
- -- When specialising instances the instance info attached to
- -- each class is not yet ready, so we record it inside the
- -- origin information. This is a bit of a hack, but it works
- -- fine. (Patrick is to blame [WDP].)
-
- | ValSpecOrigin Name -- in a SPECIALIZE pragma for a value
-
- -- Argument or result of a ccall
- -- Dictionaries with this origin aren't actually mentioned in the
- -- translated term, and so need not be bound. Nor should they
- -- be abstracted over.
-
- | CCallOrigin String -- CCall label
- (Maybe RenamedHsExpr) -- Nothing if it's the result
- -- Just arg, for an argument
-
- | LitLitOrigin String -- the litlit
-
- | UnknownOrigin -- Help! I give up...
+ | RecordUpdOrigin
+ | InstScOrigin -- Typechecking superclasses of an instance declaration
+ | DerivOrigin -- Typechecking deriving
+ | DefaultOrigin -- Typechecking a default decl
+ | DoOrigin -- Arising from a do expression
+ | ProcOrigin -- Arising from a proc expression
\end{code}
\begin{code}
pprInstLoc :: InstLoc -> SDoc
-pprInstLoc (InstLoc orig locn ctxt)
+pprInstLoc (InstLoc (SigOrigin info) locn _)
+ = text "arising from" <+> ppr info -- I don't think this happens much, if at all
+pprInstLoc (InstLoc orig locn _)
= hsep [text "arising from", pp_orig orig, text "at", ppr locn]
where
- pp_orig (OccurrenceOf name)
- = hsep [ptext SLIT("use of"), quotes (ppr name)]
- pp_orig (IPOcc name)
- = hsep [ptext SLIT("use of implicit parameter"), quotes (ppr name)]
- pp_orig (IPBind name)
- = hsep [ptext SLIT("binding for implicit parameter"), quotes (ppr name)]
- pp_orig RecordUpdOrigin
- = ptext SLIT("a record update")
- pp_orig DataDeclOrigin
- = ptext SLIT("the data type declaration")
- pp_orig InstanceDeclOrigin
- = ptext SLIT("the instance declaration")
- pp_orig (LiteralOrigin lit)
- = hsep [ptext SLIT("the literal"), quotes (ppr lit)]
- pp_orig (PatOrigin pat)
- = hsep [ptext SLIT("the pattern"), quotes (ppr pat)]
- pp_orig (ArithSeqOrigin seq)
- = hsep [ptext SLIT("the arithmetic sequence"), quotes (ppr seq)]
- pp_orig (PArrSeqOrigin seq)
- = hsep [ptext SLIT("the parallel array sequence"), quotes (ppr seq)]
- pp_orig (SignatureOrigin)
- = ptext SLIT("a type signature")
- pp_orig (Rank2Origin)
- = ptext SLIT("a function with an overloaded argument type")
- pp_orig (DoOrigin)
- = ptext SLIT("a do statement")
- pp_orig (ClassDeclOrigin)
- = ptext SLIT("a class declaration")
- pp_orig (InstanceSpecOrigin clas ty)
- = hsep [text "a SPECIALIZE instance pragma; class",
- quotes (ppr clas), text "type:", ppr ty]
- pp_orig (ValSpecOrigin name)
- = hsep [ptext SLIT("a SPECIALIZE user-pragma for"), quotes (ppr name)]
- pp_orig (CCallOrigin clabel Nothing{-ccall result-})
- = hsep [ptext SLIT("the result of the _ccall_ to"), quotes (text clabel)]
- pp_orig (CCallOrigin clabel (Just arg_expr))
- = hsep [ptext SLIT("an argument in the _ccall_ to"), quotes (text clabel) <> comma,
- text "namely", quotes (ppr arg_expr)]
- pp_orig (LitLitOrigin s)
- = hsep [ptext SLIT("the ``literal-literal''"), quotes (text s)]
- pp_orig (UnknownOrigin)
- = ptext SLIT("...oops -- I don't know where the overloading came from!")
+ pp_orig (OccurrenceOf name) = hsep [ptext SLIT("use of"), quotes (ppr name)]
+ pp_orig (IPOccOrigin name) = hsep [ptext SLIT("use of implicit parameter"), quotes (ppr name)]
+ pp_orig (IPBindOrigin name) = hsep [ptext SLIT("binding for implicit parameter"), quotes (ppr name)]
+ pp_orig RecordUpdOrigin = ptext SLIT("a record update")
+ pp_orig (LiteralOrigin lit) = hsep [ptext SLIT("the literal"), quotes (ppr lit)]
+ pp_orig (ArithSeqOrigin seq) = hsep [ptext SLIT("the arithmetic sequence"), quotes (ppr seq)]
+ pp_orig (PArrSeqOrigin seq) = hsep [ptext SLIT("the parallel array sequence"), quotes (ppr seq)]
+ pp_orig InstSigOrigin = ptext SLIT("instantiating a type signature")
+ pp_orig InstScOrigin = ptext SLIT("the superclasses of an instance declaration")
+ pp_orig DerivOrigin = ptext SLIT("the 'deriving' clause of a data type declaration")
+ pp_orig DefaultOrigin = ptext SLIT("a 'default' declaration")
+ pp_orig DoOrigin = ptext SLIT("a do statement")
+ pp_orig ProcOrigin = ptext SLIT("a proc expression")
+ pp_orig (SigOrigin info) = ppr info
\end{code}