X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcDefaults.lhs;h=9da5d96fb550ac47c596a09878745dcfe5fd6950;hb=996489295947877c5b2d6129e5d61043887391d9;hp=f4d3b6db3a460db6503742abd247e3535048b176;hpb=90dc9026b091be5cca5da4c6cbd3713ecc493361;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcDefaults.lhs b/compiler/typecheck/TcDefaults.lhs index f4d3b6d..9da5d96 100644 --- a/compiler/typecheck/TcDefaults.lhs +++ b/compiler/typecheck/TcDefaults.lhs @@ -5,19 +5,29 @@ \section[TcDefaults]{Typechecking \tr{default} declarations} \begin{code} +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module TcDefaults ( tcDefaults ) where #include "HsVersions.h" import HsSyn import Name +import Class import TcRnMonad import TcEnv import TcHsType import TcSimplify import TcType import PrelNames +import DynFlags import SrcLoc +import Maybe import Outputable \end{code} @@ -28,7 +38,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) @@ -40,34 +50,43 @@ tcDefaults [] -- defaultDefaultTys tcDefaults [L locn (DefaultDecl [])] - = returnM (Just []) -- Default declaration specifying no types + = return (Just []) -- Default declaration specifying no types tcDefaults [L locn (DefaultDecl mono_tys)] = setSrcSpan locn $ addErrCtxt defaultDeclCtxt $ - tcLookupClass numClassName `thenM` \ num_class -> - tcLookupClass isStringClassName `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 <- mapM (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")) @@ -77,5 +96,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}