Fixed uninitialised FunBind fun_tick field
[ghc-hetmet.git] / compiler / types / InstEnv.lhs
index d4a7b77..b8e10d5 100644 (file)
@@ -1,4 +1,5 @@
 %
+% (c) The University of Glasgow 2006
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
 \section[InstEnv]{Utilities for typechecking instance declarations}
@@ -20,25 +21,24 @@ module InstEnv (
 
 #include "HsVersions.h"
 
-import Class           ( Class )
-import Var             ( Id, TyVar, isTcTyVar )
+import Class
+import Var
 import VarSet
-import Name            ( Name, NamedThing(..), getSrcLoc, nameIsLocalOrFrom, nameModule )
-import OccName         ( OccName )
-import NameSet         ( unionNameSets, unitNameSet, nameSetToList )
-import Type            ( TvSubst )
-import TcType          ( Type, PredType, tcEqType,
-                         tcSplitDFunTy, tyVarsOfTypes, isExistentialTyVar,
-                         pprThetaArrow, pprClassPred,
-                         tyClsNamesOfType, tcSplitTyConApp_maybe
-                       )
-import TyCon           ( tyConName )
-import Unify           ( tcMatchTys, tcUnifyTys, BindFlag(..) )
+import Name
+import OccName
+import NameSet
+import Type
+import TcType
+import TyCon
+import TcGadt
+import Unify
 import Outputable
-import UniqFM          ( UniqFM, lookupUFM, emptyUFM, addToUFM_C, eltsUFM )
-import Id              ( idType, idName )
-import SrcLoc          ( pprDefnLoc )
-import Maybe           ( isJust, isNothing )
+import BasicTypes
+import UniqFM
+import Id
+import SrcLoc
+
+import Data.Maybe      ( isJust, isNothing )
 \end{code}
 
 
@@ -61,68 +61,74 @@ data Instance
             , is_tys  :: [Type]        -- Full arg types
 
             , is_dfun :: DFunId
-            , is_flag :: OverlapFlag
+            , is_flag :: OverlapFlag   -- See detailed comments with
+                                       -- the decl of BasicTypes.OverlapFlag
 
             , is_orph :: Maybe OccName }
+\end{code}
 
