[commit: ghc] ghc-8.6: Stop marking soluble ~R# constraints as insoluble (09abd1c)

git at git.haskell.org git at git.haskell.org
Tue Jul 31 20:34:50 UTC 2018


Repository : ssh://git@git.haskell.org/ghc

On branch  : ghc-8.6
Link       : http://ghc.haskell.org/trac/ghc/changeset/09abd1c420532c4274ddaeb5dfa54d7a9123d172/ghc

>---------------------------------------------------------------

commit 09abd1c420532c4274ddaeb5dfa54d7a9123d172
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Mon Jul 23 15:33:13 2018 +0100

    Stop marking soluble ~R# constraints as insoluble
    
    We had a constraint (a b ~R# Int), and were marking it as 'insoluble'.
    That's bad; it isn't.  And it caused Trac #15431. Soultion is simple.
    
    I did a tiny refactor on can_eq_app, so that it is used only for
    nominal equalities.
    
    (cherry picked from commit f0d27f515ffbc476144d1d1dd1a71bf9fa93c94b)


>---------------------------------------------------------------

09abd1c420532c4274ddaeb5dfa54d7a9123d172
 compiler/typecheck/TcCanonical.hs                  | 39 +++++++++++++---------
 testsuite/tests/typecheck/should_compile/T15431.hs | 15 +++++++++
 .../tests/typecheck/should_compile/T15431a.hs      | 12 +++++++
 testsuite/tests/typecheck/should_compile/all.T     |  2 ++
 4 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/compiler/typecheck/TcCanonical.hs b/compiler/typecheck/TcCanonical.hs
index a8fff6b..188065f 100644
--- a/compiler/typecheck/TcCanonical.hs
+++ b/compiler/typecheck/TcCanonical.hs
@@ -894,11 +894,13 @@ can_eq_nc' _flat _rdr_env _envs ev eq_rel
 
 -- See Note [Canonicalising type applications] about why we require flat types
 can_eq_nc' True _rdr_env _envs ev eq_rel (AppTy t1 s1) _ ty2 _
-  | Just (t2, s2) <- tcSplitAppTy_maybe ty2
-  = can_eq_app ev eq_rel t1 s1 t2 s2
+  | NomEq <- eq_rel
+  , Just (t2, s2) <- tcSplitAppTy_maybe ty2
+  = can_eq_app ev t1 s1 t2 s2
 can_eq_nc' True _rdr_env _envs ev eq_rel ty1 _ (AppTy t2 s2) _
-  | Just (t1, s1) <- tcSplitAppTy_maybe ty1
-  = can_eq_app ev eq_rel t1 s1 t2 s2
+  | NomEq <- eq_rel
+  , Just (t1, s1) <- tcSplitAppTy_maybe ty1
+  = can_eq_app ev t1 s1 t2 s2
 
 -- No similarity in type structure detected. Flatten and try again.
 can_eq_nc' False rdr_env envs ev eq_rel _ ps_ty1 _ ps_ty2
@@ -908,9 +910,22 @@ can_eq_nc' False rdr_env envs ev eq_rel _ ps_ty1 _ ps_ty2
        ; can_eq_nc' True rdr_env envs new_ev eq_rel xi1 xi1 xi2 xi2 }
 
 -- We've flattened and the types don't match. Give up.
-can_eq_nc' True _rdr_env _envs ev _eq_rel _ ps_ty1 _ ps_ty2
+can_eq_nc' True _rdr_env _envs ev eq_rel _ ps_ty1 _ ps_ty2
   = do { traceTcS "can_eq_nc' catch-all case" (ppr ps_ty1 $$ ppr ps_ty2)
-       ; canEqHardFailure ev ps_ty1 ps_ty2 }
+       ; case eq_rel of -- See Note [Unsolved equalities]
+            ReprEq -> continueWith (mkIrredCt ev)
+            NomEq  -> continueWith (mkInsolubleCt ev) }
+          -- No need to call canEqFailure/canEqHardFailure because they
+          -- flatten, and the types involved here are already flat
+
+{- Note [Unsolved equalities]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If we have an unsolved equality like
+  (a b ~R# Int)
+that is not necessarily insoluble!  Maybe 'a' will turn out to be a newtype.
+So we want to make it a potentially-soluble Irred not an insoluble one.
+Missing this point is what caused Trac #15431
+-}
 
 ---------------------------------
 can_eq_nc_forall :: CtEvidence -> EqRel
@@ -1220,8 +1235,8 @@ can_eq_newtype_nc ev swapped ty1 ((gres, co), ty1') ty2 ps_ty2
 ---------
 -- ^ Decompose a type application.
 -- All input types must be flat. See Note [Canonicalising type applications]
-can_eq_app :: CtEvidence       -- :: s1 t1 ~r s2 t2
-           -> EqRel            -- r
+-- Nominal equality only!
+can_eq_app :: CtEvidence       -- :: s1 t1 ~N s2 t2
            -> Xi -> Xi         -- s1 t1
            -> Xi -> Xi         -- s2 t2
            -> TcS (StopOrContinue Ct)
@@ -1229,13 +1244,7 @@ can_eq_app :: CtEvidence       -- :: s1 t1 ~r s2 t2
 -- AppTys only decompose for nominal equality, so this case just leads
 -- to an irreducible constraint; see typecheck/should_compile/T10494
 -- See Note [Decomposing equality], note {4}
-can_eq_app ev ReprEq _ _ _ _
-  = do { traceTcS "failing to decompose representational AppTy equality" (ppr ev)
-       ; continueWith (mkIrredCt ev) }
-          -- no need to call canEqFailure, because that flattens, and the
-          -- types involved here are already flat
-
-can_eq_app ev NomEq s1 t1 s2 t2
+can_eq_app ev s1 t1 s2 t2
   | CtDerived { ctev_loc = loc } <- ev
   = do { unifyDeriveds loc [Nominal, Nominal] [s1, t1] [s2, t2]
        ; stopWith ev "Decomposed [D] AppTy" }
diff --git a/testsuite/tests/typecheck/should_compile/T15431.hs b/testsuite/tests/typecheck/should_compile/T15431.hs
new file mode 100644
index 0000000..21fa4c4
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T15431.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE GADTs, FlexibleContexts #-}
+
+module T15431 where
+
+import Data.Coerce
+
+data T t where
+  A :: Show (t a) => t a -> T t
+  B :: Coercible Int (t a) => t a -> T t
+
+f :: T t -> String
+f (A t) = show t
+
+g :: T t -> Int
+g (B t) = coerce t
diff --git a/testsuite/tests/typecheck/should_compile/T15431a.hs b/testsuite/tests/typecheck/should_compile/T15431a.hs
new file mode 100644
index 0000000..cf5a831
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T15431a.hs
@@ -0,0 +1,12 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE GADTs #-}
+module T15431a where
+
+import Data.Coerce
+import Data.Functor.Identity
+
+g1 :: Coercible (t a) Int => t a -> Int
+g1 = coerce
+
+g2 :: Coercible Int (t a) => t a -> Int
+g2 = coerce
diff --git a/testsuite/tests/typecheck/should_compile/all.T b/testsuite/tests/typecheck/should_compile/all.T
index 1124247..4bf7fa0 100644
--- a/testsuite/tests/typecheck/should_compile/all.T
+++ b/testsuite/tests/typecheck/should_compile/all.T
@@ -642,3 +642,5 @@ def onlyHsParLocs(x):
     return '\n'.join(filteredLines)
 test('T15242', normalise_errmsg_fun(onlyHsParLocs), compile, [''])
 test('T15428', normal, compile, [''])
+test('T15431', normal, compile, [''])
+test('T15431a', normal, compile, [''])



More information about the ghc-commits mailing list