Complete work on new OVERLAPPABLE/OVERLAPPING pragmas (Trac #9242)
authorSimon Peyton Jones <simonpj@microsoft.com>
Thu, 31 Jul 2014 14:49:14 +0000 (15:49 +0100)
committerSimon Peyton Jones <simonpj@microsoft.com>
Thu, 31 Jul 2014 14:49:45 +0000 (15:49 +0100)
* Deprecate -XOverlappingInstances

* Update test suite.  Several tests even had entirely unnecessary
  uses of -XOverlappingInstances

* Update user manual with a careful description of the instance
  resolution story

* Fix an outright bug in the handling of duplidate instances in GHCi,
  which are meant to silently overwrite the earlier duplicate. The
  logic was right for family instances but was both more complicated,
  and plain wrong, for class instances.  (If you are interested, the
  bug was that we were eliminating the duplicate from the InstEnv, but
  not from the [ClsInst] held in tcg_insts.)  Test is ghci044a.

60 files changed:
compiler/basicTypes/BasicTypes.lhs
compiler/main/DynFlags.hs
compiler/main/HscTypes.lhs
compiler/typecheck/Inst.lhs
compiler/typecheck/TcRnTypes.lhs
compiler/types/FamInstEnv.lhs
compiler/types/InstEnv.lhs
docs/users_guide/glasgow_exts.xml
testsuite/tests/deriving/should_compile/T4966.hs
testsuite/tests/deriving/should_compile/T4966.stderr
testsuite/tests/generics/Uniplate/GUniplate.hs
testsuite/tests/ghci.debugger/scripts/print019.stderr
testsuite/tests/ghci/prog007/C.hs
testsuite/tests/ghci/scripts/all.T
testsuite/tests/ghci/scripts/ghci044.script
testsuite/tests/ghci/scripts/ghci044.stderr
testsuite/tests/ghci/scripts/ghci044a.hs [new file with mode: 0644]
testsuite/tests/ghci/scripts/ghci044a.script [new file with mode: 0644]
testsuite/tests/ghci/scripts/ghci044a.stdout [new file with mode: 0644]
testsuite/tests/ghci/scripts/ghci047.script
testsuite/tests/indexed-types/should_compile/Gentle.hs
testsuite/tests/indexed-types/should_compile/IndTypesPerfMerge.hs
testsuite/tests/indexed-types/should_compile/NonLinearLHS.hs
testsuite/tests/indexed-types/should_fail/T4246.hs
testsuite/tests/indexed-types/should_fail/T4485.hs
testsuite/tests/indexed-types/should_fail/T4485.stderr
testsuite/tests/indexed-types/should_fail/T5439.hs
testsuite/tests/indexed-types/should_fail/T5439.stderr
testsuite/tests/perf/compiler/T5321FD.hs
testsuite/tests/perf/compiler/T5321Fun.hs
testsuite/tests/roles/should_compile/T8958.stderr
testsuite/tests/safeHaskell/ghci/p13.script
testsuite/tests/safeHaskell/ghci/p13.stderr
testsuite/tests/safeHaskell/safeInfered/UnsafeInfered08_A.hs
testsuite/tests/safeHaskell/safeLanguage/SafeLang10.stderr
testsuite/tests/safeHaskell/safeLanguage/SafeLang10_B.hs
testsuite/tests/simplCore/should_compile/T5359b.hs
testsuite/tests/simplCore/should_compile/T5359b.stderr
testsuite/tests/simplCore/should_compile/simpl007.hs
testsuite/tests/th/T4135a.hs
testsuite/tests/typecheck/should_compile/FD4.hs
testsuite/tests/typecheck/should_compile/LoopOfTheDay3.hs
testsuite/tests/typecheck/should_compile/Makefile
testsuite/tests/typecheck/should_compile/T1470.hs
testsuite/tests/typecheck/should_compile/T3018.hs
testsuite/tests/typecheck/should_compile/T3108.hs
testsuite/tests/typecheck/should_compile/Tc173a.hs
testsuite/tests/typecheck/should_compile/Tc173b.hs
testsuite/tests/typecheck/should_compile/tc176.hs
testsuite/tests/typecheck/should_compile/tc179.hs
testsuite/tests/typecheck/should_fail/LongWayOverlapping.hs
testsuite/tests/typecheck/should_fail/LongWayOverlapping.stderr
testsuite/tests/typecheck/should_fail/T2307.hs
testsuite/tests/typecheck/should_fail/T5051.hs
testsuite/tests/typecheck/should_fail/T5051.stderr
testsuite/tests/typecheck/should_fail/T5095.hs
testsuite/tests/typecheck/should_fail/T5095.stderr
testsuite/tests/typecheck/should_fail/tcfail121.hs
testsuite/tests/typecheck/should_fail/tcfail121.stderr
testsuite/tests/typecheck/should_fail/tcfail202.hs

index 0ae4737..c6fb26c 100644 (file)
@@ -462,6 +462,7 @@ hasOverlappableFlag mode =
   case mode of
     Overlappable -> True
     Overlaps     -> True
+    Incoherent   -> True
     _            -> False
 
 hasOverlappingFlag :: OverlapMode -> Bool
@@ -469,57 +470,58 @@ hasOverlappingFlag mode =
   case mode of
     Overlapping  -> True
     Overlaps     -> True
+    Incoherent   -> True
     _            -> False
 
-data OverlapMode
-
-  {- | This instance must not overlap another `NoOverlap` instance.
-  However, it may be overlapped by `Overlapping` instances,
-  and it may overlap `Overlappable` instances. -}
+data OverlapMode  -- See Note [Rules for instance lookup] in InstEnv
   = NoOverlap
+    -- ^ This instance must not overlap another `NoOverlap` instance.
+    -- However, it may be overlapped by `Overlapping` instances,
+    -- and it may overlap `Overlappable` instances.
 
 
-  {- | Silently ignore this instance if you find a
-  more specific one that matches the constraint
-  you are trying to resolve
-
-  Example: constraint (Foo [Int])
-    instance                      Foo [Int]
-    instance {-# OVERLAPPABLE #-} Foo [a]
-
-  Since the second instance has the Overlappable flag,
-  the first instance will be chosen (otherwise
-  its ambiguous which to choose) -}
   | Overlappable
+    -- ^ Silently ignore this instance if you find a
+    -- more specific one that matches the constraint
+    -- you are trying to resolve
+    --
+    -- Example: constraint (Foo [Int])
+    --   instance                      Foo [Int]
+    --   instance {-# OVERLAPPABLE #-} Foo [a]
+    --
+    -- Since the second instance has the Overlappable flag,
+    -- the first instance will be chosen (otherwise
+    -- its ambiguous which to choose)
 
 
-  {- | Silently ignore any more general instances that may be
-       used to solve the constraint.
-
-  Example: constraint (Foo [Int])
-    instance {-# OVERLAPPING #-} Foo [Int]
-    instance                     Foo [a]
-
-  Since the first instance has the Overlapping flag,
-  the second---more general---instance will be ignored (otherwise
-  its ambiguous which to choose) -}
   | Overlapping
+    -- ^ Silently ignore any more general instances that may be
+    --   used to solve the constraint.
+    --
+    -- Example: constraint (Foo [Int])
+    --   instance {-# OVERLAPPING #-} Foo [Int]
+    --   instance                     Foo [a]
+    --
+    -- Since the first instance has the Overlapping flag,
+    -- the second---more general---instance will be ignored (otherwise
+    -- it is ambiguous which to choose)
 
 
-  -- | Equiavalent to having both `Overlapping` and `Overlappable` flags.
   | Overlaps
+    -- ^ Equiavalent to having both `Overlapping` and `Overlappable` flags.
 
-  -- | Silently ignore this instance if you find any other that matches the
-  -- constraing you are trying to resolve, including when checking if there are
-  -- instances that do not match, but unify.
-  --
-  -- Example: constraint (Foo [b])
-  -- instance {-# INCOHERENT -} Foo [Int]
-  -- instance                   Foo [a]
-  -- Without the Incoherent flag, we'd complain that
-  -- instantiating 'b' would change which instance
-  -- was chosen. See also note [Incoherent instances]
   | Incoherent
+    -- ^ Behave like Overlappable and Overlapping, and in addition pick
+    -- an an arbitrary one if there are multiple matching candidates, and
+    -- don't worry about later instantiation
+    --
+    -- Example: constraint (Foo [b])
+    -- instance {-# INCOHERENT -} Foo [Int]
+    -- instance                   Foo [a]
+    -- Without the Incoherent flag, we'd complain that
+    -- instantiating 'b' would change which instance
+    -- was chosen. See also note [Incoherent instances] in InstEnv
+
   deriving (Eq, Data, Typeable)
 
 
index 1bb9f2c..9c45f41 100644 (file)
@@ -2871,7 +2871,9 @@ xFlags = [
     deprecatedForExtension "MultiParamTypeClasses" ),
   ( "FunctionalDependencies",           Opt_FunctionalDependencies, nop ),
   ( "GeneralizedNewtypeDeriving",       Opt_GeneralizedNewtypeDeriving, setGenDeriving ),
-  ( "OverlappingInstances",             Opt_OverlappingInstances, nop ),
+  ( "OverlappingInstances",             Opt_OverlappingInstances, 
+    \ turn_on -> when turn_on
+               $ deprecate "instead use per-instance pragamas OVERLAPPING/OVERLAPPABLE/OVERLAPS" ),
   ( "UndecidableInstances",             Opt_UndecidableInstances, nop ),
   ( "IncoherentInstances",              Opt_IncoherentInstances, nop ),
   ( "PackageImports",                   Opt_PackageImports, nop ),
index 54b0700..e0ab47a 100644 (file)
@@ -1100,8 +1100,8 @@ appendStubC (ForeignStubs h c) c_code = ForeignStubs h (c $$ c_code)
 
 Note [The interactive package]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Type and class declarations at the command prompt are treated as if
-they were defined in modules
+Type, class, and value declarations at the command prompt are treated 
+as if they were defined in modules
    interactive:Ghci1
    interactive:Ghci2
    ...etc...
@@ -1151,11 +1151,12 @@ The details are a bit tricky though:
    The 'thisPackage' field stays as 'main' (or whatever -package-name says.
 
  * The main trickiness is that the type environment (tcg_type_env and
-   fixity envt (tcg_fix_env) now contains entities from all the
-   GhciN modules together, rather than just a single module as is usually
-   the case.  So you can't use "nameIsLocalOrFrom" to decide whether
-   to look in the TcGblEnv vs the HPT/PTE.  This is a change, but not
-   a problem provided you know.
+   fixity envt (tcg_fix_env), and instances (tcg_insts, tcg_fam_insts)
+   now contains entities from all the interactive-package modules
+   (Ghci1, Ghci2, ...) together, rather than just a single module as
+   is usually the case.  So you can't use "nameIsLocalOrFrom" to
+   decide whether to look in the TcGblEnv vs the HPT/PTE.  This is a
+   change, but not a problem provided you know.
 
 
 Note [Interactively-bound Ids in GHCi]
index 723ce06..a27c0bd 100644 (file)
@@ -49,7 +49,6 @@ import TcMType
 import Type
 import Coercion ( Role(..) )
 import TcType
-import Unify
 import HscTypes
 import Id
 import Name
@@ -60,9 +59,9 @@ import PrelNames
 import SrcLoc
 import DynFlags
 import Bag
-import Maybes
 import Util
 import Outputable
+import Control.Monad( unless )
 import Data.List( mapAccumL )
 \end{code}
 
@@ -410,22 +409,24 @@ tcExtendLocalInstEnv :: [ClsInst] -> TcM a -> TcM a
 tcExtendLocalInstEnv dfuns thing_inside
  = do { traceDFuns dfuns
       ; env <- getGblEnv
-      ; inst_env' <- foldlM addLocalInst (tcg_inst_env env) dfuns
-      ; let env' = env { tcg_insts = dfuns ++ tcg_insts env,
-                        tcg_inst_env = inst_env' }
+      ; (inst_env', cls_insts') <- foldlM addLocalInst
+                                          (tcg_inst_env env, tcg_insts env)
+                                          dfuns
+      ; let env' = env { tcg_insts    = cls_insts'
+                      , tcg_inst_env = inst_env' }
       ; setGblEnv env' thing_inside }
 
-addLocalInst :: InstEnv -> ClsInst -> TcM InstEnv
--- Check that the proposed new instance is OK, 
+addLocalInst :: (InstEnv, [ClsInst]) -> ClsInst -> TcM (InstEnv, [ClsInst])
+-- Check that the proposed new instance is OK,
 -- and then add it to the home inst env
 -- If overwrite_inst, then we can overwrite a direct match
-addLocalInst home_ie ispec
+addLocalInst (home_ie, my_insts) ispec
    = do {
          -- Instantiate the dfun type so that we extend the instance
          -- envt with completely fresh template variables
          -- This is important because the template variables must
          -- not overlap with anything in the things being looked up
-         -- (since we do unification).  
+         -- (since we do unification).
              --
              -- We use tcInstSkolType because we don't want to allocate fresh
              --  *meta* type variables.
@@ -438,9 +439,23 @@ addLocalInst home_ie ispec
 
              -- Load imported instances, so that we report
              -- duplicates correctly
-           eps <- getEps
-         ; let inst_envs = (eps_inst_env eps, home_ie)
-               (tvs, cls, tys) = instanceHead ispec
+
+             -- 'matches'  are existing instance declarations that are less
+             --            specific than the new one
+             -- 'dups'     are those 'matches' that are equal to the new one
+         ; isGHCi <- getIsGHCi
+         ; eps    <- getEps
+         ; let (home_ie', my_insts')
+                 | isGHCi    = ( deleteFromInstEnv home_ie ispec
+                               , filterOut (identicalInstHead ispec) my_insts)
+                 | otherwise = (home_ie, my_insts)
+               -- If there is a home-package duplicate instance,
+               -- silently delete it
+
+               (_tvs, cls, tys) = instanceHead ispec
+               inst_envs       = (eps_inst_env eps, home_ie')
+               (matches, _, _) = lookupInstEnv inst_envs cls tys
+               dups            = filter (identicalInstHead ispec) (map fst matches)
 
              -- Check functional dependencies
          ; case checkFunDeps inst_envs ispec of
@@ -448,31 +463,10 @@ addLocalInst home_ie ispec
              Nothing    -> return ()
 
              -- Check for duplicate instance decls
-         ; let (matches, unifs, _) = lookupInstEnv inst_envs cls tys
-               dup_ispecs = [ dup_ispec 
-                            | (dup_ispec, _) <- matches
-                            , let dup_tys = is_tys dup_ispec
-                            , isJust (tcMatchTys (mkVarSet tvs) tys dup_tys)]
-                             
-             -- Find memebers of the match list which ispec itself matches.
-             -- If the match is 2-way, it's a duplicate
-             -- If it's a duplicate, but we can overwrite home package dups, then overwrite
-         ; isGHCi <- getIsGHCi
-         ; overlapFlag <- getOverlapFlag
-         ; case isGHCi of
-             False -> case dup_ispecs of
-                 dup : _ -> dupInstErr ispec dup >> return (extendInstEnv home_ie ispec)
-                 []      -> return (extendInstEnv home_ie ispec)
-             True  -> case (dup_ispecs, home_ie_matches, unifs, overlapMode overlapFlag) of
-                 (_, _:_, _, _)      -> return (overwriteInstEnv home_ie ispec)
-                 (dup:_, [], _, _)   -> dupInstErr ispec dup >> return (extendInstEnv home_ie ispec)
-                 ([], _, u:_, NoOverlap)    -> overlappingInstErr ispec u >> return (extendInstEnv home_ie ispec)
-                 _                   -> return (extendInstEnv home_ie ispec)
-               where (homematches, _) = lookupInstEnv' home_ie cls tys
-                     home_ie_matches = [ dup_ispec 
-                         | (dup_ispec, _) <- homematches
-                         , let dup_tys = is_tys dup_ispec
-                         , isJust (tcMatchTys (mkVarSet tvs) tys dup_tys)] }
+         ; unless (null dups) $
+           dupInstErr ispec (head dups)
+
+         ; return (extendInstEnv home_ie' ispec, ispec:my_insts') }
 
 traceDFuns :: [ClsInst] -> TcRn ()
 traceDFuns ispecs
@@ -492,11 +486,6 @@ dupInstErr ispec dup_ispec
   = addClsInstsErr (ptext (sLit "Duplicate instance declarations:"))
                    [ispec, dup_ispec]
 
-overlappingInstErr :: ClsInst -> ClsInst -> TcRn ()
-overlappingInstErr ispec dup_ispec
-  = addClsInstsErr (ptext (sLit "Overlapping instance declarations:")) 
-                    [ispec, dup_ispec]
-
 addClsInstsErr :: SDoc -> [ClsInst] -> TcRn ()
 addClsInstsErr herald ispecs
   = setSrcSpan (getSrcSpan (head sorted)) $
index e838ba7..f46bdfd 100644 (file)
@@ -325,6 +325,9 @@ data TcGblEnv
 #endif /* GHCI */
 
         tcg_ev_binds  :: Bag EvBind,        -- Top-level evidence bindings
+
+        -- Things defined in this module, or (in GHCi) in the interactive package
+        --   For the latter, see Note [The interactive package] in HscTypes
         tcg_binds     :: LHsBinds Id,       -- Value bindings in this module
         tcg_sigs      :: NameSet,           -- ...Top-level names that *lack* a signature
         tcg_imp_specs :: [LTcSpecPrag],     -- ...SPECIALISE prags for imported Ids
index 870113f..a9da982 100644 (file)
@@ -46,7 +46,6 @@ import Coercion
 import CoAxiom
 import VarSet
 import VarEnv
-import Module( isInteractiveModule )
 import Name
 import UniqFM
 import Outputable
@@ -381,23 +380,21 @@ identicalFamInst :: FamInst -> FamInst -> Bool
 -- Same LHS, *and* both instances are on the interactive command line
 -- Used for overriding in GHCi
 identicalFamInst (FamInst { fi_axiom = ax1 }) (FamInst { fi_axiom = ax2 })
-  =  isInteractiveModule (nameModule (coAxiomName ax1))
-  && isInteractiveModule (nameModule (coAxiomName ax2))
-  && coAxiomTyCon ax1 == coAxiomTyCon ax2
+  =  coAxiomTyCon ax1 == coAxiomTyCon ax2
   && brListLength brs1 == brListLength brs2
-  && and (brListZipWith identical_ax_branch brs1 brs2)
-  where brs1 = coAxiomBranches ax1
-        brs2 = coAxiomBranches ax2
-        identical_ax_branch br1 br2
-          = length tvs1 == length tvs2
-            && length lhs1 == length lhs2
-            && and (zipWith (eqTypeX rn_env) lhs1 lhs2)
-          where
-            tvs1 = coAxBranchTyVars br1
-            tvs2 = coAxBranchTyVars br2
-            lhs1 = coAxBranchLHS br1
-            lhs2 = coAxBranchLHS br2
-            rn_env = rnBndrs2 (mkRnEnv2 emptyInScopeSet) tvs1 tvs2
+  && and (brListZipWith identical_branch brs1 brs2)
+  where
+    brs1 = coAxiomBranches ax1
+    brs2 = coAxiomBranches ax2
+
+    identical_branch br1 br2
+      =  isJust (tcMatchTys tvs1 lhs1 lhs2)
+      && isJust (tcMatchTys tvs2 lhs2 lhs1)
+      where
+        tvs1 = mkVarSet (coAxBranchTyVars br1)
+        tvs2 = mkVarSet (coAxBranchTyVars br2)
+        lhs1 = coAxBranchLHS br1
+        lhs2 = coAxBranchLHS br2
 \end{code}
 
 %************************************************************************
index e1ab8da..636147a 100644 (file)
@@ -16,7 +16,7 @@ module InstEnv (
         instanceHead, instanceSig, mkLocalInstance, mkImportedInstance,
         instanceDFunId, tidyClsInstDFun, instanceRoughTcs,
 
-        InstEnv, emptyInstEnv, extendInstEnv, overwriteInstEnv,
+        InstEnv, emptyInstEnv, extendInstEnv, deleteFromInstEnv, identicalInstHead, 
         extendInstEnvList, lookupUniqueInstEnv, lookupInstEnv', lookupInstEnv, instEnvElts,
         classInstances, orphNamesOfClsInst, instanceBindFun,
         instanceCantMatch, roughMatchTcs
@@ -160,7 +160,8 @@ pprInstance :: ClsInst -> SDoc
 -- Prints the ClsInst as an instance declaration
 pprInstance ispec
   = hang (pprInstanceHdr ispec)
-        2 (ptext (sLit "--") <+> pprDefinedAt (getName ispec))
+        2 (vcat [ ptext (sLit "--") <+> pprDefinedAt (getName ispec)
+                , ifPprDebug (ppr (is_dfun ispec)) ])
 
 -- * pprInstanceHdr is used in VStudio to populate the ClassView tree
 pprInstanceHdr :: ClsInst -> SDoc
@@ -420,26 +421,22 @@ extendInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm })
   where
     add (ClsIE cur_insts) _ = ClsIE (ins_item : cur_insts)
 
-overwriteInstEnv :: InstEnv -> ClsInst -> InstEnv
-overwriteInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm, is_tys = tys })
-  = addToUFM_C add inst_env cls_nm (ClsIE [ins_item])
+deleteFromInstEnv :: InstEnv -> ClsInst -> InstEnv
+deleteFromInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm })
+  = adjustUFM adjust inst_env cls_nm
   where
-    add (ClsIE cur_insts) _ = ClsIE (replaceInst cur_insts)
-    
-    rough_tcs  = roughMatchTcs tys
-    replaceInst [] = [ins_item]
-    replaceInst (item@(ClsInst { is_tcs = mb_tcs,  is_tvs = tpl_tvs 
-                               , is_tys = tpl_tys }) : rest)
-    -- Fast check for no match, uses the "rough match" fields
-      | instanceCantMatch rough_tcs mb_tcs
-      = item : replaceInst rest
-
-      | let tpl_tv_set = mkVarSet tpl_tvs
-      , Just _ <- tcMatchTys tpl_tv_set tpl_tys tys
-      = ins_item : rest
-
-      | otherwise
-      = item : replaceInst rest
+    adjust (ClsIE items) = ClsIE (filterOut (identicalInstHead ins_item) items)
+
+identicalInstHead :: ClsInst -> ClsInst -> Bool
+-- ^ True when when the instance heads are the same
+-- e.g.  both are   Eq [(a,b)]
+-- Obviously should be insenstive to alpha-renaming
+identicalInstHead (ClsInst { is_cls_nm = cls_nm1, is_tcs = rough1, is_tvs = tvs1, is_tys = tys1 })
+                  (ClsInst { is_cls_nm = cls_nm2, is_tcs = rough2, is_tvs = tvs2, is_tys = tys2 })
+  =  cls_nm1 == cls_nm2
+  && not (instanceCantMatch rough1 rough2)  -- Fast check for no match, uses the "rough match" fields
+  && isJust (tcMatchTys (mkVarSet tvs1) tys1 tys2)
+  && isJust (tcMatchTys (mkVarSet tvs2) tys2 tys1)
 \end{code}
 
 
@@ -453,6 +450,54 @@ overwriteInstEnv inst_env ins_item@(ClsInst { is_cls_nm = cls_nm, is_tys = tys }
 the env is kept ordered, the first match must be the only one.  The
 thing we are looking up can have an arbitrary "flexi" part.
 
+Note [Rules for instance lookup]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+These functions implement the carefully-written rules in the user
+manual section on "overlapping instances". At risk of duplication,
+here are the rules.  If the rules change, change this text and the
+user manual simultaneously.  The link may be this:
+http://www.haskell.org/ghc/docs/latest/html/users_guide/type-class-extensions.html#instance-overlap
+
+The willingness to be overlapped or incoherent is a property of the
+instance declaration itself, controlled as follows:
+
+ * An instance is "incoherent"
+   if it has an INCOHERENT pragama, or
+   if it appears in a module compiled with -XIncoherentInstances.
+
+ * An instance is "overlappable"
+   if it has an OVERLAPPABLE or OVERLAPS pragama, or
+   if it appears in a module compiled with -XOverlappingInstances, or
+   if the instance is incoherent.
+
+ * An instance is "overlapping"
+   if it has an OVERLAPPING or OVERLAPS pragama, or
+   if it appears in a module compiled with -XOverlappingInstances, or
+   if the instance is incoherent.
+     compiled with -XOverlappingInstances.
+
+Now suppose that, in some client module, we are searching for an instance
+of the target constraint (C ty1 .. tyn). The search works like this.
+
+ * Find all instances I that match the target constraint; that is, the
+   target constraint is a substitution instance of I. These instance
+   declarations are the candidates.
+
+ * Find all non-candidate instances that unify with the target
+   constraint. Such non-candidates instances might match when the
+   target constraint is further instantiated. If all of them are
+   incoherent, proceed; if not, the search fails.
+
+ * Eliminate any candidate IX for which both of the following hold:
+   * There is another candidate IY that is strictly more specific;
+     that is, IY is a substitution instance of IX but not vice versa.
+
+   * Either IX is overlappable or IY is overlapping.
+
+ * If only one candidate remains, pick it. Otherwise if all remaining
+   candidates are incoherent, pick an arbitrary candidate. Otherwise fail.
+
+
 \begin{code}
 type DFunInstType = Maybe Type
         -- Just ty   => Instantiate with this type
@@ -536,7 +581,7 @@ lookupInstEnv' ie cls tys
       = find ((item, map (lookup_tv subst) tpl_tvs) : ms) us rest
 
         -- Does not match, so next check whether the things unify
-        -- See Note [Overlapping instances] and Note [Incoherent Instances]
+        -- See Note [Overlapping instances] and Note [Incoherent instances]
       | Incoherent <- overlapMode oflag
       = find ms us rest
 
@@ -566,7 +611,7 @@ lookupInstEnv' ie cls tys
 lookupInstEnv :: (InstEnv, InstEnv)     -- External and home package inst-env
               -> Class -> [Type]   -- What we are looking for
               -> ClsInstLookupResult
+-- ^ See Note [Rules for instance lookup]
 lookupInstEnv (pkg_ie, home_ie) cls tys
   = (safe_matches, all_unifs, safe_fail)
   where
@@ -606,7 +651,7 @@ lookupInstEnv (pkg_ie, home_ie) cls tys
                 if inSameMod x
                     then go bad unchecked
                     else go (i:bad) unchecked
-            
+
             inSameMod b =
                 let na = getName $ getName inst
                     la = isInternalName na
@@ -617,7 +662,8 @@ lookupInstEnv (pkg_ie, home_ie) cls tys
 ---------------
 ---------------
 insert_overlapping :: InstMatch -> [InstMatch] -> [InstMatch]
--- Add a new solution, knocking out strictly less specific ones
+-- ^ Add a new solution, knocking out strictly less specific ones
+-- See Note [Rules for instance lookup]
 insert_overlapping new_item [] = [new_item]
 insert_overlapping new_item (item:items)
   | new_beats_old && old_beats_new = item : insert_overlapping new_item items
@@ -653,29 +699,25 @@ insert_overlapping new_item (item:items)
             Previous change: Trac #3877, Dec 10.  -}
             overlap_ok = hasOverlappingFlag  (overlapMode (is_flag instA))
                       || hasOverlappableFlag (overlapMode (is_flag instB))
-
-
 \end{code}
 
 Note [Incoherent instances]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-For some classes, the choise of a particular instance does not matter, any one
+For some classes, the choice of a particular instance does not matter, any one
 is good. E.g. consider
 
         class D a b where { opD :: a -> b -> String }
         instance D Int b where ...
         instance D a Int where ...
 
-        g (x::Int) = opD x x
+        g (x::Int) = opD x x  -- Wanted: D Int Int
 
 For such classes this should work (without having to add an "instance D Int
 Int", and using -XOverlappingInstances, which would then work). This is what
 -XIncoherentInstances is for: Telling GHC "I don't care which instance you use;
 if you can use one, use it."
 
-
-Should this logic only work when all candidates have the incoherent flag, or
+Should this logic only work when *all* candidates have the incoherent flag, or
 even when all but one have it? The right choice is the latter, which can be
 justified by comparing the behaviour with how -XIncoherentInstances worked when
 it was only about the unify-check (note [Overlapping instances]):
@@ -686,7 +728,7 @@ Example:
         instance [incoherent] [Int] b c
         instance [incoherent] C a Int c
 Thanks to the incoherent flags,
-        foo :: ([a],b,Int)
+        [Wanted]  C [a] b Int
 works: Only instance one matches, the others just unify, but are marked
 incoherent.
 
index ff7f3ea..5166c28 100644 (file)
@@ -5060,11 +5060,21 @@ The <option>-XIncoherentInstances</option> flag implies the
 <para>
 A more precise specification is as follows.
 The willingness to be overlapped or incoherent is a property of
-the <emphasis>instance declaration</emphasis> itself, controlled by
-either an explicit pragma, or the
-presence or otherwise of the <option>-XOverlappingInstances</option>
-and <option>-XIncoherentInstances</option> flags when that instance declaration is
-being compiled.  Now suppose that, in some client module, we are searching for an instance of the
+the <emphasis>instance declaration</emphasis> itself, controlled as follows:
+<itemizedlist>
+<listitem><para>An instance is <emphasis>incoherent</emphasis> if it has an <literal>INCOHERENT</literal> pragama, or if it appears in a module compiled with <literal>-XIncoherentInstances</literal>.
+</para></listitem>
+<listitem><para>An instance is <emphasis>overlappable</emphasis> if it has an <literal>OVERLAPPABLE</literal> or <literal>OVERLAPS</literal> pragama, or if it appears in a module compiled with <literal>-XOverlappingInstances</literal>, or if the instance is incoherent.
+</para></listitem>
+<listitem><para>An instance is <emphasis>overlapping</emphasis> if it has an <literal>OVERLAPPING</literal> or <literal>OVERLAPS</literal> pragama, or if it appears in a module compiled with <literal>-XOverlappingInstances</literal>, or if the instance is incoherent.
+</para></listitem>
+</itemizedlist>
+The <option>-XOverlappingInstances</option> language extension is now deprecated in favour
+per-instance pragmas.
+</para>
+
+<para>
+Now suppose that, in some client module, we are searching for an instance of the
 <emphasis>target constraint</emphasis> <literal>(C ty1 .. tyn)</literal>.
 The search works like this.
 <itemizedlist>
@@ -5078,8 +5088,7 @@ instance declarations are the <emphasis>candidates</emphasis>.
 Find all <emphasis>non-candidate</emphasis> instances 
 that <emphasis>unify</emphasis> with the target constraint.
 Such non-candidates instances might match when the target constraint is further
-instantiated.  If all of them were compiled with
-<option>-XIncoherentInstances</option>, proceed; if not, the search fails.
+instantiated.  If all of them are incoherent, proceed; if not, the search fails.
 </para></listitem>
 
 <listitem><para>
@@ -5095,21 +5104,12 @@ Eliminate any candidate IX for which both of the following hold:
   </para></listitem>
   </itemizedlist>
 </para>
-<para>
-Instance annotated with an <literal>OVERLAPPABLE</literal> or
-<literal>OVERLAPPING</literal> pragma are treated as such.
-</para>
-<para>
-Instances annotated with the <literal>OVERLAPS</literal> pragma, or compiled
-with <option>-XOverlappingInstances</option>, are treated as both
-<emphasis>overlapping</emphasis> and <emphasis>overlappable</emphasis>.
-</para>
 </listitem>
 
 <listitem><para>
-If only one candidate remains, pick it.
-Otherwise if all remaining candidates were compiled with
-<option>-XInccoherentInstances</option>, pick an arbitrary candidate.
+If exactly one non-incoherent candidate remains, pick it.  If all
+remaining candidates are incoherent, pick an arbitary
+one. Otherwise fail.
 </para></listitem>
 
 </itemizedlist>
@@ -5118,7 +5118,7 @@ overlapping instances without the library client having to know.
 </para>
 <para>
 Errors are reported <emphasis>lazily</emphasis> (when attempting to solve a constraint), rather than <emphasis>eagerly</emphasis> 
-(when the instances themselves are defined).  So for example
+(when the instances themselves are defined).  Consider, for example
 <programlisting>
   instance C Int  b where ..
   instance C a Bool where ..
@@ -5133,20 +5133,19 @@ both instances match and an error is reported.
 <para>
 As a more substantial example of the rules in action, consider
 <programlisting>
-  instance context1 => C Int b     where ...  -- (A)
-  instance context2 => C a   Bool  where ...  -- (B)
-  instance context3 => C a   [b]   where ...  -- (C)
-  instance context4 => C Int [Int] where ...  -- (D)
+  instance {-# OVERLAPPABLE #-} context1 => C Int b     where ...  -- (A)
+  instance {-# OVERLAPPABLE #-} context2 => C a   Bool  where ...  -- (B)
+  instance {-# OVERLAPPABLE #-} context3 => C a   [b]   where ...  -- (C)
+  instance {-# OVERLAPPING  #-} context4 => C Int [Int] where ...  -- (D)
 </programlisting>
-compiled with <option>-XOverlappingInstances</option> enabled. Now suppose that the type inference
-engine needs to solve The constraint
+Now suppose that the type inference
+engine needs to solve the constraint
 <literal>C Int [Int]</literal>.  This constraint matches instances (A), (C) and (D), but the last
 is more specific, and hence is chosen.
 </para>
 <para>If (D) did not exist then (A) and (C) would still be matched, but neither is
-most specific. In that case, the program would be rejected even with
-<option>-XOverlappingInstances</option>. With
-<option>-XIncoherentInstances</option> enabled, it would be accepted and (A) or
+most specific. In that case, the program would be rejected, unless
+<option>-XIncoherentInstances</option> is enabled, in which case it would be accepted and (A) or
 (C) would be chosen arbitrarily.
 </para>
 <para>
index d7328c6..363627a 100644 (file)
@@ -2,7 +2,6 @@
 {-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE OverlappingInstances #-}
 
 module HTk.Toolkit.TreeList (getObjectFromTreeList) where
 
@@ -10,7 +9,7 @@ class Eq c => CItem c
 
 -- A bizarre instance decl!
 -- People who use instance decls like this are asking for trouble
-instance GUIObject w => Eq w where
+instance {-# OVERLAPPABLE #-} GUIObject w => Eq w where
   w1 == w2 = toGUIObject w1 == toGUIObject w2
 
 data StateEntry a 
@@ -31,7 +30,7 @@ getObjectFromTreeList state = state == state
 
 data CItem a => TreeListObject a
 
-instance CItem a => Eq (TreeListObject a)
+instance {-# OVERLAPPING #-} CItem a => Eq (TreeListObject a)
 
 class GUIObject w where
   toGUIObject     :: w -> GUIOBJECT
index d5cc4a2..dceeaa6 100644 (file)
@@ -2,7 +2,7 @@
 T4966.hs:1:14: Warning:
     -XDatatypeContexts is deprecated: It was widely considered a misfeature, and has been removed from the Haskell language.
 
-T4966.hs:34:10: Warning:
+T4966.hs:33:30: Warning:
     No explicit implementation for
       either ‘==’ or ‘/=’
     In the instance declaration for ‘Eq (TreeListObject a)’
index 76f387d..99b0b40 100644 (file)
@@ -4,7 +4,8 @@
 {-# LANGUAGE FlexibleContexts           #-}
 {-# LANGUAGE TypeOperators              #-}
 {-# LANGUAGE DefaultSignatures          #-}
-{-# LANGUAGE IncoherentInstances        #-} -- necessary, unfortunately
+{- # LANGUAGE IncoherentInstances        #-} -- necessary, unfortunately
+{-# LANGUAGE OverlappingInstances        #-} 
 
 module GUniplate where
 
@@ -20,7 +21,8 @@ class Uniplate' f b where
 instance Uniplate' U1 a where
   children' U1 = []
 
-instance Uniplate' (K1 i a) a where
+instance {-# OVERLAPPING #-} Uniplate' (K1 i a) a where
+  -- overlaps the (Uniplate' (K1 i a) b) instance
   children' (K1 a) = [a]
 
 instance Uniplate' (K1 i a) b where
index e6a9159..e364f06 100644 (file)
@@ -5,8 +5,8 @@
     Use :print or :force to determine these types
     Relevant bindings include it :: a1 (bound at <interactive>:11:1)
     Note: there are several potential instances:
-      instance Show a => Show (List1 a) -- Defined at ../Test.hs:11:12
-      instance Show MyInt -- Defined at ../Test.hs:14:16
+      instance Show Unary -- Defined at ../Test.hs:37:29
+      instance Show a => Show (MkT2 a) -- Defined at ../Test.hs:20:12
       instance Show a => Show (MkT a) -- Defined at ../Test.hs:17:13
       ...plus 31 others
     In a stmt of an interactive GHCi command: print it
index 8273d6b..a66d000 100644 (file)
@@ -1,5 +1,3 @@
-{-# LANGUAGE OverlappingInstances #-}
-
 module C where
 
 import A
index d1e67eb..d5a313a 100755 (executable)
@@ -61,6 +61,7 @@ test('ghci041', normal, ghci_script, ['ghci041.script'])
 test('ghci042', normal, ghci_script, ['ghci042.script'])
 test('ghci043', normal, ghci_script, ['ghci043.script'])
 test('ghci044', normal, ghci_script, ['ghci044.script'])
+test('ghci044a', normal, ghci_script, ['ghci044a.script'])
 test('ghci045', normal, ghci_script, ['ghci045.script'])
 test('ghci046', normal, ghci_script, ['ghci046.script'])
 test('ghci047', normal, ghci_script, ['ghci047.script'])
index 7af66bb..b89ede3 100644 (file)
@@ -1,10 +1,13 @@
 --Testing flexible and Overlapping instances
-class C a where { f :: a -> Int; f _ = 3 }
-instance C Int where { f = id }
-instance C [Int]
+class C a where { f :: a -> String; f _ = "Default" }
+instance C Int where { f _ = "Zeroth" }
 :set -XFlexibleInstances
-instance C [Int]
-instance C a => C [a] where f xs = length xs
--- ***This should be an overlapping instances error!***
-:set -XOverlappingInstances
-instance C a => C [a] where f xs = length xs
+instance C [Int] where f _ = "First"
+f [3::Int]
+instance C a => C [a] where f xs = "Second"
+f [4::Int]  -- ***This should be an overlapping instances error!***
+instance {-# OVERLAPPABLE #-} C a => C [a] where f xs = "Third"
+f [5::Int]  -- Should be fine
+instance {-# OVERLAPPABLE #-} C a => C [a] where f xs = "Fourth"
+f [6::Int]  -- Should be fine too, overrides
+
index c319dd1..9bc8df9 100644 (file)
@@ -1,13 +1,8 @@
 
-<interactive>:5:10:
-    Illegal instance declaration for ‘C [Int]’
-      (All instance types must be of the form (T a1 ... an)
-       where a1 ... an are *distinct type variables*,
-       and each type variable appears at most once in the instance head.
-       Use FlexibleInstances if you want to disable this.)
-    In the instance declaration for ‘C [Int]’
-
-<interactive>:7:10:
-    Overlapping instance declarations:
-      instance C [Int] -- Defined at <interactive>:7:10
+<interactive>:9:1:
+    Overlapping instances for C [Int] arising from a use of ‘f’
+    Matching instances:
+      instance C [Int] -- Defined at <interactive>:6:10
       instance C a => C [a] -- Defined at <interactive>:8:10
+    In the expression: f [4 :: Int]
+    In an equation for ‘it’: it = f [4 :: Int]
diff --git a/testsuite/tests/ghci/scripts/ghci044a.hs b/testsuite/tests/ghci/scripts/ghci044a.hs
new file mode 100644 (file)
index 0000000..ac400d3
--- /dev/null
@@ -0,0 +1,9 @@
+--Testing flexible and Overlapping instances
+class C a where { f :: a -> String; f _ = 3 }
+instance C Int where { f = id }
+:set -XFlexibleInstances
+instance C [Int] where f _ = "First"
+f [3::Int]
+-- Should override the identical one preceding
+instance C [Int] where f _ = "Second"
+f [3::Int]
diff --git a/testsuite/tests/ghci/scripts/ghci044a.script b/testsuite/tests/ghci/scripts/ghci044a.script
new file mode 100644 (file)
index 0000000..d78c5c2
--- /dev/null
@@ -0,0 +1,9 @@
+--Testing flexible and Overlapping instances
+class C a where { f :: a -> String; f _ = "Default" }
+instance C Int where { f _ = "Zeroth" }
+:set -XFlexibleInstances
+instance C [Int] where f _ = "First"
+f [3::Int]
+-- Should override the identical one preceding
+instance C [Int] where f _ = "Second"
+f [3::Int]
diff --git a/testsuite/tests/ghci/scripts/ghci044a.stdout b/testsuite/tests/ghci/scripts/ghci044a.stdout
new file mode 100644 (file)
index 0000000..fe475f4
--- /dev/null
@@ -0,0 +1,2 @@
+"First"
+"Second"
index 49d9304..70cc518 100644 (file)
@@ -1,7 +1,6 @@
 --Testing GADTs, type families as well as a ton of crazy type stuff
 :set -XGADTs
 :set -XTypeFamilies
-:set -XOverlappingInstances
 :set -XFunctionalDependencies
 :set -XFlexibleContexts
 :set -XFlexibleInstances
@@ -22,8 +21,9 @@ data HTrue
 data HFalse
 
 class TypeEq x y b | x y -> b
-instance (HTrue ~ b)  => TypeEq x x b
-instance (HFalse ~ b) => TypeEq x y b
+instance {-# OVERLAPS #-} (HTrue ~ b)  => TypeEq x x b
+instance {-# OVERLAPS #-} (HTrue ~ b)  => TypeEq x x b
+instance {-# OVERLAPS #-} (HFalse ~ b) => TypeEq x y b
 
 type family Or a b
 type instance Or HTrue  HTrue  = HTrue
index 6cc1512..7ceedfd 100644 (file)
@@ -1,6 +1,6 @@
 {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
              FlexibleInstances,
-             OverlappingInstances, UndecidableInstances #-}
+             UndecidableInstances #-}
 
 -- Rather exotic example posted to Haskell mailing list 17 Oct 07
 -- It concerns context reduction and functional dependencies
index dbba60d..e37bfe3 100644 (file)
@@ -1,5 +1,5 @@
 {-# LANGUAGE EmptyDataDecls, TypeFamilies, UndecidableInstances,
-             ScopedTypeVariables, OverlappingInstances, TypeOperators,
+             ScopedTypeVariables, TypeOperators,
              FlexibleInstances, NoMonomorphismRestriction,
              MultiParamTypeClasses, FlexibleContexts #-}
 module IndTypesPerfMerge where
index dc0ae53..26ea632 100644 (file)
@@ -1,6 +1,6 @@
 {-# LANGUAGE TypeFamilies, EmptyDataDecls, FlexibleContexts #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances #-}
+{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
 
 module NonLinearLHS where
 
index b5c37a6..60b5640 100644 (file)
@@ -1,13 +1,13 @@
-{-# LANGUAGE TypeFamilies, FlexibleInstances, OverlappingInstances #-}\r
+{-# LANGUAGE TypeFamilies, FlexibleInstances #-}\r
 module T4246 where\r
 \r
 class Stupid a where\r
    type F a\r
 \r
-instance Stupid a where\r
+instance {-# OVERLAPPABLE #-} Stupid a where\r
    type F a = a\r
 \r
-instance Stupid Int where\r
+instance {-# OVERLAPPING #-} Stupid Int where\r
    type F Int = Bool\r
 \r
 type family G a :: *\r
index b48e820..d7d4730 100644 (file)
@@ -11,7 +11,6 @@
 {-# LANGUAGE TypeFamilies, MultiParamTypeClasses
   , FlexibleContexts, FlexibleInstances, UndecidableInstances
   , TypeSynonymInstances, GeneralizedNewtypeDeriving
-  , OverlappingInstances 
   #-}
 module XMLGenerator where
 
@@ -26,9 +25,9 @@ class Monad m => XMLGen m where
 class XMLGen m => EmbedAsChild m c where
     asChild :: c -> XMLGenT m [Child m]
 
-instance (EmbedAsChild m c, m1 ~ m) => EmbedAsChild m (XMLGenT m1 c)
+instance {-# OVERLAPPING #-} (EmbedAsChild m c, m1 ~ m) => EmbedAsChild m (XMLGenT m1 c)
 
-instance (XMLGen m,  XML m ~ x) => EmbedAsChild m x
+instance {-# OVERLAPPABLE #-} (XMLGen m,  XML m ~ x) => EmbedAsChild m x
 
 data Xml = Xml
 data IdentityT m a = IdentityT (m a)
@@ -39,11 +38,11 @@ instance XMLGen (IdentityT m) where
 data Identity a = Identity a
 instance Monad Identity
 
-instance EmbedAsChild (IdentityT IO) (XMLGenT Identity ())
+instance {-# OVERLAPPING #-} EmbedAsChild (IdentityT IO) (XMLGenT Identity ())
 
 data FooBar = FooBar
 
-instance EmbedAsChild (IdentityT IO) FooBar where
+instance {-# OVERLAPPING #-} EmbedAsChild (IdentityT IO) FooBar where
   asChild b = asChild $ (genElement "foo")
   -- asChild :: FooBar -> XMLGenT (XMLGenT (IdentityT IO) [Child (IdentitiyT IO)])
 
index b2bd626..760cdf9 100644 (file)
@@ -1,15 +1,15 @@
 
-T4485.hs:47:15:
+T4485.hs:46:15:
     Overlapping instances for EmbedAsChild
                                 (IdentityT IO) (XMLGenT m0 (XML m0))
       arising from a use of ‘asChild’
     Matching instances:
-      instance [overlap ok] (EmbedAsChild m c, m1 ~ m) =>
-                            EmbedAsChild m (XMLGenT m1 c)
-        -- Defined at T4485.hs:29:10
-      instance [overlap ok] EmbedAsChild
-                              (IdentityT IO) (XMLGenT Identity ())
-        -- Defined at T4485.hs:42:10
+      instance [overlapping] (EmbedAsChild m c, m1 ~ m) =>
+                             EmbedAsChild m (XMLGenT m1 c)
+        -- Defined at T4485.hs:28:30
+      instance [overlapping] EmbedAsChild
+                               (IdentityT IO) (XMLGenT Identity ())
+        -- Defined at T4485.hs:41:30
     (The choice depends on the instantiation of ‘m0’
      To pick the first instance above, use IncoherentInstances
      when compiling the other instance declarations)
@@ -18,12 +18,11 @@ T4485.hs:47:15:
     In an equation for ‘asChild’:
         asChild b = asChild $ (genElement "foo")
 
-T4485.hs:47:26:
+T4485.hs:46:26:
     No instance for (XMLGen m0) arising from a use of ‘genElement’
     The type variable ‘m0’ is ambiguous
     Note: there is a potential instance available:
-      instance [overlap ok] XMLGen (IdentityT m)
-        -- Defined at T4485.hs:36:10
+      instance XMLGen (IdentityT m) -- Defined at T4485.hs:35:10
     In the second argument of ‘($)’, namely ‘(genElement "foo")’
     In the expression: asChild $ (genElement "foo")
     In an equation for ‘asChild’:
index 396a543..dfcd399 100644 (file)
@@ -9,7 +9,6 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE UndecidableInstances #-}
 
 module Main where
index 18af3fa..19517cb 100644 (file)
@@ -1,26 +1,26 @@
-\r
-T5439.hs:83:28:\r
-    Couldn't match type ‘Attempt (HHead (HDrop n0 l0))\r
-                         -> Attempt (HElemOf l0)’\r
-                  with ‘Attempt (WaitOpResult (WaitOps rs))’\r
-    Expected type: f (Attempt (HNth n0 l0) -> Attempt (HElemOf l0))\r
-      Actual type: f (Attempt (WaitOpResult (WaitOps rs)))\r
-    Relevant bindings include\r
-      register :: Bool -> Peano n -> WaitOps (HDrop n rs) -> IO Bool\r
-        (bound at T5439.hs:65:9)\r
-      ev :: f (Attempt (WaitOpResult (WaitOps rs)))\r
-        (bound at T5439.hs:62:22)\r
-      ops :: WaitOps rs (bound at T5439.hs:62:18)\r
-      registerWaitOp :: WaitOps rs\r
-                        -> f (Attempt (WaitOpResult (WaitOps rs))) -> IO Bool\r
-        (bound at T5439.hs:62:3)\r
-    In the first argument of ‘complete’, namely ‘ev’\r
-    In the expression: complete ev\r
-\r
-T5439.hs:83:39:\r
-    Couldn't match expected type ‘Peano n0’\r
-                with actual type ‘Attempt α0’\r
-    In the second argument of ‘($)’, namely\r
-      ‘Failure (e :: SomeException)’\r
-    In the second argument of ‘($)’, namely\r
-      ‘inj $ Failure (e :: SomeException)’\r
+
+T5439.hs:82:28:
+    Couldn't match type ‘Attempt (HHead (HDrop n0 l0))
+                         -> Attempt (HElemOf l0)’
+                  with ‘Attempt (WaitOpResult (WaitOps rs))’
+    Expected type: f (Attempt (HNth n0 l0) -> Attempt (HElemOf l0))
+      Actual type: f (Attempt (WaitOpResult (WaitOps rs)))
+    Relevant bindings include
+      register :: Bool -> Peano n -> WaitOps (HDrop n rs) -> IO Bool
+        (bound at T5439.hs:64:9)
+      ev :: f (Attempt (WaitOpResult (WaitOps rs)))
+        (bound at T5439.hs:61:22)
+      ops :: WaitOps rs (bound at T5439.hs:61:18)
+      registerWaitOp :: WaitOps rs
+                        -> f (Attempt (WaitOpResult (WaitOps rs))) -> IO Bool
+        (bound at T5439.hs:61:3)
+    In the first argument of ‘complete’, namely ‘ev’
+    In the expression: complete ev
+
+T5439.hs:82:39:
+    Couldn't match expected type ‘Peano n0’
+                with actual type ‘Attempt α0’
+    In the second argument of ‘($)’, namely
+      ‘Failure (e :: SomeException)’
+    In the second argument of ‘($)’, namely
+      ‘inj $ Failure (e :: SomeException)’
index 6e10939..004f487 100644 (file)
@@ -1,7 +1,7 @@
 {-# OPTIONS_GHC -fcontext-stack=1000 #-} 
 {-# LANGUAGE 
      FlexibleContexts, FlexibleInstances, FunctionalDependencies, 
-     MultiParamTypeClasses, OverlappingInstances, TypeSynonymInstances, 
+     MultiParamTypeClasses, TypeSynonymInstances, 
      TypeOperators, UndecidableInstances, TypeFamilies #-} 
 module T5321FD where
 
index efd7db7..bf70ce5 100644 (file)
@@ -1,7 +1,7 @@
 {-# OPTIONS_GHC -fcontext-stack=1000 #-} 
 {-# LANGUAGE 
      FlexibleContexts, FlexibleInstances, FunctionalDependencies, 
-     MultiParamTypeClasses, OverlappingInstances, TypeSynonymInstances, 
+     MultiParamTypeClasses, TypeSynonymInstances, 
      TypeOperators, UndecidableInstances, TypeFamilies #-} 
 module T5321Fun where
 
index d400b91..b53df16 100644 (file)
@@ -12,9 +12,9 @@ TYPE CONSTRUCTORS
 COERCION AXIOMS
   axiom T8958.NTCo:Map :: Map k v = [(k, v)]
 INSTANCES
+  instance [incoherent] Nominal a -- Defined at T8958.hs:7:10
   instance [incoherent] Representational a
     -- Defined at T8958.hs:10:10
-  instance [incoherent] Nominal a -- Defined at T8958.hs:7:10
 Dependent modules: []
 Dependent packages: [base, ghc-prim, integer-gmp]
 
index 4e96c84..950f95a 100644 (file)
@@ -1,12 +1,11 @@
 -- Test restricted functionality: Overlapping
 :unset +s
 :set -XSafe
-:set -XOverlappingInstances
 :set -XFlexibleInstances
 
 :l P13_A
 
-instance Pos [Int] where { res _ = error "This curry is poisoned!" }
+instance {-# OVERLAPPING #-} Pos [Int] where { res _ = error "This curry is poisoned!" }
 
 res [1::Int, 2::Int]
 -- res 'c'
index edf5e1e..44f8ff4 100644 (file)
@@ -1,10 +1,13 @@
 
-<interactive>:12:1:
+P13_A.hs:1:14: Warning:
+    -XOverlappingInstances is deprecated: instead use per-instance pragamas OVERLAPPING/OVERLAPPABLE/OVERLAPS
+
+<interactive>:11:1:
     Unsafe overlapping instances for Pos [Int]
       arising from a use of ‘res’
     The matching instance is:
-      instance [overlap ok] [safe] Pos [Int]
-        -- Defined at <interactive>:10:10
+      instance [overlapping] [safe] Pos [Int]
+        -- Defined at <interactive>:9:30
     It is compiled in a Safe module and as such can only
     overlap instances from the same module, however it
     overlaps the following instances from different modules:
index 13f22ce..4cd276f 100644 (file)
@@ -1,4 +1,5 @@
 {-# LANGUAGE OverlappingInstances #-}
+{-# OPTIONS_GHC -w #-}  -- Turn off deprecation for OverlappingInstances
 -- | Unsafe as uses overlapping instances
 -- Although it isn't defining any so can we mark safe
 -- still?
index 83c79da..d0c5c68 100644 (file)
@@ -6,8 +6,8 @@ SafeLang10.hs:8:13:
     Unsafe overlapping instances for Pos [Int]
       arising from a use of ‘res’
     The matching instance is:
-      instance [overlap ok] [safe] Pos [Int]
-        -- Defined at SafeLang10_B.hs:14:10
+      instance [overlapping] [safe] Pos [Int]
+        -- Defined at SafeLang10_B.hs:13:30
     It is compiled in a Safe module and as such can only
     overlap instances from the same module, however it
     overlaps the following instances from different modules:
index 5b9954c..d9a8f63 100644 (file)
@@ -1,5 +1,4 @@
 {-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE Safe #-}
 
 -- Untrusted plugin! Don't wan't it changing behaviour of our
@@ -8,10 +7,10 @@ module SafeLang10_B where
 
 import SafeLang10_A
 
-instance Pos a where
+instance {-# OVERLAPPABLE #-} Pos a where
     res _ = False
 
-instance Pos [Int] where
+instance {-# OVERLAPPING #-} Pos [Int] where
     res _ = error "This curry is poisoned!"
 
 function :: Int
index 6348def..f1ce209 100644 (file)
@@ -1,5 +1,4 @@
 {-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE OverlappingInstances #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE TypeOperators #-}
index 75dde28..2802476 100644 (file)
@@ -1,3 +1,3 @@
 
-T5359b.hs:62:1: Warning:
+T5359b.hs:61:1: Warning:
     SPECIALISE pragma on INLINE function probably won't fire: ‘genum’
index 2b42cc2..c7277b7 100644 (file)
@@ -1,4 +1,4 @@
-{-# LANGUAGE OverlappingInstances, UndecidableInstances,
+{-# LANGUAGE UndecidableInstances,
              ExistentialQuantification, FlexibleInstances #-}
 
 -- module Formula where
@@ -186,7 +186,7 @@ class AddT a where
     addT :: a -> Formula -> Maybe Formula
     addT _ _ = Nothing
 
-instance (FORMULA a) => AddT a where {}
+instance {-# OVERLAPPABLE #-} (FORMULA a) => AddT a where {}
 
 instance AddT Formula where
     addT (Formula f) = addT f
index 41549ca..d78de08 100644 (file)
@@ -1,5 +1,5 @@
 {-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, TypeFamilies,
-             FlexibleInstances, OverlappingInstances #-}
+             FlexibleInstances #-}
 
 module T4135a where
 
index 5d5869c..dcf25f7 100644 (file)
@@ -2,7 +2,6 @@
     MultiParamTypeClasses,\r
     FunctionalDependencies,\r
     UndecidableInstances,\r
-    OverlappingInstances,\r
     FlexibleInstances,\r
     EmptyDataDecls #-}\r
 \r
index dce1601..f1c1b49 100644 (file)
@@ -1,5 +1,5 @@
 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
-             OverlappingInstances, UndecidableInstances #-}
+             UndecidableInstances #-}
 
 -- Instances compile fine but instance selection loops in GHC 6.2.
 -- try: :t foo (T1a 1)
index 518f923..e361556 100644 (file)
@@ -9,8 +9,8 @@ tc170:
 
 tc173:
        $(RM) Tc173a.o Tc173a.hi Tc173b.o Tc173b.hi
-       '$(TEST_HC)' $(TEST_HC_OPTS) -c -XFlexibleInstances -XTypeSynonymInstances -XUndecidableInstances -XOverlappingInstances Tc173a.hs
-       '$(TEST_HC)' $(TEST_HC_OPTS) -c -XUndecidableInstances -XOverlappingInstances Tc173b.hs
+       '$(TEST_HC)' $(TEST_HC_OPTS) -c Tc173a.hs
+       '$(TEST_HC)' $(TEST_HC_OPTS) -c Tc173b.hs
 
 T2412:
        $(RM) -f T2412.hi-boot T2412.o-boot T2412A.hi T2412A.o T2412.hi T2412.o
index d466e48..2482696 100644 (file)
@@ -1,4 +1,4 @@
-{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, OverlappingInstances, UndecidableInstances, KindSignatures #-}
+{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, FlexibleInstances, UndecidableInstances, KindSignatures #-}
 
 -- Trac #1470
 
@@ -15,10 +15,9 @@ data FooD a = FooD
 
 instance Foo t => Sat (FooD t)
 
-instance Data FooD a => Foo a
-
-
-instance Foo a       => Foo [a]
+instance {-# OVERLAPPABLE #-} Data FooD a => Foo a
+instance {-# OVERLAPS #-}     Foo a       => Foo [a]
+instance {-# OVERLAPPING #-}                 Foo [Char]
 {-
  Given:                Foo a,
  and its superclasses: Data FooD a
@@ -35,4 +34,3 @@ instance Foo a       => Foo [a]
 BUT THIS INSTANCE OVERLAPS
 -}
 
-instance                Foo [Char]
index a0868af..443d73a 100644 (file)
@@ -1,4 +1,4 @@
-{-# LANGUAGE OverlappingInstances , UndecidableInstances, EmptyDataDecls #-}
+{-# LANGUAGE UndecidableInstances, EmptyDataDecls #-}
 {-# LANGUAGE RankNTypes, KindSignatures, MultiParamTypeClasses, FlexibleInstances #-}
 
 -- Works with new constraint solver
index 774d5f3..2adaa1a 100644 (file)
@@ -1,4 +1,4 @@
-{-# LANGUAGE OverlappingInstances, UndecidableInstances, MultiParamTypeClasses, 
+{-# LANGUAGE UndecidableInstances, MultiParamTypeClasses, 
              FunctionalDependencies, FlexibleInstances #-}
 
 module T3108 where
@@ -10,9 +10,9 @@ class C0 x
  m0 :: x -> ()
  m0 = const undefined
 
-instance (C0 x, C0 y) => C0 (x,y)
-instance C0 Bool
-instance C0 (x,Bool) => C0 x
+instance {-# OVERLAPPING #-} (C0 x, C0 y) => C0 (x,y)
+instance {-# OVERLAPPING #-} C0 Bool
+instance {-# OVERLAPPABLE #-} C0 (x,Bool) => C0 x
 
 foo :: ()
 foo = m0 (1::Int)
@@ -25,9 +25,9 @@ class C1 x
  m1 :: x -> ()
  m1 = const undefined
 
-instance (C1 x, C1 y) => C1 (x,y)
-instance C1 Bool
-instance (C2 x y, C1 (y,Bool)) => C1 x
+instance {-# OVERLAPPING #-} (C1 x, C1 y) => C1 (x,y)
+instance {-# OVERLAPPING #-} C1 Bool
+instance {-# OVERLAPPABLE #-} (C2 x y, C1 (y,Bool)) => C1 x
 
 class C2 x y | x -> y
 instance C2 Int Int
index c8a589d..f3704cc 100644 (file)
@@ -1,3 +1,4 @@
+{-# LANGUAGE FlexibleInstances, TypeSynonymInstances, UndecidableInstances #-}
 module Tc173a where
 
 class FormValue value where
@@ -8,10 +9,10 @@ class FormTextField value
 
 instance FormTextField String
 
-instance FormTextField value => FormTextFieldIO value
+instance {-# OVERLAPPABLE #-} FormTextField value => FormTextFieldIO value
 
 class FormTextFieldIO value
 
 instance FormTextFieldIO value => FormValue value
 
-instance FormTextFieldIO value => FormTextFieldIO (Maybe value)
+instance {-# OVERLAPPING #-} FormTextFieldIO value => FormTextFieldIO (Maybe value)
index d05ccdb..94fdcb2 100644 (file)
@@ -1,4 +1,4 @@
-{-# LANGUAGE FlexibleInstances, OverlappingInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
 
 {-  With "hugs -98 +o test.hs" gives me:
     ERROR "test.hs":8 - Cannot justify constraints in instance member binding
@@ -29,8 +29,8 @@ class FromStr a where
 typeError :: FromStr a => a -> a
 typeError t = error "type error"
 
-instance FromStr [a] where
+instance {-# OVERLAPPABLE #-} FromStr [a] where
      fromStr _ = typeError undefined  -- line 8
 
-instance FromStr [(String,a)] where  -- line 10
+instance {-# OVERLAPPING #-} FromStr [(String,a)] where  -- line 10
      fromStr _ = typeError undefined  -- line 11
index 1109505..62db472 100644 (file)
@@ -1,5 +1,4 @@
-{-# LANGUAGE ExistentialQuantification, FlexibleInstances,
-             OverlappingInstances, UndecidableInstances #-}
+{-# LANGUAGE ExistentialQuantification, FlexibleInstances, UndecidableInstances #-}
 
 -- Tests context reduction for existentials
 
@@ -7,9 +6,9 @@ module TestWrappedNode where
 
 class Foo a where { op :: a -> Int }
 
-instance Foo a => Foo [a] where        -- NB overlap
+instance {-# OVERLAPPABLE #-} Foo a => Foo [a] where   -- NB overlap
   op (x:xs) = op x
-instance Foo [Int] where               -- NB overlap
+instance {-# OVERLAPPING #-} Foo [Int] where           -- NB overlap
   op x = 1
 
 data T = forall a. Foo a => MkT a
index 4a79e69..663143c 100644 (file)
@@ -1,7 +1,6 @@
 {-# LANGUAGE TypeFamilies, MultiParamTypeClasses\r
   , FlexibleContexts, FlexibleInstances, UndecidableInstances\r
   , TypeSynonymInstances, GeneralizedNewtypeDeriving\r
-  , OverlappingInstances \r
   #-}\r
 \r
 module LongWayOverlapping where\r
index 753ee0f..f1eb2db 100644 (file)
@@ -1,5 +1,5 @@
 
-LongWayOverlapping.hs:23:11:
+LongWayOverlapping.hs:22:11:
     No instance for (EmbAsChild [Char] Char)
       arising from a use of ‘emb’
     In the expression: emb 'c'
index 321c2d5..ea0c335 100644 (file)
@@ -1,5 +1,5 @@
 {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
-              OverlappingInstances, UndecidableInstances,
+              UndecidableInstances,
              IncoherentInstances,
               FlexibleInstances #-}
 
index 6c5faf9..e3278d8 100644 (file)
@@ -1,11 +1,11 @@
-{-# LANGUAGE FlexibleInstances, OverlappingInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
 
 -- A very delicate interaction of overlapping instances
 
 module T5051 where
 
 data T = T deriving( Eq, Ord )
-instance Eq [T] 
+instance {-# OVERLAPPING #-} Eq [T] 
 
 foo :: Ord a => [a] -> Bool
 foo x = x >= x
index f6225ea..3fc46f9 100644 (file)
@@ -3,7 +3,7 @@ T5051.hs:11:11:
     Overlapping instances for Eq [a] arising from a use of ‘>=’
     Matching instances:
       instance Eq a => Eq [a] -- Defined in ‘GHC.Classes’
-      instance [overlap ok] Eq [T] -- Defined at T5051.hs:8:10
+      instance [overlapping] Eq [T] -- Defined at T5051.hs:8:30
     (The choice depends on the instantiation of ‘a’
      To pick the first instance above, use IncoherentInstances
      when compiling the other instance declarations)
index 80e0808..7942a87 100644 (file)
@@ -1,8 +1,8 @@
-{-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances #-}
+{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
 
 module Test where
 
-instance Show a => Eq a where
+instance {-# OVERLAPPABLE #-} Show a => Eq a where
    x == y =  length (show x) == length (show y)
 
 f :: Show a => a -> a -> Bool
index 614c99c..a572c07 100644 (file)
@@ -2,7 +2,7 @@
 T5095.hs:9:11:
     Overlapping instances for Eq a arising from a use of ‘==’
     Matching instances:
-      instance [overlap ok] Show a => Eq a -- Defined at T5095.hs:5:10
+      instance [overlappable] Show a => Eq a -- Defined at T5095.hs:5:31
       instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in ‘GHC.Real’
       instance Eq () -- Defined in ‘GHC.Classes’
       instance (Eq a, Eq b) => Eq (a, b) -- Defined in ‘GHC.Classes’
index 86c2a92..84966c4 100644 (file)
@@ -1,13 +1,13 @@
 
-{-# LANGUAGE OverlappingInstances, FlexibleInstances #-}
+{-# LANGUAGE FlexibleInstances #-}
 
 module ShouldFail where
 
 class Foo a where
   op :: a -> a
 
-instance Foo a => Foo [a] 
-instance Foo [Int]
+instance {-# OVERLAPPABLE #-} Foo a => Foo [a] 
+instance {-# OVERLAPPING #-} Foo [Int]
 
 foo :: Foo a => [a] -> [a]
 foo x = op x
index bc71d5e..dc0679e 100644 (file)
@@ -2,9 +2,9 @@
 tcfail121.hs:13:9:
     Overlapping instances for Foo [a] arising from a use of ‘op’
     Matching instances:
-      instance [overlap ok] Foo a => Foo [a]
-        -- Defined at tcfail121.hs:9:10
-      instance [overlap ok] Foo [Int] -- Defined at tcfail121.hs:10:10
+      instance [overlappable] Foo a => Foo [a]
+        -- Defined at tcfail121.hs:9:31
+      instance [overlapping] Foo [Int] -- Defined at tcfail121.hs:10:30
     (The choice depends on the instantiation of ‘a’
      To pick the first instance above, use IncoherentInstances
      when compiling the other instance declarations)
index 7565755..6878e4e 100644 (file)
@@ -2,7 +2,7 @@
 -- This was accepted due to a bug in GHC
 
 {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
-             OverlappingInstances, UndecidableInstances, IncoherentInstances,
+             UndecidableInstances, IncoherentInstances,
              FlexibleInstances #-}
 
 module Foo where