Clean up some pretty-printing in errors.
authorRichard Eisenberg <eir@cis.upenn.edu>
Tue, 15 Mar 2016 20:56:51 +0000 (16:56 -0400)
committerRichard Eisenberg <eir@cis.upenn.edu>
Wed, 16 Mar 2016 01:19:21 +0000 (21:19 -0400)
It turns out that there were some pretty egregious mistakes
in the code that suggested -fprint-explicit-kinds, which are
fixed. This commit also reorders a bunch of error messages,
which I think is an improvement.

This also adds the test case for #11471, which is what
triggered the cleanup in TcErrors. Now that #11473 is done,
there is nothing more outstanding for #11471.

test case: dependent/should_fail/T11471

19 files changed:
compiler/typecheck/TcErrors.hs
compiler/typecheck/TcType.hs
testsuite/tests/dependent/should_fail/T11471.hs [new file with mode: 0644]
testsuite/tests/dependent/should_fail/T11471.stderr [new file with mode: 0644]
testsuite/tests/dependent/should_fail/all.T
testsuite/tests/indexed-types/should_fail/NoMatchErr.stderr
testsuite/tests/indexed-types/should_fail/T1897b.stderr
testsuite/tests/indexed-types/should_fail/T1900.stderr
testsuite/tests/indexed-types/should_fail/T2544.stderr
testsuite/tests/indexed-types/should_fail/T2693.stderr
testsuite/tests/indexed-types/should_fail/T4179.stderr
testsuite/tests/indexed-types/should_fail/T7729.stderr
testsuite/tests/indexed-types/should_fail/T7729a.stderr
testsuite/tests/indexed-types/should_fail/T9036.stderr
testsuite/tests/indexed-types/should_fail/T9171.stderr
testsuite/tests/polykinds/T9144.stderr
testsuite/tests/typecheck/should_fail/T8030.stderr
testsuite/tests/typecheck/should_fail/T8034.stderr
testsuite/tests/typecheck/should_fail/T8142.stderr

index 0b0dae4..4b61575 100644 (file)
@@ -1149,7 +1149,7 @@ reportEqErr :: ReportErrCtxt -> Report
             -> Maybe SwapFlag   -- Nothing <=> not sure
             -> TcType -> TcType -> TcM ErrMsg
 reportEqErr ctxt report ct oriented ty1 ty2
-  = mkErrorMsgFromCt ctxt ct (mconcat [misMatch, eqInfo, report])
+  = mkErrorMsgFromCt ctxt ct (mconcat [misMatch, report, eqInfo])
   where misMatch = important $ misMatchOrCND ctxt ct oriented ty1 ty2
         eqInfo = important $ mkEqInfoMsg ct ty1 ty2
 
@@ -1289,12 +1289,19 @@ mkEqInfoMsg ct ty1 ty2
               = snd (mkAmbigMsg False ct)
               | otherwise = empty
 
-    invis_msg | Just vis <- tcEqTypeVis ty1 ty2
+    -- better to check the exp/act types in the CtOrigin than the actual
+    -- mismatched types for suggestion about -fprint-explicit-kinds
+    (act_ty, exp_ty) = case ctOrigin ct of
+      TypeEqOrigin { uo_actual = act
+                   , uo_expected = Check exp } -> (act, exp)
+      _                                        -> (ty1, ty2)
+
+    invis_msg | Just vis <- tcEqTypeVis act_ty exp_ty
               , vis /= Visible
               = sdocWithDynFlags $ \dflags ->
                 if gopt Opt_PrintExplicitKinds dflags
-                then text "Use -fprint-explicit-kinds to see the kind arguments"
-                else empty
+                then empty
+                else text "Use -fprint-explicit-kinds to see the kind arguments"
 
               | otherwise
               = empty
index 40821e5..a9ea60b 100644 (file)
@@ -1326,11 +1326,15 @@ tcEqTypeNoKindCheck ty1 ty2
 -- are 'tcEqType'.
 tcEqTypeVis :: TcType -> TcType -> Maybe VisibilityFlag
 tcEqTypeVis ty1 ty2
-  = tc_eq_type coreView ty1 ty2 <!> tc_eq_type coreView ki1 ki2
+  = tc_eq_type coreView ty1 ty2 <!> invis (tc_eq_type coreView ki1 ki2)
   where
     ki1 = typeKind ty1
     ki2 = typeKind ty2
 
+      -- convert Just Visible to Just Invisible
+    invis :: Maybe VisibilityFlag -> Maybe VisibilityFlag
+    invis = fmap (const Invisible)
+
 (<!>) :: Maybe VisibilityFlag -> Maybe VisibilityFlag -> Maybe VisibilityFlag
 Nothing        <!> x            = x
 Just Visible   <!> _            = Just Visible
