X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcRnTypes.lhs;h=86f1dfcc797f43960bcabf50958dfe5a6bfed740;hp=80e5b0f060e8d0c802da2a2aed1d762a6bbc9c02;hb=ebec49fed627b7dd17e297ddc79a9c677a2ce538;hpb=ad94d40948668032189ad22a0ad741ac1f645f50 diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs index 80e5b0f..86f1dfc 100644 --- a/compiler/typecheck/TcRnTypes.lhs +++ b/compiler/typecheck/TcRnTypes.lhs @@ -1,15 +1,8 @@ -% + % (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/CodingStyle#Warnings --- for details - module TcRnTypes( TcRnIf, TcRn, TcM, RnM, IfM, IfL, IfG, -- The monad is opaque outside this module TcRef, @@ -35,7 +28,7 @@ module TcRnTypes( ArrowCtxt(NoArrowCtxt), newArrowScope, escapeArrowScope, -- Insts - Inst(..), InstOrigin(..), InstLoc(..), + Inst(..), EqInstCo, InstOrigin(..), InstLoc(..), pprInstLoc, pprInstArising, instLocSpan, instLocOrigin, LIE, emptyLIE, unitLIE, plusLIE, consLIE, instLoc, instSpan, plusLIEs, mkLIE, isEmptyLIE, lieToList, listToLIE, @@ -49,11 +42,9 @@ module TcRnTypes( import HsSyn hiding (LIE) import HscTypes -import Packages import Type import Coercion import TcType -import TcGadt import InstEnv import FamInstEnv import IOEnv @@ -64,7 +55,7 @@ import NameSet import Var import VarEnv import Module -import UniqFM +import LazyUniqFM import SrcLoc import VarSet import ErrUtils @@ -74,7 +65,7 @@ import Util import Bag import Outputable import ListSetOps -import FiniteMap +import FastString import Data.Maybe import Data.List @@ -152,7 +143,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 @@ -217,18 +208,13 @@ data TcGblEnv -- The binds, rules and foreign-decl fiels are collected -- initially in un-zonked form and are finally zonked in tcRnSrcDecls - -- 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_rn_imports :: Maybe [LImportDecl Name], tcg_rn_exports :: Maybe [Located (IE Name)], tcg_rn_decls :: Maybe (HsGroup Name), -- renamed decls, maybe -- Nothing <=> Don't retain renamed decls tcg_binds :: LHsBinds Id, -- Value bindings in this module - tcg_deprecs :: Deprecations, -- ...Deprecations + tcg_warns :: Warnings, -- ...Warnings and deprecations tcg_insts :: [Instance], -- ...Instances tcg_fam_insts :: [FamInst], -- ...Family instances tcg_rules :: [LRuleDecl Id], -- ...Rules @@ -243,9 +229,9 @@ 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 + -- The FieldEnv deals *only* with constructors defined in *thie* + -- module. For imported modules, we get the same info from the + -- TypeEnv \end{code} %************************************************************************ @@ -318,8 +304,8 @@ data TcLclEnv -- Changes as we move inside an expression 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_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 @@ -369,7 +355,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 @@ -470,7 +456,7 @@ data RefinementVisibility -- 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))) @@ -479,15 +465,15 @@ instance Outputable TcTyThing where -- Debugging only 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 (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") + 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} @@ -517,7 +503,7 @@ It is used * when processing the export list \begin{code} data ImportAvails = ImportAvails { - imp_mods :: ModuleEnv (Module, [(ModuleName, Bool, SrcSpan)]), + imp_mods :: ModuleEnv [(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 @@ -526,8 +512,6 @@ data ImportAvails -- True => import was "import Foo ()" -- False => import was some other form -- - -- We need the Module in the range because we can't get - -- the keys of a ModuleEnv -- Used -- (a) to help construct the usage information in -- the interface file; if we import somethign we @@ -584,13 +568,12 @@ plusImportAvails (ImportAvails { imp_mods = mods2, imp_dep_mods = dmods2, imp_dep_pkgs = dpkgs2, imp_orphs = orphs2, imp_finsts = finsts2 }) - = ImportAvails { imp_mods = plusModuleEnv_C plus_mod mods1 mods2, + = ImportAvails { imp_mods = plusModuleEnv_C (++) 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 @@ -611,9 +594,9 @@ data WhereFrom | ImportBySystem -- Non user import. instance Outputable WhereFrom where - ppr (ImportByUser is_boot) | is_boot = ptext SLIT("{- SOURCE -}") + ppr (ImportByUser is_boot) | is_boot = ptext (sLit "{- SOURCE -}") | otherwise = empty - ppr ImportBySystem = ptext SLIT("{- SYSTEM -}") + ppr ImportBySystem = ptext (sLit "{- SYSTEM -}") \end{code} @@ -632,9 +615,20 @@ 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' +represent implication constraints 'forall tvs. 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 { @@ -644,22 +638,17 @@ data Inst } | ImplicInst { -- An implication constraint - -- forall tvs. (reft, given) => wanted + -- forall tvs. given => wanted tci_name :: Name, tci_tyvars :: [TcTyVar], -- Quantified type variables - -- Includes coercion variables - -- mentioned in tci_reft - tci_reft :: Refinement, - tci_given :: [Inst], -- Only Dicts + tci_given :: [Inst], -- Only Dicts and EqInsts -- (no Methods, LitInsts, ImplicInsts) - tci_wanted :: [Inst], -- Only Dicts and ImplicInsts + tci_wanted :: [Inst], -- Only Dicts, EqInst, 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 + -- NB: the tci_given are not necessarily rigid | Method { tci_id :: TcId, -- The Id for the Inst @@ -704,30 +693,28 @@ data Inst | EqInst { -- delayed unification of the form -- co :: ty1 ~ ty2 - tci_left :: TcType, -- ty1 - tci_right :: TcType, -- ty2 - tci_co :: Either -- co - TcTyVar -- a wanted equation, with a hole, to be - -- filled with a witness for the equality - -- for equation generated by the - -- unifier, '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_left :: TcType, -- ty1 -- both types are... + tci_right :: TcType, -- ty2 -- ...free of boxes + tci_co :: EqInstCo, -- co 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. + -- of trace messages! Unlike other Insts, it + -- has no semantic significance whatsoever. } + +type EqInstCo = Either -- Distinguish between given and wanted coercions + 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. \end{code} @Insts@ are ordered by their class/type info, rather than by their @@ -737,26 +724,28 @@ than with the Avails handling stuff in TcSimplify \begin{code} instance Ord Inst where - compare = cmpInst + compare = cmpInst + -- Used *only* for AvailEnv in TcSimplify instance Eq Inst where (==) i1 i2 = case i1 `cmpInst` i2 of - EQ -> True - other -> False + EQ -> True + _ -> False +cmpInst :: Inst -> Inst -> Ordering cmpInst d1@(Dict {}) d2@(Dict {}) = tci_pred d1 `tcCmpPred` tci_pred d2 -cmpInst (Dict {}) other = LT +cmpInst (Dict {}) _ = LT cmpInst (Method {}) (Dict {}) = GT cmpInst m1@(Method {}) m2@(Method {}) = (tci_oid m1 `compare` tci_oid m2) `thenCmp` (tci_tys m1 `tcCmpTypes` tci_tys m2) -cmpInst (Method {}) other = LT +cmpInst (Method {}) _ = LT cmpInst (LitInst {}) (Dict {}) = GT cmpInst (LitInst {}) (Method {}) = GT cmpInst l1@(LitInst {}) l2@(LitInst {}) = (tci_lit l1 `compare` tci_lit l2) `thenCmp` (tci_ty l1 `tcCmpType` tci_ty l2) -cmpInst (LitInst {}) other = LT +cmpInst (LitInst {}) _ = LT -- Implication constraints are compared by *name* -- not by type; that is, we make no attempt to do CSE on them @@ -764,14 +753,15 @@ 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 +cmpInst (ImplicInst {}) _ = 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 +cmpInst (EqInst {}) (Dict {}) = GT +cmpInst (EqInst {}) (Method {}) = GT +cmpInst (EqInst {}) (LitInst {}) = GT +cmpInst (EqInst {}) (ImplicInst {}) = GT +cmpInst i1@(EqInst {}) i2@(EqInst {}) = (tci_left i1 `tcCmpType` tci_left i2) `thenCmp` + (tci_right i1 `tcCmpType` tci_right i2) \end{code} @@ -785,15 +775,31 @@ cmpInst i1@(EqInst {}) i2@(EqInst {}) = tci_name i1 `compare` tci_name i -- FIXME: Rename this. It clashes with (Located (IE ...)) type LIE = Bag Inst -isEmptyLIE = isEmptyBag -emptyLIE = emptyBag -unitLIE inst = unitBag inst -mkLIE insts = listToBag insts +isEmptyLIE :: LIE -> Bool +isEmptyLIE = isEmptyBag + +emptyLIE :: LIE +emptyLIE = emptyBag + +unitLIE :: Inst -> LIE +unitLIE inst = unitBag inst + +mkLIE :: [Inst] -> LIE +mkLIE insts = listToBag insts + +plusLIE :: LIE -> LIE -> LIE plusLIE lie1 lie2 = lie1 `unionBags` lie2 -plusLIEs lies = unionManyBags lies -lieToList = bagToList -listToLIE = listToBag +plusLIEs :: [LIE] -> LIE +plusLIEs lies = unionManyBags lies + +lieToList :: LIE -> [Inst] +lieToList = bagToList + +listToLIE :: [Inst] -> LIE +listToLIE = listToBag + +consLIE :: Inst -> LIE -> LIE 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 @@ -837,7 +843,7 @@ instLocOrigin :: InstLoc -> InstOrigin instLocOrigin (InstLoc o _ _) = o pprInstArising :: Inst -> SDoc -pprInstArising loc = ptext SLIT("arising from") <+> pprInstLoc (tci_loc loc) +pprInstArising loc = ptext (sLit "arising from") <+> pprInstLoc (tci_loc loc) pprInstLoc :: InstLoc -> SDoc pprInstLoc (InstLoc orig span _) = sep [ppr orig, text "at" <+> ppr span] @@ -854,18 +860,23 @@ data InstOrigin -- The rest are all occurrences: Insts that are 'wanted' ------------------------------------------------------- | OccurrenceOf Name -- Occurrence of an overloaded identifier + | SpecPragOrigin Name -- Specialisation pragma for identifier | IPOccOrigin (IPName Name) -- Occurrence of an implicit parameter | LiteralOrigin (HsOverLit Name) -- Occurrence of a literal + | NegateOrigin -- Occurrence of syntactic negation | ArithSeqOrigin (ArithSeqInfo Name) -- [x..], [x..y] etc | PArrSeqOrigin (ArithSeqInfo Name) -- [:x..y:] and [:x,y..z:] + | TupleOrigin -- (..,..) | InstSigOrigin -- A dict occurrence arising from instantiating -- a polymorphic type during a subsumption check + | ExprSigOrigin -- e :: ty | RecordUpdOrigin + | ViewPatOrigin | InstScOrigin -- Typechecking superclasses of an instance declaration | DerivOrigin -- Typechecking deriving | StandAloneDerivOrigin -- Typechecking stand-alone deriving @@ -876,22 +887,26 @@ data InstOrigin | EqOrigin -- A type equality instance Outputable InstOrigin where - ppr (OccurrenceOf name) = hsep [ptext SLIT("a use of"), quotes (ppr name)] - ppr (IPOccOrigin name) = hsep [ptext SLIT("a use of implicit parameter"), quotes (ppr name)] - ppr (IPBindOrigin name) = hsep [ptext SLIT("a binding for implicit parameter"), quotes (ppr name)] - ppr RecordUpdOrigin = ptext SLIT("a record update") - ppr (LiteralOrigin lit) = hsep [ptext SLIT("the literal"), quotes (ppr lit)] - ppr (ArithSeqOrigin seq) = hsep [ptext SLIT("the arithmetic sequence"), quotes (ppr seq)] - ppr (PArrSeqOrigin seq) = hsep [ptext SLIT("the parallel array sequence"), quotes (ppr seq)] - ppr InstSigOrigin = ptext SLIT("instantiating a type signature") - ppr InstScOrigin = ptext SLIT("the superclasses of an instance declaration") - ppr DerivOrigin = ptext SLIT("the 'deriving' clause of a data type declaration") - ppr StandAloneDerivOrigin = ptext SLIT("a 'deriving' declaration") - ppr DefaultOrigin = ptext SLIT("a 'default' declaration") - ppr DoOrigin = ptext SLIT("a do statement") - ppr ProcOrigin = ptext SLIT("a proc expression") + ppr (OccurrenceOf name) = hsep [ptext (sLit "a use of"), quotes (ppr name)] + ppr (SpecPragOrigin name) = hsep [ptext (sLit "a specialisation pragma for"), quotes (ppr name)] + ppr (IPOccOrigin name) = hsep [ptext (sLit "a use of implicit parameter"), quotes (ppr name)] + ppr (IPBindOrigin name) = hsep [ptext (sLit "a binding for implicit parameter"), quotes (ppr name)] + ppr RecordUpdOrigin = ptext (sLit "a record update") + ppr ExprSigOrigin = ptext (sLit "an expression type signature") + ppr ViewPatOrigin = ptext (sLit "a view pattern") + ppr (LiteralOrigin lit) = hsep [ptext (sLit "the literal"), quotes (ppr lit)] + ppr (ArithSeqOrigin seq) = hsep [ptext (sLit "the arithmetic sequence"), quotes (ppr seq)] + ppr (PArrSeqOrigin seq) = hsep [ptext (sLit "the parallel array sequence"), quotes (ppr seq)] + ppr TupleOrigin = ptext (sLit "a tuple") + ppr NegateOrigin = ptext (sLit "a use of syntactic negation") + ppr InstScOrigin = ptext (sLit "the superclasses of an instance declaration") + ppr DerivOrigin = ptext (sLit "the 'deriving' clause of a data type declaration") + ppr StandAloneDerivOrigin = ptext (sLit "a 'deriving' declaration") + ppr DefaultOrigin = ptext (sLit "a 'default' declaration") + ppr DoOrigin = ptext (sLit "a do statement") + ppr ProcOrigin = ptext (sLit "a proc expression") ppr (ImplicOrigin doc) = doc ppr (SigOrigin info) = pprSkolInfo info - ppr EqOrigin = ptext SLIT("a type equality") - + ppr EqOrigin = ptext (sLit "a type equality") + ppr InstSigOrigin = panic "ppr InstSigOrigin" \end{code}