summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorRichard Eisenberg <eir@cis.upenn.edu>2016-04-22 22:28:35 -0400
committerRichard Eisenberg <eir@cis.upenn.edu>2016-06-23 15:17:41 -0400
commit9a34bf1985035858ece043bf38b47b6ff4b88efb (patch)
treeced7886f40cb2f4f690cf062ffa2ba1d0dd02865 /compiler
parent7f5d560377458f3ec328b9fc60a875d9b91e978e (diff)
downloadhaskell-9a34bf1985035858ece043bf38b47b6ff4b88efb.tar.gz
Fix #11974 by adding a more smarts to TcDefaults.
Test cases: typecheck/should_compile/T11974 typecheck/should_fail/T11974b
Diffstat (limited to 'compiler')
-rw-r--r--compiler/prelude/PrelNames.hs12
-rw-r--r--compiler/typecheck/TcDefaults.hs37
-rw-r--r--compiler/typecheck/TcSimplify.hs2
3 files changed, 33 insertions, 18 deletions
diff --git a/compiler/prelude/PrelNames.hs b/compiler/prelude/PrelNames.hs
index 1480851690..5ed31519e9 100644
--- a/compiler/prelude/PrelNames.hs
+++ b/compiler/prelude/PrelNames.hs
@@ -2245,6 +2245,18 @@ derivableClassKeys
= [ eqClassKey, ordClassKey, enumClassKey, ixClassKey,
boundedClassKey, showClassKey, readClassKey ]
+
+-- These are the "interactive classes" that are consulted when doing
+-- defaulting. Does not include Num or IsString, which have special
+-- handling.
+interactiveClassNames :: [Name]
+interactiveClassNames
+ = [ showClassName, eqClassName, ordClassName, foldableClassName
+ , traversableClassName ]
+
+interactiveClassKeys :: [Unique]
+interactiveClassKeys = map getUnique interactiveClassNames
+
{-
************************************************************************
* *
diff --git a/compiler/typecheck/TcDefaults.hs b/compiler/typecheck/TcDefaults.hs
index f45dd633bf..e33b8c53ea 100644
--- a/compiler/typecheck/TcDefaults.hs
+++ b/compiler/typecheck/TcDefaults.hs
@@ -13,12 +13,12 @@ import Class
import TcRnMonad
import TcEnv
import TcHsType
+import TcHsSyn
import TcSimplify
-import TcMType
+import TcValidity
import TcType
import PrelNames
import SrcLoc
-import Data.Maybe
import Outputable
import FastString
import qualified GHC.LanguageExtensions as LangExt
@@ -46,13 +46,18 @@ tcDefaults [L _ (DefaultDecl [])]
tcDefaults [L locn (DefaultDecl mono_tys)]
= setSrcSpan locn $
addErrCtxt defaultDeclCtxt $
- do { ovl_str <- xoptM LangExt.OverloadedStrings
+ do { ovl_str <- xoptM LangExt.OverloadedStrings
+ ; ext_deflt <- xoptM LangExt.ExtendedDefaultRules
; num_class <- tcLookupClass numClassName
- ; is_str_class <- tcLookupClass isStringClassName
- ; let deflt_clss | ovl_str = [num_class, is_str_class]
- | otherwise = [num_class]
+ ; deflt_str <- if ovl_str
+ then mapM tcLookupClass [isStringClassName]
+ else return []
+ ; deflt_interactive <- if ext_deflt
+ then mapM tcLookupClass interactiveClassNames
+ else return []
+ ; let deflt_clss = num_class : deflt_str ++ deflt_interactive
- ; tau_tys <- mapM (tc_default_ty deflt_clss) mono_tys
+ ; tau_tys <- mapAndReportM (tc_default_ty deflt_clss) mono_tys
; return (Just tau_tys) }
@@ -63,10 +68,10 @@ tcDefaults decls@(L locn (DefaultDecl _) : _)
tc_default_ty :: [Class] -> LHsType Name -> TcM Type
tc_default_ty deflt_clss hs_ty
- = do { ty <- solveEqualities $
- tcHsLiftedType hs_ty
- ; ty <- zonkTcType ty -- establish Type invariants
- ; checkTc (isTauTy ty) (polyDefErr hs_ty)
+ = do { (ty, _kind) <- solveEqualities $
+ tcLHsType hs_ty
+ ; ty <- zonkTcTypeToType emptyZonkEnv ty -- establish Type invariants
+ ; checkValidType DefaultDeclCtxt ty
-- Check that the type is an instance of at least one of the deflt_clss
; oks <- mapM (check_instance ty) deflt_clss
@@ -77,8 +82,10 @@ check_instance :: Type -> Class -> TcM Bool
-- Check that ty is an instance of cls
-- We only care about whether it worked or not; return a boolean
check_instance ty cls
- = do { (_, mb_res) <- tryTc (simplifyDefault [mkClassPred cls [ty]])
- ; return (isJust mb_res) }
+ = do { (_, success) <- discardErrs $
+ askNoErrs $
+ simplifyDefault [mkClassPred cls [ty]]
+ ; return success }
defaultDeclCtxt :: SDoc
defaultDeclCtxt = text "When checking the types in a default declaration"
@@ -91,10 +98,6 @@ dupDefaultDeclErr (L _ (DefaultDecl _) : dup_things)
pp (L locn (DefaultDecl _)) = text "here was another default declaration" <+> ppr locn
dupDefaultDeclErr [] = panic "dupDefaultDeclErr []"
-polyDefErr :: LHsType Name -> SDoc
-polyDefErr ty
- = hang (text "Illegal polymorphic type in default declaration" <> colon) 2 (ppr ty)
-
badDefaultTy :: Type -> [Class] -> SDoc
badDefaultTy ty deflt_clss
= hang (text "The default type" <+> quotes (ppr ty) <+> ptext (sLit "is not an instance of"))
diff --git a/compiler/typecheck/TcSimplify.hs b/compiler/typecheck/TcSimplify.hs
index f9a30c2f5a..594cc949b3 100644
--- a/compiler/typecheck/TcSimplify.hs
+++ b/compiler/typecheck/TcSimplify.hs
@@ -427,7 +427,7 @@ simplifyInteractive wanteds
simplifyDefault :: ThetaType -- Wanted; has no type variables in it
-> TcM () -- Succeeds if the constraint is soluble
simplifyDefault theta
- = do { traceTc "simplifyInteractive" empty
+ = do { traceTc "simplifyDefault" empty
; loc <- getCtLocM DefaultOrigin Nothing
; let wanted = [ CtDerived { ctev_pred = pred
, ctev_loc = loc }