% (c) The University of Glasgow 2006-2012
% (c) The GRASP Project, Glasgow University, 1992-2002
%
Various types used during typechecking, please see TcRnMonad as well for
operations on these types. You probably want to import it, instead of this
module.
All the monads exported here are built on top of the same IOEnv monad. The
monad functions like a Reader monad in the way it passes the environment
around. This is done to allow the environment to be manipulated in a stack
like fashion when entering expressions... ect.
For state that is global and should be returned at the end (e.g not part
of the stack mechanism), you should use an TcRef (= IORef) to store them.
\begin{code}
module TcRnTypes(
TcRnIf, TcRn, TcM, RnM, IfM, IfL, IfG,
TcRef,
Env(..),
TcGblEnv(..), TcLclEnv(..),
IfGblEnv(..), IfLclEnv(..),
ErrCtxt, RecFieldEnv(..),
ImportAvails(..), emptyImportAvails, plusImportAvails,
WhereFrom(..), mkModDeps,
TcTypeEnv, TcIdBinder(..), TcTyThing(..), PromotionErr(..),
pprTcTyThingCategory, pprPECategory,
ThStage(..), topStage, topAnnStage, topSpliceStage,
ThLevel, impLevel, outerLevel, thLevel,
ArrowCtxt(NoArrowCtxt), newArrowScope, escapeArrowScope,
Xi, Ct(..), Cts, emptyCts, andCts, andManyCts, dropDerivedWC,
singleCt, extendCts, isEmptyCts, isCTyEqCan, isCFunEqCan,
isCDictCan_Maybe, isCFunEqCan_Maybe,
isCIrredEvCan, isCNonCanonical, isWantedCt, isDerivedCt,
isGivenCt, isHoleCt,
ctEvidence,
SubGoalDepth, mkNonCanonical, mkNonCanonicalCt,
ctPred, ctEvPred, ctEvTerm, ctEvId,
WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC,
andWC, unionsWC, addFlats, addImplics, mkFlatWC, addInsols,
Implication(..),
CtLoc(..), ctLocSpan, ctLocEnv, ctLocOrigin,
ctLocDepth, bumpCtLocDepth,
setCtLocOrigin, setCtLocEnv,
CtOrigin(..),
pushErrCtxt, pushErrCtxtSameOrigin,
SkolemInfo(..),
CtEvidence(..),
mkGivenLoc,
isWanted, isGiven,
isDerived, canSolve, canRewrite,
CtFlavour(..), ctEvFlavour, ctFlavour,
pprEvVarTheta, pprWantedsWithLocs,
pprEvVars, pprEvVarWithType,
pprArising, pprArisingAt,
TcId, TcIdSet, TcTyVarBind(..), TcTyVarBinds
) where
#include "HsVersions.h"
import HsSyn
import HscTypes
import TcEvidence
import Type
import Class ( Class )
import TyCon ( TyCon )
import DataCon ( DataCon, dataConUserType )
import TcType
import Annotations
import InstEnv
import FamInstEnv
import IOEnv
import RdrName
import Name
import NameEnv
import NameSet
import Avail
import Var
import VarEnv
import Module
import SrcLoc
import VarSet
import ErrUtils
import UniqFM
import UniqSupply
import BasicTypes
import Bag
import DynFlags
import Outputable
import ListSetOps
import FastString
import Data.Set (Set)
\end{code}
%************************************************************************
%* *
Standard monad definition for TcRn
All the combinators for the monad can be found in TcRnMonad
%* *
%************************************************************************
The monad itself has to be defined here, because it is mentioned by ErrCtxt
\begin{code}
type TcRef a = IORef a
type TcId = Id
type TcIdSet = IdSet
type TcRnIf a b c = IOEnv (Env a b) c
type IfM lcl a = TcRnIf IfGblEnv lcl a
type IfG a = IfM () a
type IfL a = IfM IfLclEnv a
type TcRn a = TcRnIf TcGblEnv TcLclEnv a
type RnM a = TcRn a
type TcM a = TcRn a
\end{code}
Representation of type bindings to uninstantiated meta variables used during
constraint solving.
\begin{code}
data TcTyVarBind = TcTyVarBind TcTyVar TcType
type TcTyVarBinds = Bag TcTyVarBind
instance Outputable TcTyVarBind where
ppr (TcTyVarBind tv ty) = ppr tv <+> text ":=" <+> ppr ty
\end{code}
%************************************************************************
%* *
The main environment types
%* *
%************************************************************************
\begin{code}
data Env gbl lcl
= Env {
env_top :: HscEnv,
env_us :: !(IORef UniqSupply),
env_gbl :: gbl,
env_lcl :: lcl
}
instance ContainsDynFlags (Env gbl lcl) where
extractDynFlags env = hsc_dflags (env_top env)
replaceDynFlags env dflags
= env {env_top = replaceDynFlags (env_top env) dflags}
instance ContainsModule gbl => ContainsModule (Env gbl lcl) where
extractModule env = extractModule (env_gbl env)
data TcGblEnv
= TcGblEnv {
tcg_mod :: Module,
tcg_src :: HscSource,
tcg_rdr_env :: GlobalRdrEnv,
tcg_default :: Maybe [Type],
tcg_fix_env :: FixityEnv,
tcg_field_env :: RecFieldEnv,
tcg_type_env :: TypeEnv,
tcg_type_env_var :: TcRef TypeEnv,
tcg_inst_env :: InstEnv,
tcg_fam_inst_env :: FamInstEnv,
tcg_exports :: [AvailInfo],
tcg_imports :: ImportAvails,
tcg_dus :: DefUses,
tcg_used_rdrnames :: TcRef (Set RdrName),
tcg_keep :: TcRef NameSet,
tcg_th_used :: TcRef Bool,
tcg_th_splice_used :: TcRef Bool,
tcg_dfun_n :: TcRef OccSet,
tcg_rn_exports :: Maybe [Located (IE Name)],
tcg_rn_imports :: [LImportDecl Name],
tcg_rn_decls :: Maybe (HsGroup Name),
tcg_dependent_files :: TcRef [FilePath],
tcg_ev_binds :: Bag EvBind,
tcg_binds :: LHsBinds Id,
tcg_sigs :: NameSet,
tcg_imp_specs :: [LTcSpecPrag],
tcg_warns :: Warnings,
tcg_anns :: [Annotation],
tcg_tcs :: [TyCon],
tcg_insts :: [ClsInst],
tcg_fam_insts :: [FamInst],
tcg_rules :: [LRuleDecl Id],
tcg_fords :: [LForeignDecl Id],
tcg_vects :: [LVectDecl Id],
tcg_doc_hdr :: Maybe LHsDocString,
tcg_hpc :: AnyHpcUsage,
tcg_main :: Maybe Name,
tcg_safeInfer :: TcRef Bool
}
instance ContainsModule TcGblEnv where
extractModule env = tcg_mod env
data RecFieldEnv
= RecFields (NameEnv [Name])
NameSet
\end{code}
Note [Tracking unused binding and imports]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We gather two sorts of usage information
* tcg_dus (defs/uses)
Records *defined* Names (local, top-level)
and *used* Names (local or imported)
Used (a) to report "defined but not used"
(see RnNames.reportUnusedNames)
(b) to generate version-tracking usage info in interface
files (see MkIface.mkUsedNames)
This usage info is mainly gathered by the renamer's
gathering of free-variables
* tcg_used_rdrnames
Records used *imported* (not locally-defined) RdrNames
Used only to report unused import declarations
Notice that they are RdrNames, not Names, so we can
tell whether the reference was qualified or unqualified, which
is esssential in deciding whether a particular import decl
is unnecessary. This info isn't present in Names.
%************************************************************************
%* *
The interface environments
Used when dealing with IfaceDecls
%* *
%************************************************************************
\begin{code}
data IfGblEnv
= IfGblEnv {
if_rec_types :: Maybe (Module, IfG TypeEnv)
}
data IfLclEnv
= IfLclEnv {
if_mod :: Module,
if_loc :: SDoc,
if_tv_env :: UniqFM TyVar,
if_id_env :: UniqFM Id
}
\end{code}
%************************************************************************
%* *
The local typechecker environment
%* *
%************************************************************************
The Global-Env/Local-Env story
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
During type checking, we keep in the tcg_type_env
* All types and classes
* All Ids derived from types and classes (constructors, selectors)
At the end of type checking, we zonk the local bindings,
and as we do so we add to the tcg_type_env
* Locally defined top-level Ids
Why? Because they are now Ids not TcIds. This final GlobalEnv is
a) fed back (via the knot) to typechecking the
unfoldings of interface signatures
b) used in the ModDetails of this module
\begin{code}
data TcLclEnv
= TcLclEnv {
tcl_loc :: SrcSpan,
tcl_ctxt :: [ErrCtxt],
tcl_untch :: Untouchables,
tcl_th_ctxt :: ThStage,
tcl_arrow_ctxt :: ArrowCtxt,
tcl_rdr :: LocalRdrEnv,
tcl_env :: TcTypeEnv,
tcl_bndrs :: [TcIdBinder],
tcl_tidy :: TidyEnv,
tcl_tyvars :: TcRef TcTyVarSet,
tcl_lie :: TcRef WantedConstraints,
tcl_errs :: TcRef Messages
}
type TcTypeEnv = NameEnv TcTyThing
data TcIdBinder = TcIdBndr TcId TopLevelFlag
data ThStage
= Splice
| Comp
| Brack
ThStage
(TcRef [PendingSplice])
(TcRef WantedConstraints)
topStage, topAnnStage, topSpliceStage :: ThStage
topStage = Comp
topAnnStage = Splice
topSpliceStage = Splice
instance Outputable ThStage where
ppr Splice = text "Splice"
ppr Comp = text "Comp"
ppr (Brack s _ _) = text "Brack" <> parens (ppr s)
type ThLevel = Int
impLevel, outerLevel :: ThLevel
impLevel = 0
outerLevel = 1
thLevel :: ThStage -> ThLevel
thLevel Splice = 0
thLevel Comp = 1
thLevel (Brack s _ _) = thLevel s + 1
data ArrowCtxt
= NoArrowCtxt
| ArrowCtxt (Env TcGblEnv TcLclEnv)
newArrowScope :: TcM a -> TcM a
newArrowScope
= updEnv $ \env ->
env { env_lcl = (env_lcl env) { tcl_arrow_ctxt = ArrowCtxt env } }
escapeArrowScope :: TcM a -> TcM a
escapeArrowScope
= updEnv $ \ env -> case tcl_arrow_ctxt (env_lcl env) of
NoArrowCtxt -> env
ArrowCtxt env' -> env'
data TcTyThing
= AGlobal TyThing
| ATcId {
tct_id :: TcId,
tct_closed :: TopLevelFlag,
tct_level :: ThLevel }
| ATyVar Name TcTyVar
| AThing TcKind
| APromotionErr PromotionErr
data PromotionErr
= TyConPE
| ClassPE
| FamDataConPE
| RecDataConPE
| NoDataKinds
instance Outputable TcTyThing where
ppr (AGlobal g) = pprTyThing g
ppr elt@(ATcId {}) = text "Identifier" <>
brackets (ppr (tct_id elt) <> dcolon
<> ppr (varType (tct_id elt)) <> comma
<+> ppr (tct_closed elt) <> comma
<+> ppr (tct_level elt))
ppr (ATyVar n tv) = text "Type variable" <+> quotes (ppr n) <+> equals <+> ppr tv
ppr (AThing k) = text "AThing" <+> ppr k
ppr (APromotionErr err) = text "APromotionErr" <+> ppr err
instance Outputable PromotionErr where
ppr ClassPE = text "ClassPE"
ppr TyConPE = text "TyConPE"
ppr FamDataConPE = text "FamDataConPE"
ppr RecDataConPE = text "RecDataConPE"
ppr NoDataKinds = text "NoDataKinds"
pprTcTyThingCategory :: TcTyThing -> SDoc
pprTcTyThingCategory (AGlobal thing) = pprTyThingCategory thing
pprTcTyThingCategory (ATyVar {}) = ptext (sLit "Type variable")
pprTcTyThingCategory (ATcId {}) = ptext (sLit "Local identifier")
pprTcTyThingCategory (AThing {}) = ptext (sLit "Kinded thing")
pprTcTyThingCategory (APromotionErr pe) = pprPECategory pe
pprPECategory :: PromotionErr -> SDoc
pprPECategory ClassPE = ptext (sLit "Class")
pprPECategory TyConPE = ptext (sLit "Type constructor")
pprPECategory FamDataConPE = ptext (sLit "Data constructor")
pprPECategory RecDataConPE = ptext (sLit "Data constructor")
pprPECategory NoDataKinds = ptext (sLit "Data constructor")
\end{code}
Note [Bindings with closed types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
f x = let g ys = map not ys
in ...
Can we generalise 'g' under the OutsideIn algorithm? Yes,
because all g's free variables are top-level; that is they themselves
have no free type variables, and it is the type variables in the
environment that makes things tricky for OutsideIn generalisation.
Definition:
A variable is "closed", and has tct_closed set to TopLevel,
iff
a) all its free variables are imported, or are themselves closed
b) generalisation is not restricted by the monomorphism restriction
Under OutsideIn we are free to generalise a closed let-binding.
This is an extension compared to the JFP paper on OutsideIn, which
used "top-level" as a proxy for "closed". (It's not a good proxy
anyway -- the MR can make a top-level binding with a free type
variable.)
Note that:
* A top-level binding may not be closed, if it suffer from the MR
* A nested binding may be closed (eg 'g' in the example we started with)
Indeed, that's the point; whether a function is defined at top level
or nested is orthogonal to the question of whether or not it is closed
* A binding may be non-closed because it mentions a lexically scoped
*type variable* Eg
f :: forall a. blah
f x = let g y = ...(y::a)...
\begin{code}
type ErrCtxt = (Bool, TidyEnv -> TcM (TidyEnv, MsgDoc))
\end{code}
%************************************************************************
%* *
Operations over ImportAvails
%* *
%************************************************************************
\begin{code}
data ImportAvails
= ImportAvails {
imp_mods :: ImportedMods,
imp_dep_mods :: ModuleNameEnv (ModuleName, IsBootInterface),
imp_dep_pkgs :: [PackageId],
imp_trust_pkgs :: [PackageId],
imp_trust_own_pkg :: Bool,
imp_orphs :: [Module],
imp_finsts :: [Module]
}
mkModDeps :: [(ModuleName, IsBootInterface)]
-> ModuleNameEnv (ModuleName, IsBootInterface)
mkModDeps deps = foldl add emptyUFM deps
where
add env elt@(m,_) = addToUFM env m elt
emptyImportAvails :: ImportAvails
emptyImportAvails = ImportAvails { imp_mods = emptyModuleEnv,
imp_dep_mods = emptyUFM,
imp_dep_pkgs = [],
imp_trust_pkgs = [],
imp_trust_own_pkg = False,
imp_orphs = [],
imp_finsts = [] }
plusImportAvails :: ImportAvails -> ImportAvails -> ImportAvails
plusImportAvails
(ImportAvails { imp_mods = mods1,
imp_dep_mods = dmods1, imp_dep_pkgs = dpkgs1,
imp_trust_pkgs = tpkgs1, imp_trust_own_pkg = tself1,
imp_orphs = orphs1, imp_finsts = finsts1 })
(ImportAvails { imp_mods = mods2,
imp_dep_mods = dmods2, imp_dep_pkgs = dpkgs2,
imp_trust_pkgs = tpkgs2, imp_trust_own_pkg = tself2,
imp_orphs = orphs2, imp_finsts = finsts2 })
= ImportAvails { imp_mods = plusModuleEnv_C (++) mods1 mods2,
imp_dep_mods = plusUFM_C plus_mod_dep dmods1 dmods2,
imp_dep_pkgs = dpkgs1 `unionLists` dpkgs2,
imp_trust_pkgs = tpkgs1 `unionLists` tpkgs2,
imp_trust_own_pkg = tself1 || tself2,
imp_orphs = orphs1 `unionLists` orphs2,
imp_finsts = finsts1 `unionLists` finsts2 }
where
plus_mod_dep (m1, boot1) (m2, boot2)
= WARN( not (m1 == m2), (ppr m1 <+> ppr m2) $$ (ppr boot1 <+> ppr boot2) )
(m1, boot1 && boot2)
\end{code}
%************************************************************************
%* *
\subsection{Where from}
%* *
%************************************************************************
The @WhereFrom@ type controls where the renamer looks for an interface file
\begin{code}
data WhereFrom
= ImportByUser IsBootInterface
| ImportBySystem
| ImportByPlugin
instance Outputable WhereFrom where
ppr (ImportByUser is_boot) | is_boot = ptext (sLit "{- SOURCE -}")
| otherwise = empty
ppr ImportBySystem = ptext (sLit "{- SYSTEM -}")
ppr ImportByPlugin = ptext (sLit "{- PLUGIN -}")
\end{code}
%************************************************************************
%* *
%* Canonical constraints *
%* *
%* These are the constraints the low-level simplifier works with *
%* *
%************************************************************************
\begin{code}
type Xi = Type
type Cts = Bag Ct
data Ct
= CDictCan {
cc_ev :: CtEvidence,
cc_class :: Class,
cc_tyargs :: [Xi],
cc_loc :: CtLoc
}
| CIrredEvCan {
cc_ev :: CtEvidence,
cc_loc :: CtLoc
}
| CTyEqCan {
cc_ev :: CtEvidence,
cc_tyvar :: TcTyVar,
cc_rhs :: Xi,
cc_loc :: CtLoc
}
| CFunEqCan {
cc_ev :: CtEvidence,
cc_fun :: TyCon,
cc_tyargs :: [Xi],
cc_rhs :: Xi,
cc_loc :: CtLoc
}
| CNonCanonical {
cc_ev :: CtEvidence,
cc_loc :: CtLoc
}
| CHoleCan {
cc_ev :: CtEvidence,
cc_loc :: CtLoc,
cc_occ :: OccName
}
\end{code}
Note [Kind orientation for CTyEqCan]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Given an equality (t:* ~ s:Open), we absolutely want to re-orient it.
We can't solve it by updating t:=s, ragardless of how touchable 't' is,
because the kinds don't work. Indeed we don't want to leave it with
the orientation (t ~ s), becuase if that gets into the inert set we'll
start replacing t's by s's, and that too is the wrong way round.
Hence in a CTyEqCan, (t:k1 ~ xi:k2) we require that k2 is a subkind of k1.
If the two have incompatible kinds, we just don't use a CTyEqCan at all.
See Note [Equalities with incompatible kinds] in TcCanonical
We can't require *equal* kinds, because
* wanted constraints don't necessarily have identical kinds
eg alpha::? ~ Int
* a solved wanted constraint becomes a given
Note [Kind orientation for CFunEqCan]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For (F xis ~ rhs) we require that kind(rhs) is a subkind of kind(lhs).
This reallly only maters when rhs is an Open type variable (since only type
variables have Open kinds):
F ty ~ (a:Open)
which can happen, say, from
f :: F a b
f = undefined -- The a:Open comes from instantiating 'undefined'
Note that the kind invariant is maintained by rewriting.
Eg wanted1 rewrites wanted2; if both were compatible kinds before,
wanted2 will be afterwards. Similarly givens.
Caveat:
- Givens from higher-rank, such as:
type family T b :: * -> * -> *
type instance T Bool = (->)
f :: forall a. ((T a ~ (->)) => ...) -> a -> ...
flop = f (...) True
Whereas we would be able to apply the type instance, we would not be able to
use the given (T Bool ~ (->)) in the body of 'flop'
Note [CIrredEvCan constraints]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CIrredEvCan constraints are used for constraints that are "stuck"
- we can't solve them (yet)
- we can't use them to solve other constraints
- but they may become soluble if we substitute for some
of the type variables in the constraint
Example 1: (c Int), where c :: * -> Constraint. We can't do anything
with this yet, but if later c := Num, *then* we can solve it
Example 2: a ~ b, where a :: *, b :: k, where k is a kind variable
We don't want to use this to substitute 'b' for 'a', in case
'k' is subequently unifed with (say) *->*, because then
we'd have ill-kinded types floating about. Rather we want
to defer using the equality altogether until 'k' get resolved.
Note [Ct/evidence invariant]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If ct :: Ct, then extra fields of 'ct' cache precisely the ctev_pred field
of (cc_ev ct), and is fully rewritten wrt the substitution. Eg for CDictCan,
ctev_pred (cc_ev ct) = (cc_class ct) (cc_tyargs ct)
This holds by construction; look at the unique place where CDictCan is
built (in TcCanonical).
In contrast, the type of the evidence *term* (ccev_evtm or ctev_evar) in
the evidence may *not* be fully zonked; we are careful not to look at it
during constraint solving. See Note [Evidence field of CtEvidence]
\begin{code}
mkNonCanonical :: CtLoc -> CtEvidence -> Ct
mkNonCanonical loc ev = CNonCanonical { cc_ev = ev, cc_loc = loc }
mkNonCanonicalCt :: Ct -> Ct
mkNonCanonicalCt ct = CNonCanonical { cc_ev = cc_ev ct, cc_loc = cc_loc ct }
ctEvidence :: Ct -> CtEvidence
ctEvidence = cc_ev
ctPred :: Ct -> PredType
ctPred ct = ctEvPred (cc_ev ct)
dropDerivedWC :: WantedConstraints -> WantedConstraints
dropDerivedWC wc@(WC { wc_flat = flats, wc_insol = insols })
= wc { wc_flat = filterBag isWantedCt flats
, wc_insol = filterBag (not . isDerivedCt) insols }
\end{code}
Note [Insoluble derived constraints]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In general we discard derived constraints at the end of constraint solving;
see dropDerivedWC. For example,
* If we have an unsolved (Ord a), we don't want to complain about
an unsolved (Eq a) as well.
* If we have kind-incompatible (a::* ~ Int#::#) equality, we
don't want to complain about the kind error twice.
Arguably, for *some* derived constraints we might want to report errors.
Notably, functional dependencies. If we have
class C a b | a -> b
and we have
[W] C a b, [W] C a c
where a,b,c are all signature variables. Then we could reasonably
report an error unifying (b ~ c). But it's probably not worth it;
after all, we also get an error because we can't discharge the constraint.
%************************************************************************
%* *
CtEvidence
The "flavor" of a canonical constraint
%* *
%************************************************************************
\begin{code}
isWantedCt :: Ct -> Bool
isWantedCt = isWanted . cc_ev
isGivenCt :: Ct -> Bool
isGivenCt = isGiven . cc_ev
isDerivedCt :: Ct -> Bool
isDerivedCt = isDerived . cc_ev
isCTyEqCan :: Ct -> Bool
isCTyEqCan (CTyEqCan {}) = True
isCTyEqCan (CFunEqCan {}) = False
isCTyEqCan _ = False
isCDictCan_Maybe :: Ct -> Maybe Class
isCDictCan_Maybe (CDictCan {cc_class = cls }) = Just cls
isCDictCan_Maybe _ = Nothing
isCIrredEvCan :: Ct -> Bool
isCIrredEvCan (CIrredEvCan {}) = True
isCIrredEvCan _ = False
isCFunEqCan_Maybe :: Ct -> Maybe TyCon
isCFunEqCan_Maybe (CFunEqCan { cc_fun = tc }) = Just tc
isCFunEqCan_Maybe _ = Nothing
isCFunEqCan :: Ct -> Bool
isCFunEqCan (CFunEqCan {}) = True
isCFunEqCan _ = False
isCNonCanonical :: Ct -> Bool
isCNonCanonical (CNonCanonical {}) = True
isCNonCanonical _ = False
isHoleCt:: Ct -> Bool
isHoleCt (CHoleCan {}) = True
isHoleCt _ = False
\end{code}
\begin{code}
instance Outputable Ct where
ppr ct = ppr (cc_ev ct) <+> parens (text ct_sort)
where ct_sort = case ct of
CTyEqCan {} -> "CTyEqCan"
CFunEqCan {} -> "CFunEqCan"
CNonCanonical {} -> "CNonCanonical"
CDictCan {} -> "CDictCan"
CIrredEvCan {} -> "CIrredEvCan"
CHoleCan {} -> "CHoleCan"
\end{code}
\begin{code}
singleCt :: Ct -> Cts
singleCt = unitBag
andCts :: Cts -> Cts -> Cts
andCts = unionBags
extendCts :: Cts -> Ct -> Cts
extendCts = snocBag
andManyCts :: [Cts] -> Cts
andManyCts = unionManyBags
emptyCts :: Cts
emptyCts = emptyBag
isEmptyCts :: Cts -> Bool
isEmptyCts = isEmptyBag
\end{code}
%************************************************************************
%* *
Wanted constraints
These are forced to be in TcRnTypes because
TcLclEnv mentions WantedConstraints
WantedConstraint mentions CtLoc
CtLoc mentions ErrCtxt
ErrCtxt mentions TcM
%* *
v%************************************************************************
\begin{code}
data WantedConstraints
= WC { wc_flat :: Cts
, wc_impl :: Bag Implication
, wc_insol :: Cts
}
emptyWC :: WantedConstraints
emptyWC = WC { wc_flat = emptyBag, wc_impl = emptyBag, wc_insol = emptyBag }
mkFlatWC :: [Ct] -> WantedConstraints
mkFlatWC cts
= WC { wc_flat = listToBag cts, wc_impl = emptyBag, wc_insol = emptyBag }
isEmptyWC :: WantedConstraints -> Bool
isEmptyWC (WC { wc_flat = f, wc_impl = i, wc_insol = n })
= isEmptyBag f && isEmptyBag i && isEmptyBag n
insolubleWC :: WantedConstraints -> Bool
insolubleWC wc = not (isEmptyBag (wc_insol wc))
|| anyBag ic_insol (wc_impl wc)
andWC :: WantedConstraints -> WantedConstraints -> WantedConstraints
andWC (WC { wc_flat = f1, wc_impl = i1, wc_insol = n1 })
(WC { wc_flat = f2, wc_impl = i2, wc_insol = n2 })
= WC { wc_flat = f1 `unionBags` f2
, wc_impl = i1 `unionBags` i2
, wc_insol = n1 `unionBags` n2 }
unionsWC :: [WantedConstraints] -> WantedConstraints
unionsWC = foldr andWC emptyWC
addFlats :: WantedConstraints -> Bag Ct -> WantedConstraints
addFlats wc cts
= wc { wc_flat = wc_flat wc `unionBags` cts }
addImplics :: WantedConstraints -> Bag Implication -> WantedConstraints
addImplics wc implic = wc { wc_impl = wc_impl wc `unionBags` implic }
addInsols :: WantedConstraints -> Bag Ct -> WantedConstraints
addInsols wc cts
= wc { wc_insol = wc_insol wc `unionBags` cts }
instance Outputable WantedConstraints where
ppr (WC {wc_flat = f, wc_impl = i, wc_insol = n})
= ptext (sLit "WC") <+> braces (vcat
[ if isEmptyBag f then empty else
ptext (sLit "wc_flat =") <+> pprBag ppr f
, if isEmptyBag i then empty else
ptext (sLit "wc_impl =") <+> pprBag ppr i
, if isEmptyBag n then empty else
ptext (sLit "wc_insol =") <+> pprBag ppr n ])
pprBag :: (a -> SDoc) -> Bag a -> SDoc
pprBag pp b = foldrBag (($$) . pp) empty b
\end{code}
%************************************************************************
%* *
Implication constraints
%* *
%************************************************************************
\begin{code}
data Implication
= Implic {
ic_untch :: Untouchables,
ic_skols :: [TcTyVar],
ic_info :: SkolemInfo,
ic_fsks :: [TcTyVar],
ic_given :: [EvVar],
ic_env :: TcLclEnv,
ic_wanted :: WantedConstraints,
ic_insol :: Bool,
ic_binds :: EvBindsVar
}
instance Outputable Implication where
ppr (Implic { ic_untch = untch, ic_skols = skols, ic_fsks = fsks
, ic_given = given
, ic_wanted = wanted
, ic_binds = binds, ic_info = info })
= ptext (sLit "Implic") <+> braces
(sep [ ptext (sLit "Untouchables =") <+> ppr untch
, ptext (sLit "Skolems =") <+> ppr skols
, ptext (sLit "Flatten-skolems =") <+> ppr fsks
, ptext (sLit "Given =") <+> pprEvVars given
, ptext (sLit "Wanted =") <+> ppr wanted
, ptext (sLit "Binds =") <+> ppr binds
, pprSkolInfo info ])
\end{code}
Note [Shadowing in a constraint]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We assume NO SHADOWING in a constraint. Specifically
* The unification variables are all implicitly quantified at top
level, and are all unique
* The skolem varibles bound in ic_skols are all freah when the
implication is created.
So we can safely substitute. For example, if we have
forall a. a~Int => ...(forall b. ...a...)...
we can push the (a~Int) constraint inwards in the "givens" without
worrying that 'b' might clash.
Note [Skolems in an implication]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The skolems in an implication are not there to perform a skolem escape
check. That happens because all the environment variables are in the
untouchables, and therefore cannot be unified with anything at all,
let alone the skolems.
Instead, ic_skols is used only when considering floating a constraint
outside the implication in TcSimplify.floatEqualities or
TcSimplify.approximateImplications
Note [Insoluble constraints]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some of the errors that we get during canonicalization are best
reported when all constraints have been simplified as much as
possible. For instance, assume that during simplification the
following constraints arise:
[Wanted] F alpha ~ uf1
[Wanted] beta ~ uf1 beta
When canonicalizing the wanted (beta ~ uf1 beta), if we eagerly fail
we will simply see a message:
'Can't construct the infinite type beta ~ uf1 beta'
and the user has no idea what the uf1 variable is.
Instead our plan is that we will NOT fail immediately, but:
(1) Record the "frozen" error in the ic_insols field
(2) Isolate the offending constraint from the rest of the inerts
(3) Keep on simplifying/canonicalizing
At the end, we will hopefully have substituted uf1 := F alpha, and we
will be able to report a more informative error:
'Can't construct the infinite type beta ~ F alpha beta'
Insoluble constraints *do* include Derived constraints. For example,
a functional dependency might give rise to [D] Int ~ Bool, and we must
report that. If insolubles did not contain Deriveds, reportErrors would
never see it.
%************************************************************************
%* *
Pretty printing
%* *
%************************************************************************
\begin{code}
pprEvVars :: [EvVar] -> SDoc
pprEvVars ev_vars = vcat (map pprEvVarWithType ev_vars)
pprEvVarTheta :: [EvVar] -> SDoc
pprEvVarTheta ev_vars = pprTheta (map evVarPred ev_vars)
pprEvVarWithType :: EvVar -> SDoc
pprEvVarWithType v = ppr v <+> dcolon <+> pprType (evVarPred v)
pprWantedsWithLocs :: WantedConstraints -> SDoc
pprWantedsWithLocs wcs
= vcat [ pprBag ppr (wc_flat wcs)
, pprBag ppr (wc_impl wcs)
, pprBag ppr (wc_insol wcs) ]
\end{code}
%************************************************************************
%* *
CtEvidence
%* *
%************************************************************************
Note [Evidence field of CtEvidence]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
During constraint solving we never look at the type of ctev_evtm, or
ctev_evar; instead we look at the cte_pred field. The evtm/evar field
may be un-zonked.
\begin{code}
data CtEvidence
= CtGiven { ctev_pred :: TcPredType
, ctev_evtm :: EvTerm }
| CtWanted { ctev_pred :: TcPredType
, ctev_evar :: EvVar }
| CtDerived { ctev_pred :: TcPredType }
data CtFlavour = Given | Wanted | Derived
ctFlavour :: Ct -> CtFlavour
ctFlavour ct = ctEvFlavour (cc_ev ct)
ctEvFlavour :: CtEvidence -> CtFlavour
ctEvFlavour (CtGiven {}) = Given
ctEvFlavour (CtWanted {}) = Wanted
ctEvFlavour (CtDerived {}) = Derived
ctEvPred :: CtEvidence -> TcPredType
ctEvPred = ctev_pred
ctEvTerm :: CtEvidence -> EvTerm
ctEvTerm (CtGiven { ctev_evtm = tm }) = tm
ctEvTerm (CtWanted { ctev_evar = ev }) = EvId ev
ctEvTerm ctev@(CtDerived {}) = pprPanic "ctEvTerm: derived constraint cannot have id"
(ppr ctev)
ctEvId :: CtEvidence -> TcId
ctEvId (CtWanted { ctev_evar = ev }) = ev
ctEvId ctev = pprPanic "ctEvId:" (ppr ctev)
instance Outputable CtFlavour where
ppr Given = ptext (sLit "[G]")
ppr Wanted = ptext (sLit "[W]")
ppr Derived = ptext (sLit "[D]")
instance Outputable CtEvidence where
ppr fl = case fl of
CtGiven {} -> ptext (sLit "[G]") <+> ppr (ctev_evtm fl) <+> ppr_pty
CtWanted {} -> ptext (sLit "[W]") <+> ppr (ctev_evar fl) <+> ppr_pty
CtDerived {} -> ptext (sLit "[D]") <+> text "_" <+> ppr_pty
where ppr_pty = dcolon <+> ppr (ctEvPred fl)
isWanted :: CtEvidence -> Bool
isWanted (CtWanted {}) = True
isWanted _ = False
isGiven :: CtEvidence -> Bool
isGiven (CtGiven {}) = True
isGiven _ = False
isDerived :: CtEvidence -> Bool
isDerived (CtDerived {}) = True
isDerived _ = False
canSolve :: CtFlavour -> CtFlavour -> Bool
canSolve Given _ = True
canSolve Wanted Derived = True
canSolve Wanted Wanted = True
canSolve Derived Derived = True
canSolve _ _ = False
canRewrite :: CtFlavour -> CtFlavour -> Bool
canRewrite = canSolve
\end{code}
%************************************************************************
%* *
CtLoc
%* *
%************************************************************************
The 'CtLoc' gives information about where a constraint came from.
This is important for decent error message reporting because
dictionaries don't appear in the original source code.
type will evolve...
\begin{code}
data CtLoc = CtLoc { ctl_origin :: CtOrigin
, ctl_env :: TcLclEnv
, ctl_depth :: SubGoalDepth }
type SubGoalDepth = Int
mkGivenLoc :: SkolemInfo -> TcLclEnv -> CtLoc
mkGivenLoc skol_info env = CtLoc { ctl_origin = GivenOrigin skol_info
, ctl_env = env
, ctl_depth = 0 }
ctLocEnv :: CtLoc -> TcLclEnv
ctLocEnv = ctl_env
ctLocDepth :: CtLoc -> SubGoalDepth
ctLocDepth = ctl_depth
ctLocOrigin :: CtLoc -> CtOrigin
ctLocOrigin = ctl_origin
ctLocSpan :: CtLoc -> SrcSpan
ctLocSpan (CtLoc { ctl_env = lcl}) = tcl_loc lcl
bumpCtLocDepth :: CtLoc -> CtLoc
bumpCtLocDepth loc@(CtLoc { ctl_depth = d }) = loc { ctl_depth = d+1 }
setCtLocOrigin :: CtLoc -> CtOrigin -> CtLoc
setCtLocOrigin ctl orig = ctl { ctl_origin = orig }
setCtLocEnv :: CtLoc -> TcLclEnv -> CtLoc
setCtLocEnv ctl env = ctl { ctl_env = env }
pushErrCtxt :: CtOrigin -> ErrCtxt -> CtLoc -> CtLoc
pushErrCtxt o err loc@(CtLoc { ctl_env = lcl })
= loc { ctl_origin = o, ctl_env = lcl { tcl_ctxt = err : tcl_ctxt lcl } }
pushErrCtxtSameOrigin :: ErrCtxt -> CtLoc -> CtLoc
pushErrCtxtSameOrigin err loc@(CtLoc { ctl_env = lcl })
= loc { ctl_env = lcl { tcl_ctxt = err : tcl_ctxt lcl } }
pprArising :: CtOrigin -> SDoc
pprArising (TypeEqOrigin {}) = empty
pprArising FunDepOrigin = empty
pprArising orig = text "arising from" <+> ppr orig
pprArisingAt :: CtLoc -> SDoc
pprArisingAt (CtLoc { ctl_origin = o, ctl_env = lcl})
= sep [ text "arising from" <+> ppr o
, text "at" <+> ppr (tcl_loc lcl)]
\end{code}
%************************************************************************
%* *
SkolemInfo
%* *
%************************************************************************
\begin{code}
data SkolemInfo
= SigSkol UserTypeCtxt
Type
| ClsSkol Class
| InstSkol
| DataSkol
| FamInstSkol
| PatSkol
DataCon
(HsMatchContext Name)
| ArrowSkol
| IPSkol [HsIPName]
| RuleSkol RuleName
| InferSkol [(Name,TcType)]
| BracketSkol
| UnifyForAllSkol
[TcTyVar]
TcType
| UnkSkol
instance Outputable SkolemInfo where
ppr = pprSkolInfo
pprSkolInfo :: SkolemInfo -> SDoc
pprSkolInfo (SigSkol (FunSigCtxt f) ty)
= hang (ptext (sLit "the type signature for"))
2 (pprPrefixOcc f <+> dcolon <+> ppr ty)
pprSkolInfo (SigSkol cx ty) = hang (pprUserTypeCtxt cx <> colon)
2 (ppr ty)
pprSkolInfo (IPSkol ips) = ptext (sLit "the implicit-parameter bindings for")
<+> pprWithCommas ppr ips
pprSkolInfo (ClsSkol cls) = ptext (sLit "the class declaration for") <+> quotes (ppr cls)
pprSkolInfo InstSkol = ptext (sLit "the instance declaration")
pprSkolInfo DataSkol = ptext (sLit "the data type declaration")
pprSkolInfo FamInstSkol = ptext (sLit "the family instance declaration")
pprSkolInfo BracketSkol = ptext (sLit "a Template Haskell bracket")
pprSkolInfo (RuleSkol name) = ptext (sLit "the RULE") <+> doubleQuotes (ftext name)
pprSkolInfo ArrowSkol = ptext (sLit "the arrow form")
pprSkolInfo (PatSkol dc mc) = sep [ ptext (sLit "a pattern with constructor")
, nest 2 $ ppr dc <+> dcolon
<+> ppr (dataConUserType dc) <> comma
, ptext (sLit "in") <+> pprMatchContext mc ]
pprSkolInfo (InferSkol ids) = sep [ ptext (sLit "the inferred type of")
, vcat [ ppr name <+> dcolon <+> ppr ty
| (name,ty) <- ids ]]
pprSkolInfo (UnifyForAllSkol tvs ty) = ptext (sLit "the type") <+> ppr (mkForAllTys tvs ty)
pprSkolInfo UnkSkol = WARN( True, text "pprSkolInfo: UnkSkol" ) ptext (sLit "UnkSkol")
\end{code}
%************************************************************************
%* *
CtOrigin
%* *
%************************************************************************
\begin{code}
data CtOrigin
= GivenOrigin SkolemInfo
| OccurrenceOf Name
| AppOrigin
| SpecPragOrigin Name
| TypeEqOrigin { uo_actual :: TcType
, uo_expected :: TcType }
| KindEqOrigin
TcType TcType
CtOrigin
| IPOccOrigin HsIPName
| LiteralOrigin (HsOverLit Name)
| NegateOrigin
| ArithSeqOrigin (ArithSeqInfo Name)
| PArrSeqOrigin (ArithSeqInfo Name)
| SectionOrigin
| TupleOrigin
| AmbigOrigin UserTypeCtxt
| ExprSigOrigin
| PatSigOrigin
| PatOrigin
| RecordUpdOrigin
| ViewPatOrigin
| ScOrigin
| DerivOrigin
| StandAloneDerivOrigin
| DefaultOrigin
| DoOrigin
| MCompOrigin
| IfOrigin
| ProcOrigin
| AnnOrigin
| FunDepOrigin
| HoleOrigin
| UnboundOccurrenceOf RdrName
| ListOrigin
pprO :: CtOrigin -> SDoc
pprO (GivenOrigin sk) = ppr sk
pprO (OccurrenceOf name) = hsep [ptext (sLit "a use of"), quotes (ppr name)]
pprO AppOrigin = ptext (sLit "an application")
pprO (SpecPragOrigin name) = hsep [ptext (sLit "a specialisation pragma for"), quotes (ppr name)]
pprO (IPOccOrigin name) = hsep [ptext (sLit "a use of implicit parameter"), quotes (ppr name)]
pprO RecordUpdOrigin = ptext (sLit "a record update")
pprO (AmbigOrigin ctxt) = ptext (sLit "the ambiguity check for")
<+> case ctxt of
FunSigCtxt name -> quotes (ppr name)
InfSigCtxt name -> quotes (ppr name)
_ -> pprUserTypeCtxt ctxt
pprO ExprSigOrigin = ptext (sLit "an expression type signature")
pprO PatSigOrigin = ptext (sLit "a pattern type signature")
pprO PatOrigin = ptext (sLit "a pattern")
pprO ViewPatOrigin = ptext (sLit "a view pattern")
pprO IfOrigin = ptext (sLit "an if statement")
pprO (LiteralOrigin lit) = hsep [ptext (sLit "the literal"), quotes (ppr lit)]
pprO (ArithSeqOrigin seq) = hsep [ptext (sLit "the arithmetic sequence"), quotes (ppr seq)]
pprO (PArrSeqOrigin seq) = hsep [ptext (sLit "the parallel array sequence"), quotes (ppr seq)]
pprO SectionOrigin = ptext (sLit "an operator section")
pprO TupleOrigin = ptext (sLit "a tuple")
pprO NegateOrigin = ptext (sLit "a use of syntactic negation")
pprO ScOrigin = ptext (sLit "the superclasses of an instance declaration")
pprO DerivOrigin = ptext (sLit "the 'deriving' clause of a data type declaration")
pprO StandAloneDerivOrigin = ptext (sLit "a 'deriving' declaration")
pprO DefaultOrigin = ptext (sLit "a 'default' declaration")
pprO DoOrigin = ptext (sLit "a do statement")
pprO MCompOrigin = ptext (sLit "a statement in a monad comprehension")
pprO ProcOrigin = ptext (sLit "a proc expression")
pprO (TypeEqOrigin t1 t2) = ptext (sLit "a type equality") <+> sep [ppr t1, char '~', ppr t2]
pprO (KindEqOrigin t1 t2 _) = ptext (sLit "a kind equality arising from") <+> sep [ppr t1, char '~', ppr t2]
pprO AnnOrigin = ptext (sLit "an annotation")
pprO FunDepOrigin = ptext (sLit "a functional dependency")
pprO HoleOrigin = ptext (sLit "a use of") <+> quotes (ptext $ sLit "_")
pprO (UnboundOccurrenceOf name) = hsep [ptext (sLit "an undeclared identifier"), quotes (ppr name)]
pprO ListOrigin = ptext (sLit "an overloaded list")
instance Outputable CtOrigin where
ppr = pprO
\end{code}