diff options
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 |