@@ -1368,7 +1372,7 @@ tc_eq_type view_fun orig_ty1 orig_ty2 = go Visible orig_env orig_ty1 orig_ty2
       | Just (s1, t1) <- tcRepSplitAppTy_maybe ty1
       = go vis env s1 s2 <!> go vis env t1 t2
     go vis env (TyConApp tc1 ts1)   (TyConApp tc2 ts2)
-      = check vis (tc1 == tc2) <!> gos (tc_vis tc1) env ts1 ts2
+      = check vis (tc1 == tc2) <!> gos (tc_vis vis tc1) env ts1 ts2
     go vis env (CastTy t1 _)        t2              = go vis env t1 t2
     go vis env t1                   (CastTy t2 _)   = go vis env t1 t2
     go _   _   (CoercionTy {})      (CoercionTy {}) = Nothing
@@ -1379,13 +1383,15 @@ tc_eq_type view_fun orig_ty1 orig_ty2 = go Visible orig_env orig_ty1 orig_ty2
     gos (v:_)  _   _        _        = Just v
     gos _      _   _        _        = panic "tc_eq_type"
 
-    tc_vis :: TyCon -> [VisibilityFlag]
-    tc_vis tc = viss ++ repeat Visible
+    tc_vis :: VisibilityFlag -> TyCon -> [VisibilityFlag]
+    tc_vis Visible tc = viss ++ repeat Visible
        -- the repeat Visible is necessary because tycons can legitimately
        -- be oversaturated
       where
         bndrs = tyConBinders tc
         viss  = map binderVisibility bndrs
+    tc_vis vis _ = repeat vis   -- if we're not in a visible context, our args
+                                -- aren't either
 
     check :: VisibilityFlag -> Bool -> Maybe VisibilityFlag
     check _   True  = Nothing
