[commit: ghc] master: Improve error message for a handwritten Typeable instance (6d1ac96)
git at git.haskell.org
git at git.haskell.org
Tue Nov 4 10:38:49 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/6d1ac963d87b83f1cac85c18729cfbc29c390383/ghc
>---------------------------------------------------------------
commit 6d1ac963d87b83f1cac85c18729cfbc29c390383
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date: Thu Oct 30 16:33:34 2014 +0000
Improve error message for a handwritten Typeable instance
>---------------------------------------------------------------
6d1ac963d87b83f1cac85c18729cfbc29c390383
compiler/typecheck/TcInstDcls.lhs | 42 ++++++++++++----------
testsuite/tests/deriving/should_fail/T9687.hs | 4 +++
testsuite/tests/deriving/should_fail/T9687.stderr | 5 +++
.../should_fail/T9730.stderr} | 0
testsuite/tests/deriving/should_fail/all.T | 1 +
5 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/compiler/typecheck/TcInstDcls.lhs b/compiler/typecheck/TcInstDcls.lhs
index 10bc466..d22938e 100644
--- a/compiler/typecheck/TcInstDcls.lhs
+++ b/compiler/typecheck/TcInstDcls.lhs
@@ -61,7 +61,7 @@ import BooleanFormula ( isUnsatisfied, pprBooleanFormulaNice )
import Control.Monad
import Maybes ( isNothing, isJust, whenIsJust )
-import Data.List ( mapAccumL )
+import Data.List ( mapAccumL, partition )
\end{code}
Typechecking instance declarations is done in two passes. The first
@@ -378,7 +378,8 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
local_infos' = concat local_infos_s
-- Handwritten instances of the poly-kinded Typeable class are
-- forbidden, so we handle those separately
- (typeable_instances, local_infos) = splitTypeable env local_infos'
+ (typeable_instances, local_infos)
+ = partition (bad_typeable_instance env) local_infos'
; addClsInsts local_infos $
addFamInsts fam_insts $
@@ -400,7 +401,7 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
else tcDeriving tycl_decls inst_decls deriv_decls
-- Fail if there are any handwritten instance of poly-kinded Typeable
- ; mapM_ (failWithTc . instMsg) typeable_instances
+ ; mapM_ typeable_err typeable_instances
-- Check that if the module is compiled with -XSafe, there are no
-- hand written instances of old Typeable as then unsafe casts could be
@@ -422,18 +423,14 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
}}
where
-- Separate the Typeable instances from the rest
- splitTypeable _ [] = ([],[])
- splitTypeable env (i:is) =
- let (typeableInsts, otherInsts) = splitTypeable env is
- in if -- We will filter out instances of Typeable
- (typeableClassName == is_cls_nm (iSpec i))
- -- but not those that come from Data.Typeable.Internal
- && tcg_mod env /= tYPEABLE_INTERNAL
- -- nor those from an .hs-boot or .hsig file
- -- (deriving can't be used there)
- && not (isHsBootOrSig (tcg_src env))
- then (i:typeableInsts, otherInsts)
- else (typeableInsts, i:otherInsts)
+ bad_typeable_instance env i
+ = -- Class name is Typeable
+ typeableClassName == is_cls_nm (iSpec i)
+ -- but not those that come from Data.Typeable.Internal
+ && tcg_mod env /= tYPEABLE_INTERNAL
+ -- nor those from an .hs-boot or .hsig file
+ -- (deriving can't be used there)
+ && not (isHsBootOrSig (tcg_src env))
overlapCheck ty = overlapMode (is_flag $ iSpec ty) `elem`
[Overlappable, Overlapping, Overlaps]
@@ -443,9 +440,18 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls
ptext (sLit "Replace the following instance:"))
2 (pprInstanceHdr (iSpec i))
- instMsg i = hang (ptext (sLit $ "Typeable instances can only be derived; replace "
- ++ "the following instance:"))
- 2 (pprInstance (iSpec i))
+ typeable_err i
+ = setSrcSpan (getSrcSpan ispec) $
+ addErrTc $ hang (ptext (sLit "Typeable instances can only be derived"))
+ 2 (vcat [ ptext (sLit "Try") <+> quotes (ptext (sLit "deriving instance Typeable")
+ <+> pp_tc)
+ , ptext (sLit "(requires StandaloneDeriving)") ])
+ where
+ ispec = iSpec i
+ pp_tc | [_kind, ty] <- is_tys ispec
+ , Just (tc,_) <- tcSplitTyConApp_maybe ty
+ = ppr tc
+ | otherwise = ptext (sLit "<tycon>")
addClsInsts :: [InstInfo Name] -> TcM a -> TcM a
addClsInsts infos thing_inside
diff --git a/testsuite/tests/deriving/should_fail/T9687.hs b/testsuite/tests/deriving/should_fail/T9687.hs
new file mode 100644
index 0000000..818878b
--- /dev/null
+++ b/testsuite/tests/deriving/should_fail/T9687.hs
@@ -0,0 +1,4 @@
+module T9687 where
+import Data.Typeable
+
+instance Typeable (a,b,c,d,e,f,g,h)
diff --git a/testsuite/tests/deriving/should_fail/T9687.stderr b/testsuite/tests/deriving/should_fail/T9687.stderr
new file mode 100644
index 0000000..10619a6
--- /dev/null
+++ b/testsuite/tests/deriving/should_fail/T9687.stderr
@@ -0,0 +1,5 @@
+
+T9687.hs:4:10:
+ Typeable instances can only be derived
+ Try ‘deriving instance Typeable (,,,,,,,)’
+ (requires StandaloneDeriving)
diff --git a/testsuite/tests/deSugar/should_run/T5472.stdout b/testsuite/tests/deriving/should_fail/T9730.stderr
similarity index 100%
copy from testsuite/tests/deSugar/should_run/T5472.stdout
copy to testsuite/tests/deriving/should_fail/T9730.stderr
diff --git a/testsuite/tests/deriving/should_fail/all.T b/testsuite/tests/deriving/should_fail/all.T
index 7700d62..54a6f95 100644
--- a/testsuite/tests/deriving/should_fail/all.T
+++ b/testsuite/tests/deriving/should_fail/all.T
@@ -51,4 +51,5 @@ test('T6147', normal, compile_fail, [''])
test('T8851', normal, compile_fail, [''])
test('T9071', normal, multimod_compile_fail, ['T9071',''])
test('T9071_2', normal, compile_fail, [''])
+test('T9687', normal, compile_fail, [''])
More information about the ghc-commits
mailing list