diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2014-07-31 15:49:14 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2014-07-31 15:49:45 +0100 |
commit | 1ae5fa451f4f554e0d652d55f9312a585188ce13 (patch) | |
tree | 1d0ef82924eedf6803b48b8d0ba7748f9622b227 | |
parent | bfaa17998ed0cb8b22132d8e824b274ac5f038cc (diff) | |
download | haskell-1ae5fa451f4f554e0d652d55f9312a585188ce13.tar.gz |
Complete work on new OVERLAPPABLE/OVERLAPPING pragmas (Trac #9242)
* 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, 355 insertions, 307 deletions
diff --git a/compiler/basicTypes/BasicTypes.lhs b/compiler/basicTypes/BasicTypes.lhs index 0ae47377d7..c6fb26ccd3 100644 --- a/compiler/basicTypes/BasicTypes.lhs +++ b/compiler/basicTypes/BasicTypes.lhs @@ -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) diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs index 1bb9f2ceb8..9c45f41f14 100644 --- a/compiler/main/DynFlags.hs +++ b/compiler/main/DynFlags.hs @@ -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 ), diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs index 54b070031a..e0ab47afb7 100644 --- a/compiler/main/HscTypes.lhs +++ b/compiler/main/HscTypes.lhs @@ -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] diff --git a/compiler/typecheck/Inst.lhs b/compiler/typecheck/Inst.lhs index 723ce0671e..a27c0bd0f6 100644 --- a/compiler/typecheck/Inst.lhs +++ b/compiler/typecheck/Inst.lhs @@ -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)) $ diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs index e838ba7c26..f46bdfd2d9 100644 --- a/compiler/typecheck/TcRnTypes.lhs +++ b/compiler/typecheck/TcRnTypes.lhs @@ -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 diff --git a/compiler/types/FamInstEnv.lhs b/compiler/types/FamInstEnv.lhs index 870113f134..a9da982e6a 100644 --- a/compiler/types/FamInstEnv.lhs +++ b/compiler/types/FamInstEnv.lhs @@ -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} %************************************************************************ diff --git a/compiler/types/InstEnv.lhs b/compiler/types/InstEnv.lhs index e1ab8da5c7..636147a461 100644 --- a/compiler/types/InstEnv.lhs +++ b/compiler/types/InstEnv.lhs @@ -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. diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml index ff7f3eae74..5166c28f0e 100644 --- a/docs/users_guide/glasgow_exts.xml +++ b/docs/users_guide/glasgow_exts.xml @@ -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> diff --git a/testsuite/tests/deriving/should_compile/T4966.hs b/testsuite/tests/deriving/should_compile/T4966.hs index d7328c6ef6..363627a415 100644 --- a/testsuite/tests/deriving/should_compile/T4966.hs +++ b/testsuite/tests/deriving/should_compile/T4966.hs @@ -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 diff --git a/testsuite/tests/deriving/should_compile/T4966.stderr b/testsuite/tests/deriving/should_compile/T4966.stderr index d5cc4a24b2..dceeaa698f 100644 --- a/testsuite/tests/deriving/should_compile/T4966.stderr +++ b/testsuite/tests/deriving/should_compile/T4966.stderr @@ -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)’ diff --git a/testsuite/tests/generics/Uniplate/GUniplate.hs b/testsuite/tests/generics/Uniplate/GUniplate.hs index 76f387d636..99b0b405a8 100644 --- a/testsuite/tests/generics/Uniplate/GUniplate.hs +++ b/testsuite/tests/generics/Uniplate/GUniplate.hs @@ -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 diff --git a/testsuite/tests/ghci.debugger/scripts/print019.stderr b/testsuite/tests/ghci.debugger/scripts/print019.stderr index e6a9159836..e364f06f03 100644 --- a/testsuite/tests/ghci.debugger/scripts/print019.stderr +++ b/testsuite/tests/ghci.debugger/scripts/print019.stderr @@ -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 diff --git a/testsuite/tests/ghci/prog007/C.hs b/testsuite/tests/ghci/prog007/C.hs index 8273d6bdda..a66d000e8e 100644 --- a/testsuite/tests/ghci/prog007/C.hs +++ b/testsuite/tests/ghci/prog007/C.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE OverlappingInstances #-} - module C where import A diff --git a/testsuite/tests/ghci/scripts/all.T b/testsuite/tests/ghci/scripts/all.T index d1e67ebeca..d5a313a328 100755 --- a/testsuite/tests/ghci/scripts/all.T +++ b/testsuite/tests/ghci/scripts/all.T @@ -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']) diff --git a/testsuite/tests/ghci/scripts/ghci044.script b/testsuite/tests/ghci/scripts/ghci044.script index 7af66bb935..b89ede3768 100644 --- a/testsuite/tests/ghci/scripts/ghci044.script +++ b/testsuite/tests/ghci/scripts/ghci044.script @@ -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 + diff --git a/testsuite/tests/ghci/scripts/ghci044.stderr b/testsuite/tests/ghci/scripts/ghci044.stderr index c319dd1f1c..9bc8df9994 100644 --- a/testsuite/tests/ghci/scripts/ghci044.stderr +++ b/testsuite/tests/ghci/scripts/ghci044.stderr @@ -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 index 0000000000..ac400d3ef9 --- /dev/null +++ b/testsuite/tests/ghci/scripts/ghci044a.hs @@ -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 index 0000000000..d78c5c25bc --- /dev/null +++ b/testsuite/tests/ghci/scripts/ghci044a.script @@ -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 index 0000000000..fe475f4745 --- /dev/null +++ b/testsuite/tests/ghci/scripts/ghci044a.stdout @@ -0,0 +1,2 @@ +"First" +"Second" diff --git a/testsuite/tests/ghci/scripts/ghci047.script b/testsuite/tests/ghci/scripts/ghci047.script index 49d93047f6..70cc5181d8 100644 --- a/testsuite/tests/ghci/scripts/ghci047.script +++ b/testsuite/tests/ghci/scripts/ghci047.script @@ -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 diff --git a/testsuite/tests/indexed-types/should_compile/Gentle.hs b/testsuite/tests/indexed-types/should_compile/Gentle.hs index 6cc1512a1f..7ceedfd098 100644 --- a/testsuite/tests/indexed-types/should_compile/Gentle.hs +++ b/testsuite/tests/indexed-types/should_compile/Gentle.hs @@ -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 diff --git a/testsuite/tests/indexed-types/should_compile/IndTypesPerfMerge.hs b/testsuite/tests/indexed-types/should_compile/IndTypesPerfMerge.hs index dbba60d595..e37bfe323e 100644 --- a/testsuite/tests/indexed-types/should_compile/IndTypesPerfMerge.hs +++ b/testsuite/tests/indexed-types/should_compile/IndTypesPerfMerge.hs @@ -1,5 +1,5 @@ {-# LANGUAGE EmptyDataDecls, TypeFamilies, UndecidableInstances, - ScopedTypeVariables, OverlappingInstances, TypeOperators, + ScopedTypeVariables, TypeOperators, FlexibleInstances, NoMonomorphismRestriction, MultiParamTypeClasses, FlexibleContexts #-} module IndTypesPerfMerge where diff --git a/testsuite/tests/indexed-types/should_compile/NonLinearLHS.hs b/testsuite/tests/indexed-types/should_compile/NonLinearLHS.hs index dc0ae5392a..26ea632a29 100644 --- a/testsuite/tests/indexed-types/should_compile/NonLinearLHS.hs +++ b/testsuite/tests/indexed-types/should_compile/NonLinearLHS.hs @@ -1,6 +1,6 @@ {-# LANGUAGE TypeFamilies, EmptyDataDecls, FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE FlexibleInstances, OverlappingInstances, UndecidableInstances #-} +{-# LANGUAGE FlexibleInstances, UndecidableInstances #-} module NonLinearLHS where diff --git a/testsuite/tests/indexed-types/should_fail/T4246.hs b/testsuite/tests/indexed-types/should_fail/T4246.hs index b5c37a68e3..60b56405ad 100644 --- a/testsuite/tests/indexed-types/should_fail/T4246.hs +++ b/testsuite/tests/indexed-types/should_fail/T4246.hs @@ -1,13 +1,13 @@ -{-# LANGUAGE TypeFamilies, FlexibleInstances, OverlappingInstances #-}
+{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
module T4246 where
class Stupid a where
type F a
-instance Stupid a where
+instance {-# OVERLAPPABLE #-} Stupid a where
type F a = a
-instance Stupid Int where
+instance {-# OVERLAPPING #-} Stupid Int where
type F Int = Bool
type family G a :: *
diff --git a/testsuite/tests/indexed-types/should_fail/T4485.hs b/testsuite/tests/indexed-types/should_fail/T4485.hs index b48e8206f2..d7d4730362 100644 --- a/testsuite/tests/indexed-types/should_fail/T4485.hs +++ b/testsuite/tests/indexed-types/should_fail/T4485.hs @@ -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)]) diff --git a/testsuite/tests/indexed-types/should_fail/T4485.stderr b/testsuite/tests/indexed-types/should_fail/T4485.stderr index b2bd626d20..760cdf912d 100644 --- a/testsuite/tests/indexed-types/should_fail/T4485.stderr +++ b/testsuite/tests/indexed-types/should_fail/T4485.stderr @@ -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’: diff --git a/testsuite/tests/indexed-types/should_fail/T5439.hs b/testsuite/tests/indexed-types/should_fail/T5439.hs index 396a5436c4..dfcd399b4f 100644 --- a/testsuite/tests/indexed-types/should_fail/T5439.hs +++ b/testsuite/tests/indexed-types/should_fail/T5439.hs @@ -9,7 +9,6 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE OverlappingInstances #-} {-# LANGUAGE UndecidableInstances #-} module Main where diff --git a/testsuite/tests/indexed-types/should_fail/T5439.stderr b/testsuite/tests/indexed-types/should_fail/T5439.stderr index 18af3fa7cf..19517cbf57 100644 --- a/testsuite/tests/indexed-types/should_fail/T5439.stderr +++ b/testsuite/tests/indexed-types/should_fail/T5439.stderr @@ -1,26 +1,26 @@ -
-T5439.hs:83: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:65:9)
- ev :: f (Attempt (WaitOpResult (WaitOps rs)))
- (bound at T5439.hs:62:22)
- ops :: WaitOps rs (bound at T5439.hs:62:18)
- registerWaitOp :: WaitOps rs
- -> f (Attempt (WaitOpResult (WaitOps rs))) -> IO Bool
- (bound at T5439.hs:62:3)
- In the first argument of ‘complete’, namely ‘ev’
- In the expression: complete ev
-
-T5439.hs:83: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)’
+ +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)’ diff --git a/testsuite/tests/perf/compiler/T5321FD.hs b/testsuite/tests/perf/compiler/T5321FD.hs index 6e10939837..004f487098 100644 --- a/testsuite/tests/perf/compiler/T5321FD.hs +++ b/testsuite/tests/perf/compiler/T5321FD.hs @@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fcontext-stack=1000 #-} {-# LANGUAGE FlexibleContexts, FlexibleInstances, FunctionalDependencies, - MultiParamTypeClasses, OverlappingInstances, TypeSynonymInstances, + MultiParamTypeClasses, TypeSynonymInstances, TypeOperators, UndecidableInstances, TypeFamilies #-} module T5321FD where diff --git a/testsuite/tests/perf/compiler/T5321Fun.hs b/testsuite/tests/perf/compiler/T5321Fun.hs index efd7db770b..bf70ce5221 100644 --- a/testsuite/tests/perf/compiler/T5321Fun.hs +++ b/testsuite/tests/perf/compiler/T5321Fun.hs @@ -1,7 +1,7 @@ {-# OPTIONS_GHC -fcontext-stack=1000 #-} {-# LANGUAGE FlexibleContexts, FlexibleInstances, FunctionalDependencies, - MultiParamTypeClasses, OverlappingInstances, TypeSynonymInstances, + MultiParamTypeClasses, TypeSynonymInstances, TypeOperators, UndecidableInstances, TypeFamilies #-} module T5321Fun where diff --git a/testsuite/tests/roles/should_compile/T8958.stderr b/testsuite/tests/roles/should_compile/T8958.stderr index d400b9190c..b53df162a8 100644 --- a/testsuite/tests/roles/should_compile/T8958.stderr +++ b/testsuite/tests/roles/should_compile/T8958.stderr @@ -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] diff --git a/testsuite/tests/safeHaskell/ghci/p13.script b/testsuite/tests/safeHaskell/ghci/p13.script index 4e96c844ed..950f95ab67 100644 --- a/testsuite/tests/safeHaskell/ghci/p13.script +++ b/testsuite/tests/safeHaskell/ghci/p13.script @@ -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' diff --git a/testsuite/tests/safeHaskell/ghci/p13.stderr b/testsuite/tests/safeHaskell/ghci/p13.stderr index edf5e1eb91..44f8ff4ac0 100644 --- a/testsuite/tests/safeHaskell/ghci/p13.stderr +++ b/testsuite/tests/safeHaskell/ghci/p13.stderr @@ -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: diff --git a/testsuite/tests/safeHaskell/safeInfered/UnsafeInfered08_A.hs b/testsuite/tests/safeHaskell/safeInfered/UnsafeInfered08_A.hs index 13f22ce3d7..4cd276fafd 100644 --- a/testsuite/tests/safeHaskell/safeInfered/UnsafeInfered08_A.hs +++ b/testsuite/tests/safeHaskell/safeInfered/UnsafeInfered08_A.hs @@ -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? diff --git a/testsuite/tests/safeHaskell/safeLanguage/SafeLang10.stderr b/testsuite/tests/safeHaskell/safeLanguage/SafeLang10.stderr index 83c79da75f..d0c5c68d6a 100644 --- a/testsuite/tests/safeHaskell/safeLanguage/SafeLang10.stderr +++ b/testsuite/tests/safeHaskell/safeLanguage/SafeLang10.stderr @@ -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: diff --git a/testsuite/tests/safeHaskell/safeLanguage/SafeLang10_B.hs b/testsuite/tests/safeHaskell/safeLanguage/SafeLang10_B.hs index 5b9954c12e..d9a8f63f50 100644 --- a/testsuite/tests/safeHaskell/safeLanguage/SafeLang10_B.hs +++ b/testsuite/tests/safeHaskell/safeLanguage/SafeLang10_B.hs @@ -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 diff --git a/testsuite/tests/simplCore/should_compile/T5359b.hs b/testsuite/tests/simplCore/should_compile/T5359b.hs index 6348defdd1..f1ce2091a9 100644 --- a/testsuite/tests/simplCore/should_compile/T5359b.hs +++ b/testsuite/tests/simplCore/should_compile/T5359b.hs @@ -1,5 +1,4 @@ {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE OverlappingInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeOperators #-} diff --git a/testsuite/tests/simplCore/should_compile/T5359b.stderr b/testsuite/tests/simplCore/should_compile/T5359b.stderr index 75dde28fcc..2802476a2d 100644 --- a/testsuite/tests/simplCore/should_compile/T5359b.stderr +++ b/testsuite/tests/simplCore/should_compile/T5359b.stderr @@ -1,3 +1,3 @@ -T5359b.hs:62:1: Warning: +T5359b.hs:61:1: Warning: SPECIALISE pragma on INLINE function probably won't fire: ‘genum’ diff --git a/testsuite/tests/simplCore/should_compile/simpl007.hs b/testsuite/tests/simplCore/should_compile/simpl007.hs index 2b42cc29ee..c7277b7f66 100644 --- a/testsuite/tests/simplCore/should_compile/simpl007.hs +++ b/testsuite/tests/simplCore/should_compile/simpl007.hs @@ -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 diff --git a/testsuite/tests/th/T4135a.hs b/testsuite/tests/th/T4135a.hs index 41549cad40..d78de088a0 100644 --- a/testsuite/tests/th/T4135a.hs +++ b/testsuite/tests/th/T4135a.hs @@ -1,5 +1,5 @@ {-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, TypeFamilies, - FlexibleInstances, OverlappingInstances #-} + FlexibleInstances #-} module T4135a where diff --git a/testsuite/tests/typecheck/should_compile/FD4.hs b/testsuite/tests/typecheck/should_compile/FD4.hs index 5d5869ca01..dcf25f7293 100644 --- a/testsuite/tests/typecheck/should_compile/FD4.hs +++ b/testsuite/tests/typecheck/should_compile/FD4.hs @@ -2,7 +2,6 @@ MultiParamTypeClasses,
FunctionalDependencies,
UndecidableInstances,
- OverlappingInstances,
FlexibleInstances,
EmptyDataDecls #-}
diff --git a/testsuite/tests/typecheck/should_compile/LoopOfTheDay3.hs b/testsuite/tests/typecheck/should_compile/LoopOfTheDay3.hs index dce1601a70..f1c1b49839 100644 --- a/testsuite/tests/typecheck/should_compile/LoopOfTheDay3.hs +++ b/testsuite/tests/typecheck/should_compile/LoopOfTheDay3.hs @@ -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) diff --git a/testsuite/tests/typecheck/should_compile/Makefile b/testsuite/tests/typecheck/should_compile/Makefile index 518f923689..e361556f8f 100644 --- a/testsuite/tests/typecheck/should_compile/Makefile +++ b/testsuite/tests/typecheck/should_compile/Makefile @@ -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 diff --git a/testsuite/tests/typecheck/should_compile/T1470.hs b/testsuite/tests/typecheck/should_compile/T1470.hs index d466e487e9..2482696452 100644 --- a/testsuite/tests/typecheck/should_compile/T1470.hs +++ b/testsuite/tests/typecheck/should_compile/T1470.hs @@ -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] diff --git a/testsuite/tests/typecheck/should_compile/T3018.hs b/testsuite/tests/typecheck/should_compile/T3018.hs index a0868afa24..443d73a17a 100644 --- a/testsuite/tests/typecheck/should_compile/T3018.hs +++ b/testsuite/tests/typecheck/should_compile/T3018.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE OverlappingInstances , UndecidableInstances, EmptyDataDecls #-} +{-# LANGUAGE UndecidableInstances, EmptyDataDecls #-} {-# LANGUAGE RankNTypes, KindSignatures, MultiParamTypeClasses, FlexibleInstances #-} -- Works with new constraint solver diff --git a/testsuite/tests/typecheck/should_compile/T3108.hs b/testsuite/tests/typecheck/should_compile/T3108.hs index 774d5f3801..2adaa1aef7 100644 --- a/testsuite/tests/typecheck/should_compile/T3108.hs +++ b/testsuite/tests/typecheck/should_compile/T3108.hs @@ -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 diff --git a/testsuite/tests/typecheck/should_compile/Tc173a.hs b/testsuite/tests/typecheck/should_compile/Tc173a.hs index c8a589d2b3..f3704ccd9a 100644 --- a/testsuite/tests/typecheck/should_compile/Tc173a.hs +++ b/testsuite/tests/typecheck/should_compile/Tc173a.hs @@ -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) diff --git a/testsuite/tests/typecheck/should_compile/Tc173b.hs b/testsuite/tests/typecheck/should_compile/Tc173b.hs index c98c57acd8..d14663d866 100644 --- a/testsuite/tests/typecheck/should_compile/Tc173b.hs +++ b/testsuite/tests/typecheck/should_compile/Tc173b.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE UndecidableInstances #-} module Tc173b where import Tc173a diff --git a/testsuite/tests/typecheck/should_compile/tc176.hs b/testsuite/tests/typecheck/should_compile/tc176.hs index d05ccdbe29..94fdcb2227 100644 --- a/testsuite/tests/typecheck/should_compile/tc176.hs +++ b/testsuite/tests/typecheck/should_compile/tc176.hs @@ -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 diff --git a/testsuite/tests/typecheck/should_compile/tc179.hs b/testsuite/tests/typecheck/should_compile/tc179.hs index 110950587d..62db4726a0 100644 --- a/testsuite/tests/typecheck/should_compile/tc179.hs +++ b/testsuite/tests/typecheck/should_compile/tc179.hs @@ -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 diff --git a/testsuite/tests/typecheck/should_fail/LongWayOverlapping.hs b/testsuite/tests/typecheck/should_fail/LongWayOverlapping.hs index 4a79e69ed6..663143ceb4 100644 --- a/testsuite/tests/typecheck/should_fail/LongWayOverlapping.hs +++ b/testsuite/tests/typecheck/should_fail/LongWayOverlapping.hs @@ -1,7 +1,6 @@ {-# LANGUAGE TypeFamilies, MultiParamTypeClasses
, FlexibleContexts, FlexibleInstances, UndecidableInstances
, TypeSynonymInstances, GeneralizedNewtypeDeriving
- , OverlappingInstances
#-}
module LongWayOverlapping where
diff --git a/testsuite/tests/typecheck/should_fail/LongWayOverlapping.stderr b/testsuite/tests/typecheck/should_fail/LongWayOverlapping.stderr index 753ee0f2af..f1eb2db530 100644 --- a/testsuite/tests/typecheck/should_fail/LongWayOverlapping.stderr +++ b/testsuite/tests/typecheck/should_fail/LongWayOverlapping.stderr @@ -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' diff --git a/testsuite/tests/typecheck/should_fail/T2307.hs b/testsuite/tests/typecheck/should_fail/T2307.hs index 321c2d5641..ea0c335a96 100644 --- a/testsuite/tests/typecheck/should_fail/T2307.hs +++ b/testsuite/tests/typecheck/should_fail/T2307.hs @@ -1,5 +1,5 @@ {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, - OverlappingInstances, UndecidableInstances, + UndecidableInstances, IncoherentInstances, FlexibleInstances #-} diff --git a/testsuite/tests/typecheck/should_fail/T5051.hs b/testsuite/tests/typecheck/should_fail/T5051.hs index 6c5faf9170..e3278d83d3 100644 --- a/testsuite/tests/typecheck/should_fail/T5051.hs +++ b/testsuite/tests/typecheck/should_fail/T5051.hs @@ -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 diff --git a/testsuite/tests/typecheck/should_fail/T5051.stderr b/testsuite/tests/typecheck/should_fail/T5051.stderr index f6225ea406..3fc46f9e98 100644 --- a/testsuite/tests/typecheck/should_fail/T5051.stderr +++ b/testsuite/tests/typecheck/should_fail/T5051.stderr @@ -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) diff --git a/testsuite/tests/typecheck/should_fail/T5095.hs b/testsuite/tests/typecheck/should_fail/T5095.hs index 80e080802e..7942a87433 100644 --- a/testsuite/tests/typecheck/should_fail/T5095.hs +++ b/testsuite/tests/typecheck/should_fail/T5095.hs @@ -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 diff --git a/testsuite/tests/typecheck/should_fail/T5095.stderr b/testsuite/tests/typecheck/should_fail/T5095.stderr index 614c99cb11..a572c07788 100644 --- a/testsuite/tests/typecheck/should_fail/T5095.stderr +++ b/testsuite/tests/typecheck/should_fail/T5095.stderr @@ -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’ diff --git a/testsuite/tests/typecheck/should_fail/tcfail121.hs b/testsuite/tests/typecheck/should_fail/tcfail121.hs index 86c2a92c5c..84966c4e7e 100644 --- a/testsuite/tests/typecheck/should_fail/tcfail121.hs +++ b/testsuite/tests/typecheck/should_fail/tcfail121.hs @@ -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 diff --git a/testsuite/tests/typecheck/should_fail/tcfail121.stderr b/testsuite/tests/typecheck/should_fail/tcfail121.stderr index bc71d5e79f..dc0679edca 100644 --- a/testsuite/tests/typecheck/should_fail/tcfail121.stderr +++ b/testsuite/tests/typecheck/should_fail/tcfail121.stderr @@ -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) diff --git a/testsuite/tests/typecheck/should_fail/tcfail202.hs b/testsuite/tests/typecheck/should_fail/tcfail202.hs index 7565755218..6878e4ece6 100644 --- a/testsuite/tests/typecheck/should_fail/tcfail202.hs +++ b/testsuite/tests/typecheck/should_fail/tcfail202.hs @@ -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 |