add -fsimpleopt-before-flatten
[ghc-hetmet.git] / compiler / types / InstEnv.lhs
index 2d6a9eb..07f68f7 100644 (file)
@@ -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}