X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcDefaults.lhs;h=f3f35d4c9bed904effbd34b1bff26c0d30e25dc6;hp=6c9de36a3c099979b3336f97596373b9c94847b7;hb=c1681a73fa4ca4cf8758264ae387ac09a9e900d8;hpb=0065d5ab628975892cea1ec7303f968c3338cbe1 diff --git a/compiler/typecheck/TcDefaults.lhs b/compiler/typecheck/TcDefaults.lhs index 6c9de36..f3f35d4 100644 --- a/compiler/typecheck/TcDefaults.lhs +++ b/compiler/typecheck/TcDefaults.lhs @@ -1,4 +1,5 @@ % +% (c) The University of Glasgow 2006 % (c) The AQUA Project, Glasgow University, 1993-1998 % \section[TcDefaults]{Typechecking \tr{default} declarations} @@ -8,15 +9,18 @@ module TcDefaults ( tcDefaults ) where #include "HsVersions.h" -import HsSyn ( DefaultDecl(..), LDefaultDecl ) -import Name ( Name ) +import HsSyn +import Name +import Class import TcRnMonad -import TcEnv ( tcLookupClass ) -import TcHsType ( tcHsSigType, UserTypeCtxt( DefaultDeclCtxt ) ) -import TcSimplify ( tcSimplifyDefault ) -import TcType ( Type, mkClassPred, isTauTy ) -import PrelNames ( numClassName ) -import SrcLoc ( Located(..) ) +import TcEnv +import TcHsType +import TcSimplify +import TcType +import PrelNames +import DynFlags +import SrcLoc +import Maybe import Outputable \end{code} @@ -27,7 +31,7 @@ tcDefaults :: [LDefaultDecl Name] -- in Disambig. tcDefaults [] - = getDefaultTys -- No default declaration, so get the + = getDeclaredDefaultTys -- No default declaration, so get the -- default types from the envt; -- i.e. use the curent ones -- (the caller will put them back there) @@ -44,28 +48,38 @@ tcDefaults [L locn (DefaultDecl [])] tcDefaults [L locn (DefaultDecl mono_tys)] = setSrcSpan locn $ addErrCtxt defaultDeclCtxt $ - tcLookupClass numClassName `thenM` \ num_class -> - mappM tc_default_ty mono_tys `thenM` \ tau_tys -> - - -- Check that all the types are instances of Num - -- We only care about whether it worked or not - tcSimplifyDefault [mkClassPred num_class [ty] | ty <- tau_tys] `thenM_` + do { ovl_str <- doptM Opt_OverloadedStrings + ; num_class <- tcLookupClass numClassName + ; is_str_class <- tcLookupClass isStringClassName + ; let deflt_clss | ovl_str = [num_class, is_str_class] + | otherwise = [num_class] + + ; tau_tys <- mappM (tc_default_ty deflt_clss) mono_tys - returnM (Just tau_tys) + ; return (Just tau_tys) } -tcDefaults decls@(L locn (DefaultDecl _) : _) = - setSrcSpan locn $ +tcDefaults decls@(L locn (DefaultDecl _) : _) + = setSrcSpan locn $ failWithTc (dupDefaultDeclErr decls) -tc_default_ty hs_ty - = tcHsSigType DefaultDeclCtxt hs_ty `thenM` \ ty -> - checkTc (isTauTy ty) (polyDefErr hs_ty) `thenM_` - returnM ty +tc_default_ty deflt_clss hs_ty + = do { ty <- tcHsSigType DefaultDeclCtxt hs_ty + ; checkTc (isTauTy ty) (polyDefErr hs_ty) -defaultDeclCtxt = ptext SLIT("when checking that each type in a default declaration") - $$ ptext SLIT("is an instance of class Num") + -- Check that the type is an instance of at least one of the deflt_clss + ; oks <- mapM (check_instance ty) deflt_clss + ; checkTc (or oks) (badDefaultTy ty deflt_clss) + ; return ty } +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 (tcSimplifyDefault [mkClassPred cls [ty]]) + ; return (isJust mb_res) } + +defaultDeclCtxt = ptext SLIT("When checking the types in a default declaration") dupDefaultDeclErr (L _ (DefaultDecl _) : dup_things) = hang (ptext SLIT("Multiple default declarations")) @@ -75,5 +89,9 @@ dupDefaultDeclErr (L _ (DefaultDecl _) : dup_things) polyDefErr ty = hang (ptext SLIT("Illegal polymorphic type in default declaration") <> colon) 4 (ppr ty) + +badDefaultTy ty deflt_clss + = hang (ptext SLIT("The default type") <+> quotes (ppr ty) <+> ptext SLIT("is not an instance of")) + 2 (foldr1 (\a b -> a <+> ptext SLIT("or") <+> b) (map (quotes. ppr) deflt_clss)) \end{code}