X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcRnTypes.lhs;h=eb1cd0427111f1af107c0e4c3a5f65231bed1566;hp=dc233089e98d3e1c15665aa1aa3de0976bfa765f;hb=3f1b316d7035c55cd712cd39a9981339bcef2e8c;hpb=f4510d27c5883fe7e8570f4dd49d45a8b0122f2c diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs index dc23308..eb1cd04 100644 --- a/compiler/typecheck/TcRnTypes.lhs +++ b/compiler/typecheck/TcRnTypes.lhs @@ -1,8 +1,15 @@ -% + % (c) The University of Glasgow 2006 % (c) The GRASP Project, Glasgow University, 1992-2002 % \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 TcRnTypes( TcRnIf, TcRn, TcM, RnM, IfM, IfL, IfG, -- The monad is opaque outside this module TcRef, @@ -13,12 +20,12 @@ module TcRnTypes( IfGblEnv(..), IfLclEnv(..), -- Ranamer types - ErrCtxt, + ErrCtxt, RecFieldEnv, ImportAvails(..), emptyImportAvails, plusImportAvails, WhereFrom(..), mkModDeps, -- Typechecker types - TcTyThing(..), pprTcTyThingCategory, + TcTyThing(..), pprTcTyThingCategory, RefinementVisibility(..), -- Template Haskell ThStage(..), topStage, topSpliceStage, @@ -30,11 +37,12 @@ module TcRnTypes( -- Insts Inst(..), InstOrigin(..), InstLoc(..), pprInstLoc, pprInstArising, instLocSpan, instLocOrigin, - LIE, emptyLIE, unitLIE, plusLIE, consLIE, + LIE, emptyLIE, unitLIE, plusLIE, consLIE, instLoc, instSpan, plusLIEs, mkLIE, isEmptyLIE, lieToList, listToLIE, -- Misc other types - TcId, TcIdSet, TcDictBinds + TcId, TcIdSet, TcDictBinds, + ) where #include "HsVersions.h" @@ -43,6 +51,7 @@ import HsSyn hiding (LIE) import HscTypes import Packages import Type +import Coercion import TcType import TcGadt import InstEnv @@ -65,6 +74,7 @@ import Util import Bag import Outputable import ListSetOps +import FiniteMap import Data.Maybe import Data.List @@ -115,8 +125,7 @@ data Env gbl lcl -- Changes as we move into an expression env_gbl :: gbl, -- Info about things defined at the top level -- of the module being compiled - env_lcl :: lcl -- Nested stuff; changes as we go into - -- an expression + env_lcl :: lcl -- Nested stuff; changes as we go into } -- TcGblEnv describes the top-level of the module at the @@ -133,7 +142,8 @@ data TcGblEnv tcg_default :: Maybe [Type], -- Types used for defaulting -- Nothing => no 'default' decl - tcg_fix_env :: FixityEnv, -- Just for things in this module + tcg_fix_env :: FixityEnv, -- Just for things in this module + tcg_field_env :: RecFieldEnv, -- 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, @@ -142,7 +152,7 @@ data TcGblEnv -- (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, + 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 @@ -225,8 +235,17 @@ data TcGblEnv tcg_fords :: [LForeignDecl Id], -- ...Foreign import & exports tcg_doc :: Maybe (HsDoc Name), -- Maybe Haddock documentation - tcg_hmi :: HaddockModInfo Name -- Haddock module information + tcg_hmi :: HaddockModInfo Name, -- Haddock module information + tcg_hpc :: AnyHpcUsage -- True if any part of the prog uses hpc instrumentation. } + +type RecFieldEnv = NameEnv [Name] -- Maps a constructor name *in this module* + -- to the fields for that constructor + -- This is used when dealing with ".." notation in record + -- construction and pattern matching. + -- The FieldEnv deals *only* with constructors defined in + -- *thie* module. For imported modules, we get the same info + -- from the TypeEnv \end{code} %************************************************************************ @@ -350,7 +369,7 @@ type ThLevel = Int -- Incremented when going inside a bracket, -- decremented when going inside a splice -- NB: ThLevel is one greater than the 'n' in Fig 2 of the - -- original "Template meta-programmign for Haskell" paper + -- original "Template meta-programming for Haskell" paper impLevel, topLevel :: ThLevel topLevel = 1 -- Things defined at top level of this module @@ -421,7 +440,8 @@ data TcTyThing | ATcId { -- Ids defined in this module; may not be fully zonked tct_id :: TcId, - tct_co :: Maybe HsWrapper, -- Nothing <=> Do not apply a GADT type refinement + tct_co :: RefinementVisibility, -- Previously: Maybe HsWrapper + -- Nothing <=> Do not apply a GADT type refinement -- I am wobbly, or have no free -- type variables -- Just co <=> Apply any type refinement to me, @@ -436,8 +456,21 @@ data TcTyThing | AThing TcKind -- Used temporarily, during kind checking, for the -- tycons and clases in this recursive group +data RefinementVisibility + = Unrefineable -- Do not apply a GADT refinement + -- I have no free variables + + | Rigid HsWrapper -- Apply any refinement to me + -- and record it in the coercion + + | Wobbly -- Do not apply a GADT refinement + -- I am wobbly + + | WobblyInvisible -- Wobbly type, not available inside current + -- GADT refinement + instance Outputable TcTyThing where -- Debugging only - ppr (AGlobal g) = ppr g + ppr (AGlobal g) = pprTyThing g ppr elt@(ATcId {}) = text "Identifier" <> ifPprDebug (brackets (ppr (tct_id elt) <> dcolon <> ppr (tct_type elt) <> comma <+> ppr (tct_level elt) <+> ppr (tct_co elt))) @@ -449,6 +482,13 @@ pprTcTyThingCategory (AGlobal thing) = pprTyThingCategory thing pprTcTyThingCategory (ATyVar {}) = ptext SLIT("Type variable") pprTcTyThingCategory (ATcId {}) = ptext SLIT("Local identifier") pprTcTyThingCategory (AThing {}) = ptext SLIT("Kinded thing") + +instance Outputable RefinementVisibility where + ppr Unrefineable = ptext SLIT("unrefineable") + ppr (Rigid co) = ptext SLIT("rigid") <+> ppr co + ppr Wobbly = ptext SLIT("wobbly") + ppr WobblyInvisible = ptext SLIT("wobbly-invisible") + \end{code} \begin{code} @@ -477,8 +517,11 @@ It is used * when processing the export list \begin{code} data ImportAvails = ImportAvails { - imp_mods :: ModuleEnv (Module, Bool, SrcSpan), + imp_mods :: ModuleEnv (Module, [(ModuleName, Bool, SrcSpan)]), -- Domain is all directly-imported modules + -- The ModuleName is what the module was imported as, e.g. in + -- import Foo as Bar + -- it is Bar. -- Bool means: -- True => import was "import Foo ()" -- False => import was some other form @@ -541,12 +584,13 @@ plusImportAvails (ImportAvails { imp_mods = mods2, imp_dep_mods = dmods2, imp_dep_pkgs = dpkgs2, imp_orphs = orphs2, imp_finsts = finsts2 }) - = ImportAvails { imp_mods = mods1 `plusModuleEnv` mods2, + = ImportAvails { imp_mods = plusModuleEnv_C plus_mod mods1 mods2, imp_dep_mods = plusUFM_C plus_mod_dep dmods1 dmods2, imp_dep_pkgs = dpkgs1 `unionLists` dpkgs2, imp_orphs = orphs1 `unionLists` orphs2, imp_finsts = finsts1 `unionLists` finsts2 } where + plus_mod (m1, xs1) (_, xs2) = (m1, xs1 ++ xs2) plus_mod_dep (m1, boot1) (m2, boot2) = WARN( not (m1 == m2), (ppr m1 <+> ppr m2) $$ (ppr boot1 <+> ppr boot2) ) -- Check mod-names match @@ -587,6 +631,21 @@ type Int, represented by Method 34 doubleId [Int] origin +In addition to the basic Haskell variants of 'Inst's, they can now also +represent implication constraints 'forall tvs. (reft, given) => wanted' +and equality constraints 'co :: ty1 ~ ty2'. + +NB: Equalities occur in two flavours: + + (1) Dict {tci_pred = EqPred ty1 ty2} + (2) EqInst {tci_left = ty1, tci_right = ty2, tci_co = coe} + +The former arises from equalities in contexts, whereas the latter is used +whenever the type checker introduces an equality (e.g., during deferring +unification). + +I am not convinced that this duplication is necessary or useful! -=chak + \begin{code} data Inst = Dict { @@ -598,14 +657,20 @@ data Inst | ImplicInst { -- An implication constraint -- forall tvs. (reft, given) => wanted tci_name :: Name, + tci_tyvars :: [TcTyVar], -- Quantified type variables + -- Includes coercion variables + -- mentioned in tci_reft tci_reft :: Refinement, - tci_tyvars :: [TcTyVar], - tci_given :: [Inst], -- Only Dicts + tci_given :: [Inst], -- Only Dicts and EqInsts -- (no Methods, LitInsts, ImplicInsts) tci_wanted :: [Inst], -- Only Dicts and ImplicInsts -- (no Methods or LitInsts) + tci_loc :: InstLoc } + -- NB: the tci_given are not necessarily rigid, + -- although they will be if the tci_reft is non-trivial + -- NB: the tci_reft is already applied to tci_given and tci_wanted | Method { tci_id :: TcId, -- The Id for the Inst @@ -647,6 +712,32 @@ data Inst tci_ty :: TcType, -- The type at which the literal is used tci_loc :: InstLoc } + + | EqInst { -- delayed unification of the form + -- co :: ty1 ~ ty2 + tci_left :: TcType, -- ty1 -- both types are... + tci_right :: TcType, -- ty2 -- ...free of boxes + tci_co :: Either -- co + TcTyVar -- - a wanted equation, with a hole, to be + -- filled with a witness for the equality; + -- for equation arising from deferring + -- unification, 'ty1' is the actual and + -- 'ty2' the expected type + Coercion, -- - a given equation, with a coercion + -- witnessing the equality; + -- a coercion that originates from a + -- signature or a GADT is a CoVar, but + -- after normalisation of coercions, they + -- can be arbitrary Coercions involving + -- constructors and pseudo-constructors + -- like sym and trans. + tci_loc :: InstLoc, + + tci_name :: Name -- Debugging help only: this makes it easier to + -- follow where a constraint is used in a morass + -- of trace messages! Unlike other Insts, it has + -- no semantic significance whatsoever. + } \end{code} @Insts@ are ordered by their class/type info, rather than by their @@ -683,6 +774,14 @@ cmpInst (ImplicInst {}) (Dict {}) = GT cmpInst (ImplicInst {}) (Method {}) = GT cmpInst (ImplicInst {}) (LitInst {}) = GT cmpInst i1@(ImplicInst {}) i2@(ImplicInst {}) = tci_name i1 `compare` tci_name i2 +cmpInst (ImplicInst {}) other = LT + + -- same for Equality constraints +cmpInst (EqInst {}) (Dict {}) = GT +cmpInst (EqInst {}) (Method {}) = GT +cmpInst (EqInst {}) (LitInst {}) = GT +cmpInst (EqInst {}) (ImplicInst {}) = GT +cmpInst i1@(EqInst {}) i2@(EqInst {}) = tci_name i1 `compare` tci_name i2 \end{code} @@ -701,10 +800,20 @@ emptyLIE = emptyBag unitLIE inst = unitBag inst mkLIE insts = listToBag insts plusLIE lie1 lie2 = lie1 `unionBags` lie2 -consLIE inst lie = inst `consBag` lie plusLIEs lies = unionManyBags lies lieToList = bagToList listToLIE = listToBag + +consLIE inst lie = lie `snocBag` inst +-- Putting the new Inst at the *end* of the bag is a half-hearted attempt +-- to ensure that we tend to report the *leftmost* type-constraint error +-- E.g. f :: [a] +-- f = [1,2,3] +-- we'd like to complain about the '1', not the '3'. +-- +-- "Half-hearted" because the rest of the type checker makes no great +-- claims for retaining order in the constraint set. Still, this +-- seems to improve matters slightly. Exampes: mdofail001, tcfail015 \end{code} @@ -725,6 +834,12 @@ functions that deal with it. ------------------------------------------- data InstLoc = InstLoc InstOrigin SrcSpan ErrCtxt +instLoc :: Inst -> InstLoc +instLoc inst = tci_loc inst + +instSpan :: Inst -> SrcSpan +instSpan wanted = instLocSpan (instLoc wanted) + instLocSpan :: InstLoc -> SrcSpan instLocSpan (InstLoc _ s _) = s @@ -768,6 +883,7 @@ data InstOrigin | DoOrigin -- Arising from a do expression | ProcOrigin -- Arising from a proc expression | ImplicOrigin SDoc -- An implication constraint + | EqOrigin -- A type equality instance Outputable InstOrigin where ppr (OccurrenceOf name) = hsep [ptext SLIT("a use of"), quotes (ppr name)] @@ -786,4 +902,6 @@ instance Outputable InstOrigin where ppr ProcOrigin = ptext SLIT("a proc expression") ppr (ImplicOrigin doc) = doc ppr (SigOrigin info) = pprSkolInfo info + ppr EqOrigin = ptext SLIT("a type equality") + \end{code}