X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypes%2FInstEnv.lhs;h=07f68f7b91ce91c6c271b201f7fdce8ddcb20027;hp=2d6a9eb215346b64574ccee53d5578e3ed046145;hb=16b9e80dc14db24509f051f294b5b51943285090;hpb=a3bab0506498db41853543558c52a4fda0d183af diff --git a/compiler/types/InstEnv.lhs b/compiler/types/InstEnv.lhs index 2d6a9eb..07f68f7 100644 --- a/compiler/types/InstEnv.lhs +++ b/compiler/types/InstEnv.lhs @@ -128,7 +128,7 @@ setInstanceDFunId ispec dfun -- are ok; hence the assert ispec { is_dfun = dfun, is_tvs = mkVarSet tvs, is_tys = tys } where - (tvs, _, tys) = tcSplitDFunTy (idType dfun) + (tvs, _, _, tys) = tcSplitDFunTy (idType dfun) instanceRoughTcs :: Instance -> [Maybe Name] instanceRoughTcs = is_tcs @@ -166,11 +166,14 @@ pprInstances :: [Instance] -> SDoc pprInstances ispecs = vcat (map pprInstance ispecs) instanceHead :: Instance -> ([TyVar], ThetaType, Class, [Type]) -instanceHead ispec - = (tvs, theta, cls, tys) +-- Returns the *source* theta, without the silent arguments +instanceHead ispec + = (tvs, drop n_silent theta, cls, tys) where - (tvs, theta, tau) = tcSplitSigmaTy (idType (is_dfun ispec)) - (cls, tys) = tcSplitDFunHead tau + (tvs, theta, tau) = tcSplitSigmaTy (idType dfun) + (cls, tys) = tcSplitDFunHead tau + dfun = is_dfun ispec + n_silent = dfunNSilent dfun mkLocalInstance :: DFunId -> OverlapFlag @@ -181,7 +184,7 @@ mkLocalInstance dfun oflag is_tvs = mkVarSet tvs, is_tys = tys, is_cls = className cls, is_tcs = roughMatchTcs tys } where - (tvs, cls, tys) = tcSplitDFunTy (idType dfun) + (tvs, _, cls, tys) = tcSplitDFunTy (idType dfun) mkImportedInstance :: Name -> [Maybe Name] -> DFunId -> OverlapFlag -> Instance @@ -192,7 +195,7 @@ mkImportedInstance cls mb_tcs dfun oflag is_tvs = mkVarSet tvs, is_tys = tys, is_cls = cls, is_tcs = mb_tcs } where - (tvs, _, tys) = tcSplitDFunTy (idType dfun) + (tvs, _, _, tys) = tcSplitDFunTy (idType dfun) roughMatchTcs :: [Type] -> [Maybe Name] roughMatchTcs tys = map rough tys @@ -496,7 +499,7 @@ lookupInstEnv (pkg_ie, home_ie) cls tys find ((item, map (lookup_tv subst) dfun_tvs) : ms) us rest -- Does not match, so next check whether the things unify - -- See Note [overlapping instances] above + -- See Note [Overlapping instances] above | Incoherent <- oflag = find ms us rest @@ -530,14 +533,18 @@ insert_overlapping new_item (item:items) old_beats_new = item `beats` new_item (instA, _) `beats` (instB, _) - = overlap_ok && - isJust (tcMatchTys (is_tvs instB) (is_tys instB) (is_tys instA)) - -- A beats B if A is more specific than B, and B admits overlap - -- I.e. if B can be instantiated to match A - where - overlap_ok = case is_flag instB of - NoOverlap -> False - _ -> True + = overlap_ok && + isJust (tcMatchTys (is_tvs instB) (is_tys instB) (is_tys instA)) + -- A beats B if A is more specific than B, + -- (ie. if B can be instantiated to match A) + -- and overlap is permitted + where + -- Overlap permitted if *either* instance permits overlap + -- This is a change (Trac #3877, Dec 10). It used to + -- require that instB (the less specific one) permitted overlap. + overlap_ok = case (is_flag instA, is_flag instB) of + (NoOverlap, NoOverlap) -> False + _ -> True \end{code}