diff --git a/testsuite/tests/dependent/should_fail/T11471.hs b/testsuite/tests/dependent/should_fail/T11471.hs
new file mode 100644 (file)
index 0000000..19025db
--- /dev/null
@@ -0,0 +1,15 @@
+{-# LANGUAGE MagicHash, PolyKinds, TypeFamilies #-}
+
+module T11471 where
+
+import GHC.Exts
+import Data.Proxy
+
+type family F a :: k
+
+type instance F Int = Int#
+
+f :: Proxy a -> F a -> F a
+f _ x = x
+
+bad = f (undefined :: Proxy Int#) 3#
diff --git a/testsuite/tests/dependent/should_fail/T11471.stderr b/testsuite/tests/dependent/should_fail/T11471.stderr
new file mode 100644 (file)
index 0000000..0578910
--- /dev/null
@@ -0,0 +1,18 @@
+
+T11471.hs:15:10: error:
+    • Couldn't match a lifted type with an unlifted type
+      Expected type: Proxy Int#
+        Actual type: Proxy Int#
+      Use -fprint-explicit-kinds to see the kind arguments
+    • In the first argument of ‘f’, namely ‘(undefined :: Proxy Int#)’
+      In the expression: f (undefined :: Proxy Int#) 3#
+      In an equation for ‘bad’: bad = f (undefined :: Proxy Int#) 3#
+
+T11471.hs:15:35: error:
+    • Couldn't match a lifted type with an unlifted type
+      When matching types
+        F Int# :: *
+        Int# :: TYPE 'IntRep
+    • In the second argument of ‘f’, namely ‘3#’
+      In the expression: f (undefined :: Proxy Int#) 3#
+      In an equation for ‘bad’: bad = f (undefined :: Proxy Int#) 3#
index c75a9c6..9565bc0 100644 (file)
@@ -13,3 +13,4 @@ test('T11334', normal, compile_fail, [''])
 test('InferDependency', normal, compile_fail, [''])
 test('KindLevelsB', normal, compile_fail, [''])
 test('T11473', normal, compile_fail, [''])
+test('T11471', normal, compile_fail, [''])
index 8afd375..7a553f3 100644 (file)
@@ -1,10 +1,10 @@
 
 NoMatchErr.hs:19:7: error:
     • Couldn't match type ‘Memo d0’ with ‘Memo d’
-      NB: ‘Memo’ is a type function, and may not be injective
-      The type variable ‘d0’ is ambiguous
       Expected type: Memo d a -> Memo d a
         Actual type: Memo d0 a -> Memo d0 a
+      NB: ‘Memo’ is a type function, and may not be injective
+      The type variable ‘d0’ is ambiguous
     • In the ambiguity check for ‘f’
       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
       In the type signature:
index e70a256..b83c7ff 100644 (file)
@@ -1,10 +1,10 @@
 
 T1897b.hs:16:1: error:
     • Couldn't match type ‘Depend a’ with ‘Depend a0’
-      NB: ‘Depend’ is a type function, and may not be injective
-      The type variable ‘a0’ is ambiguous
       Expected type: t (Depend a) -> Bool
         Actual type: t (Depend a0) -> Bool
+      NB: ‘Depend’ is a type function, and may not be injective
+      The type variable ‘a0’ is ambiguous
     • In the ambiguity check for the inferred type for ‘isValid’
       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
       When checking the inferred type
index dbcbddc..0783a2d 100644 (file)
@@ -1,10 +1,10 @@
 
 T1900.hs:7:3: error:
     • Couldn't match type ‘Depend s0’ with ‘Depend s’
-      NB: ‘Depend’ is a type function, and may not be injective
-      The type variable ‘s0’ is ambiguous
       Expected type: Depend s -> Depend s
         Actual type: Depend s0 -> Depend s0
+      NB: ‘Depend’ is a type function, and may not be injective
+      The type variable ‘s0’ is ambiguous
     • In the ambiguity check for ‘trans’
       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
       When checking the class method:
index a296a36..6375c8f 100644 (file)
@@ -1,10 +1,10 @@
 
 T2544.hs:17:18: error:
     • Couldn't match type ‘IxMap i0’ with ‘IxMap l’
-      NB: ‘IxMap’ is a type function, and may not be injective
-      The type variable ‘i0’ is ambiguous
       Expected type: IxMap l [Int]
         Actual type: IxMap i0 [Int]
+      NB: ‘IxMap’ is a type function, and may not be injective
+      The type variable ‘i0’ is ambiguous
     • In the first argument of ‘BiApp’, namely ‘empty’
       In the expression: BiApp empty empty
       In an equation for ‘empty’: empty = BiApp empty empty
@@ -13,10 +13,10 @@ T2544.hs:17:18: error:
 
 T2544.hs:17:24: error:
     • Couldn't match type ‘IxMap i1’ with ‘IxMap r’
-      NB: ‘IxMap’ is a type function, and may not be injective
-      The type variable ‘i1’ is ambiguous
       Expected type: IxMap r [Int]
         Actual type: IxMap i1 [Int]
+      NB: ‘IxMap’ is a type function, and may not be injective
+      The type variable ‘i1’ is ambiguous
     • In the second argument of ‘BiApp’, namely ‘empty’
       In the expression: BiApp empty empty
       In an equation for ‘empty’: empty = BiApp empty empty
index b41e19f..5e925c3 100644 (file)
@@ -33,9 +33,9 @@ T2693.hs:19:23: error:
 
 T2693.hs:30:47: error:
     • Couldn't match type ‘TFn a0’ with ‘PVR a1’
-      The type variables ‘a0’, ‘a1’ are ambiguous
       Expected type: [PVR a1]
         Actual type: [TFn a0]
+      The type variables ‘a0’, ‘a1’ are ambiguous
     • In the second argument of ‘map’, namely ‘pvs’
       In the second argument of ‘min’, namely ‘(map pvrX pvs)’
       In the expression: (map pvrX pvs) `min` (map pvrX pvs)
index 0dfa2db..f3411a0 100644 (file)
@@ -2,7 +2,6 @@
 T4179.hs:26:16: error:
     • Couldn't match type ‘A2 (x (A2 (FCon x) -> A3 (FCon x)))’
                      with ‘A2 (FCon x)’
-      NB: ‘A2’ is a type function, and may not be injective
       Expected type: x (A2 (x (A2 (FCon x) -> A3 (FCon x)))
                         -> A3 (x (A2 (FCon x) -> A3 (FCon x))))
                      -> A2 (x (A2 (FCon x) -> A3 (FCon x)))
@@ -10,6 +9,7 @@ T4179.hs:26:16: error:
         Actual type: x (A2 (FCon x) -> A3 (FCon x))
                      -> A2 (x (A2 (FCon x) -> A3 (FCon x)))
                      -> A3 (x (A2 (FCon x) -> A3 (FCon x)))
+      NB: ‘A2’ is a type function, and may not be injective
     • In the first argument of ‘foldDoC’, namely ‘op’
       In the expression: foldDoC op
       In an equation for ‘fCon’: fCon = foldDoC op
index aa71a97..80b6fd8 100644 (file)
@@ -1,9 +1,9 @@
 
 T7729.hs:36:25: error:
     • Couldn't match type ‘BasePrimMonad m’ with ‘t0 (BasePrimMonad m)’
-      The type variable ‘t0’ is ambiguous
       Expected type: BasePrimMonad m a -> BasePrimMonad (Rand m) a
         Actual type: BasePrimMonad m a -> t0 (BasePrimMonad m) a
+      The type variable ‘t0’ is ambiguous
     • In the second argument of ‘(.)’, namely ‘lift’
       In the expression: liftPrim . lift
       In an equation for ‘liftPrim’: liftPrim = liftPrim . lift
index 513a132..e5a6289 100644 (file)
@@ -1,9 +1,9 @@
 
 T7729a.hs:36:26: error:
     • Couldn't match type ‘BasePrimMonad m’ with ‘t0 (BasePrimMonad m)’
-      The type variable ‘t0’ is ambiguous
       Expected type: BasePrimMonad (Rand m) a
         Actual type: t0 (BasePrimMonad m) a
+      The type variable ‘t0’ is ambiguous
     • In the first argument of ‘liftPrim’, namely ‘(lift x)’
       In the expression: liftPrim (lift x)
       In an equation for ‘liftPrim’: liftPrim x = liftPrim (lift x)
index 3d768de..cb12dea 100644 (file)
@@ -1,10 +1,10 @@
 
 T9036.hs:17:17: error:
     • Couldn't match type ‘Curried t0 [t0]’ with ‘Curried t [t]’
-      NB: ‘Curried’ is a type function, and may not be injective
-      The type variable ‘t0’ is ambiguous
       Expected type: Maybe (GetMonad t after) -> Curried t [t]
         Actual type: Maybe (GetMonad t0 after) -> Curried t0 [t0]
+      NB: ‘Curried’ is a type function, and may not be injective
+      The type variable ‘t0’ is ambiguous
     • In the ambiguity check for ‘simpleLogger’
       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
       In the type signature:
index 5ffb87b..db44dd7 100644 (file)
@@ -4,6 +4,7 @@ T9171.hs:10:20: error:
                   with actual type ‘GetParam Base (GetParam Base Int)’
       NB: ‘GetParam’ is a type function, and may not be injective
       The type variable ‘k20’ is ambiguous
+      Use -fprint-explicit-kinds to see the kind arguments
     • In the ambiguity check for an expression type signature
       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
       In an expression type signature: GetParam Base (GetParam Base Int)
index b62d1f1..5db0260 100644 (file)
@@ -3,6 +3,7 @@ T9144.hs:34:26: error:
     • Couldn't match type ‘Integer’ with ‘FooTerm’
       Expected type: DemoteRep 'KProxy
         Actual type: DemoteRep 'KProxy
+      Use -fprint-explicit-kinds to see the kind arguments
     • In the first argument of ‘toSing’, namely ‘n’
       In the expression: toSing n
       In the expression:
index 6e902a4..d9c34cd 100644 (file)
@@ -11,10 +11,10 @@ T8030.hs:9:3: error:
 
 T8030.hs:10:3: error:
     • Couldn't match type ‘Pr a0’ with ‘Pr a’
+      Expected type: Pr a -> Pr a -> Pr a
+        Actual type: Pr a0 -> Pr a0 -> Pr a0
       NB: ‘Pr’ is a type function, and may not be injective
       The type variable ‘a0’ is ambiguous
-      Expected type: Pr a -> Pr a -> Pr a
-      Actual type: Pr a0 -> Pr a0 -> Pr a0
     • In the ambiguity check for ‘op2’
       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
       When checking the class method:
index 1a2b1f7..247732a 100644 (file)
@@ -1,10 +1,10 @@
 
 T8034.hs:6:3: error:
     • Couldn't match type ‘F a0’ with ‘F a’
-      NB: ‘F’ is a type function, and may not be injective
-      The type variable ‘a0’ is ambiguous
       Expected type: F a -> F a
         Actual type: F a0 -> F a0
+      NB: ‘F’ is a type function, and may not be injective
+      The type variable ‘a0’ is ambiguous
     • In the ambiguity check for ‘foo’
       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
       When checking the class method: foo :: forall a. C a => F a -> F a
index 09a2a96..3faa530 100644 (file)
@@ -1,10 +1,10 @@
 
 T8142.hs:6:18: error:
     • Couldn't match type ‘Nu g0’ with ‘Nu g’
-      NB: ‘Nu’ is a type function, and may not be injective
-      The type variable ‘g0’ is ambiguous
       Expected type: Nu ((,) t) -> Nu g
         Actual type: Nu ((,) t0) -> Nu g0
+      NB: ‘Nu’ is a type function, and may not be injective
+      The type variable ‘g0’ is ambiguous
     • In the ambiguity check for the inferred type for ‘h’
       To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
       When checking the inferred type