--- The "rough-match" fields
--- ~~~~~~~~~~~~~~~~~~~~~~~~~
--- The is_cls, is_args fields allow a "rough match" to be done
--- without poking inside the DFunId.  Poking the DFunId forces
--- us to suck in all the type constructors etc it involves,
--- which is a total waste of time if it has no chance of matching
--- So the Name, [Maybe Name] fields allow us to say "definitely
--- does not match", based only on the Name.
---
--- In is_tcs, 
---     Nothing  means that this type arg is a type variable
---
---     (Just n) means that this type arg is a
---             TyConApp with a type constructor of n.
---             This is always a real tycon, never a synonym!
---             (Two different synonyms might match, but two
---             different real tycons can't.)
---             NB: newtypes are not transparent, though!
---
--- The "proper-match" fields
--- ~~~~~~~~~~~~~~~~~~~~~~~~~
--- The is_tvs, is_tys fields are simply cahced values, pulled
--- out (lazily) from the dfun id. They are cached here simply so 
--- that we don't need to decompose the DFunId each time we want 
--- to match it.  The hope is that the fast-match fields mean
--- that we often never poke th proper-match fields
---
--- However, note that:
---  * is_tvs must be a superset of the free vars of is_tys
---
---  * The is_dfun must itself be quantified over exactly is_tvs
---    (This is so that we can use the matching substitution to
---     instantiate the dfun's context.)
---
--- The "orphan" field
--- ~~~~~~~~~~~~~~~~~~
--- An instance is an orphan if its head (after the =>) mentions
--- nothing defined in this module.  
---
---    Just n   The head mentions n, which is defined in this module
---             This is used for versioning; the instance decl is
---             considered part of the defn of n when computing versions
---
---    Nothing  The head mentions nothing defined in this modle
---
--- If a module contains any orphans, then its interface file is read 
--- regardless, so that its instances are not missed. 
--- 
--- Functional dependencies worsen the situation a bit. Consider
---     class C a b | a -> b
--- In some other module we might have
---    module M where
---     data T = ...
---     instance C Int T where ...
--- This isn't considered an orphan, so we will only read M's interface
--- if something from M is used (e.g. T).  So there's a risk we'll
--- miss the improvement from the instance.  Workaround: import M.
+The "rough-match" fields
+~~~~~~~~~~~~~~~~~~~~~~~~~
+The is_cls, is_args fields allow a "rough match" to be done
+without poking inside the DFunId.  Poking the DFunId forces
+us to suck in all the type constructors etc it involves,
+which is a total waste of time if it has no chance of matching
+So the Name, [Maybe Name] fields allow us to say "definitely
+does not match", based only on the Name.
+
+In is_tcs, 
+    Nothing  means that this type arg is a type variable
+
+    (Just n) means that this type arg is a
+               TyConApp with a type constructor of n.
+               This is always a real tycon, never a synonym!
+               (Two different synonyms might match, but two
+               different real tycons can't.)
+               NB: newtypes are not transparent, though!
+
+The "proper-match" fields
+~~~~~~~~~~~~~~~~~~~~~~~~~
+The is_tvs, is_tys fields are simply cahced values, pulled
+out (lazily) from the dfun id. They are cached here simply so 
+that we don't need to decompose the DFunId each time we want 
+to match it.  The hope is that the fast-match fields mean
+that we often never poke th proper-match fields
+
+However, note that:
+ * is_tvs must be a superset of the free vars of is_tys
+
+ * The is_dfun must itself be quantified over exactly is_tvs
+   (This is so that we can use the matching substitution to
+    instantiate the dfun's context.)
+
+
+Note [Orphans]: the "is_orph" field
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+An instance is an orphan if its head (after the =>) mentions
+nothing defined in this module.  
+
+   Just n      The head mentions n, which is defined in this module
+               This is used for versioning; the instance decl is
+               considered part of the defn of n when computing versions
+
+   Nothing     The head mentions nothing defined in this module
+
+If a module contains any orphans, then its interface file is read 
+regardless, so that its instances are not missed. 
+
+Functional dependencies worsen the situation a bit. Consider
+       class C a b | a -> b
+In some other module we might have
+   module M where
+       data T = ...
+       instance C Int T where ...
+This isn't considered an orphan, so we will only read M's interface
+if something from M is used (e.g. T).  So there's a risk we'll
+miss the improvement from the instance.  Workaround: import M.
+
+Rules are orphans and versioned in much the same way.
 
+\begin{code}
 instanceDFunId :: Instance -> DFunId
 instanceDFunId = is_dfun
 
@@ -213,38 +219,6 @@ instanceCantMatch :: [Maybe Name] -> [Maybe Name] -> Bool
 -- False is non-committal
 instanceCantMatch (Just t : ts) (Just a : as) = t/=a || instanceCantMatch ts as
 instanceCantMatch ts           as            =  False  -- Safe
-
----------------------------------------------------
-data OverlapFlag
-  = NoOverlap  -- This instance must not overlap another
-
-  | OverlapOk  -- Silently ignore this instance if you find a 
-               -- more specific one that matches the constraint
-               -- you are trying to resolve
-               --
-               -- Example: constraint (Foo [Int])
-               --          instances  (Foo [Int])
-               --                     (Foo [a])        OverlapOk
-               -- Since the second instance has the OverlapOk flag,
-               -- the first instance will be chosen (otherwise 
-               -- its ambiguous which to choose)
-
-  | Incoherent -- Like OverlapOk, but also ignore this instance 
-               -- if it doesn't match the constraint you are
-               -- trying to resolve, but could match if the type variables
-               -- in the constraint were instantiated
-               --
-               -- Example: constraint (Foo [b])
-               --          instances  (Foo [Int])      Incoherent
-               --                     (Foo [a])
-               -- Without the Incoherent flag, we'd complain that
-               -- instantiating 'b' would change which instance 
-               -- was chosen
-
-instance Outputable OverlapFlag where
-   ppr NoOverlap  = empty
-   ppr OverlapOk  = ptext SLIT("[overlap ok]")
-   ppr Incoherent = ptext SLIT("[incoherent]")
 \end{code}
 
 
@@ -504,9 +478,9 @@ lookupInstEnv (pkg_ie, home_ie) cls tys
       = find ms us rest
 
       | otherwise
-      = ASSERT2( not (tyVarsOfTypes tys `intersectsVarSet` tpl_tvs),
-                      (ppr cls <+> ppr tys <+> ppr all_tvs) $$
-                      (ppr dfun <+> ppr tpl_tvs <+> ppr tpl_tys)
+      = ASSERT2( tyVarsOfTypes tys `disjointVarSet` tpl_tvs,
+                (ppr cls <+> ppr tys <+> ppr all_tvs) $$
+                (ppr dfun <+> ppr tpl_tvs <+> ppr tpl_tys)
                )
                -- Unification will break badly if the variables overlap
                -- They shouldn't because we allocate separate uniques for them