listNF_Tc, mapAndUnzipNF_Tc, mapBagNF_Tc,
checkTc, checkTcM, checkMaybeTc, checkMaybeTcM,
- failTc, warnTc, recoverTc, recoverNF_Tc,
+ failTc, warnTc, recoverTc, checkNoErrsTc, recoverNF_Tc, discardErrsTc,
tcGetEnv, tcSetEnv,
tcGetDefaultTys, tcSetDefaultTys,
-- For closure
SYN_IE(MutableVar),
-#if __GLASGOW_HASKELL__ >= 200
+#if __GLASGOW_HASKELL__ == 201
GHCbase.MutableArray
+#elif __GLASGOW_HASKELL__ == 201
+ GlaExts.MutableArray
#else
_MutableArray
#endif
IMP_Ubiq(){-uitous-}
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 201
IMPORT_DELOOPER(TcMLoop) ( TcEnv, initEnv, TcMaybe ) -- We need the type TcEnv and an initial Env
+#else
+import {-# SOURCE #-} TcEnv ( TcEnv, initEnv )
+import {-# SOURCE #-} TcType ( TcMaybe, TcTyVarSet )
+#endif
import Type ( SYN_IE(Type), GenType )
import TyVar ( SYN_IE(TyVar), GenTyVar )
import Usage ( SYN_IE(Usage), GenUsage )
import ErrUtils ( SYN_IE(Error), SYN_IE(Message), SYN_IE(Warning) )
+import CmdLineOpts ( opt_PprStyle_All, opt_PprUserLength )
import SST
import Bag ( Bag, emptyBag, isEmptyBag,
import Unique ( Unique )
import Util
import Pretty
-import PprStyle ( PprStyle(..) )
+import Outputable ( PprStyle(..), Outputable(..) )
+
infixr 9 `thenTc`, `thenTc_`, `thenNF_Tc`, `thenNF_Tc_`
\end{code}
warnTc warn_if_true warn down env
= if warn_if_true then
readMutVarSST errs_var `thenSST` \ (warns,errs) ->
- writeMutVarSST errs_var (warns `snocBag` warn, errs) `thenSST_`
+ listNF_Tc ctxt down env `thenSST` \ ctxt_msgs ->
+ let
+ full_warn = mkTcErr loc ctxt_msgs warn
+ in
+ writeMutVarSST errs_var (warns `snocBag` full_warn, errs) `thenSST_`
returnSST ()
else
returnSST ()
where
errs_var = getTcErrs down
+ ctxt = getErrCtxt down
+ loc = getLoc down
recoverTc :: TcM s r -> TcM s r -> TcM s r
recoverTc recover m down env
recoverNF_Tc recover m down env
= recoverSST (\ _ -> recover down env) (m down env)
+-- (checkNoErrsTc m) succeeds iff m succeeds and generates no errors
+-- If m fails then (checkNoErrsTc m) fails.
+-- If m succeeds, it checks whether m generated any errors messages
+-- (it might have recovered internally)
+-- If so, it fails too.
+-- Regardless, any errors generated by m are propagated to the enclosing
+-- context.
+
+checkNoErrsTc :: TcM s r -> TcM s r
+checkNoErrsTc m down env
+ = newMutVarSST (emptyBag,emptyBag) `thenSST` \ m_errs_var ->
+ let
+ errs_var = getTcErrs down
+ propagate_errs
+ = readMutVarSST m_errs_var `thenSST` \ (m_warns, m_errs) ->
+ readMutVarSST errs_var `thenSST` \ (warns, errs) ->
+ writeMutVarSST errs_var (warns `unionBags` m_warns,
+ errs `unionBags` m_errs) `thenSST_`
+ returnSST m_errs
+ in
+
+ recoverFSST (\ _ -> propagate_errs `thenSST_` failFSST ()) $
+
+ m (setTcErrs down m_errs_var) env `thenFSST` \ result ->
+
+ -- Check that m has no errors; if it has internal recovery
+ -- mechanisms it might "succeed" but having found a bunch of
+ -- errors along the way.
+ propagate_errs `thenSST` \ errs ->
+ if isEmptyBag errs then
+ returnFSST result
+ else
+ failFSST ()
+
-- (tryTc r m) tries m; if it succeeds it returns it,
-- otherwise it returns r. Any error messages added by m are discarded,
-- whether or not m succeeds.
= recoverFSST (\ _ -> recover down env) $
newMutVarSST (emptyBag,emptyBag) `thenSST` \ new_errs_var ->
-
m (setTcErrs down new_errs_var) env `thenFSST` \ result ->
-- Check that m has no errors; if it has internal recovery
else
recover down env
+-- Run the thing inside, but throw away all its error messages.
+discardErrsTc :: TcM s r -> TcM s r
+discardErrsTc m down env
+ = newMutVarSST (emptyBag,emptyBag) `thenSST` \ new_errs_var ->
+ m (setTcErrs down new_errs_var) env
+
checkTc :: Bool -> Message -> TcM s () -- Check that the boolean is true
checkTc True err = returnTc ()
checkTc False err = failTc err
tcGetEnv :: NF_TcM s (TcEnv s)
tcGetEnv down env = returnSST env
-tcSetEnv :: TcEnv s -> TcM s a -> TcM s a
+tcSetEnv :: TcEnv s
+ -> (TcDown s -> TcEnv s -> State# s -> b)
+ -> TcDown s -> TcEnv s -> State# s -> b
+-- tcSetEnv :: TcEnv s -> TcM s a -> TcM s a
+-- tcSetEnv :: TcEnv s -> NF_TcM s a -> NF_TcM s a
+
tcSetEnv new_env m down old_env = m down new_env
\end{code}
tcSetDefaultTys :: [Type] -> TcM s r -> TcM s r
tcSetDefaultTys tys m down env = m (setDefaultTys down tys) env
-tcAddSrcLoc :: SrcLoc -> TcM s a -> TcM s a
+-- tcAddSrcLoc :: SrcLoc -> TcM s a -> TcM s a
+-- tcAddSrcLoc :: SrcLoc -> NF_TcM s a -> NF_TcM s a
+tcAddSrcLoc :: SrcLoc -> (TcDown s -> env -> result)
+ -> (TcDown s -> env -> result)
tcAddSrcLoc loc m down env = m (setLoc down loc) env
tcGetSrcLoc :: NF_TcM s SrcLoc
-> TcError -- The complete error report
mkTcErr locn ctxt msg sty
- = ppHang (ppBesides [ppr PprForUser locn, ppStr ": ", msg sty])
- 4 (ppAboves [msg sty | msg <- ctxt])
+ = hang (hcat [ppr (PprForUser opt_PprUserLength) locn, ptext SLIT(": "), msg sty])
+ 4 (vcat [msg sty | msg <- ctxt_to_use])
+ where
+ ctxt_to_use =
+ if opt_PprStyle_All then
+ ctxt
+ else
+ takeAtMost 4 ctxt
+ takeAtMost :: Int -> [a] -> [a]
+ takeAtMost 0 ls = []
+ takeAtMost n [] = []
+ takeAtMost n (x:xs) = x:takeAtMost (n-1) xs
arityErr kind name n m sty
- = ppBesides [ ppStr "`", ppr sty name, ppStr "' should have ",
- n_arguments, ppStr ", but has been given ", ppInt m, ppChar '.']
+ = hsep [ ppr sty name, ptext SLIT("should have"),
+ n_arguments <> comma, text "but has been given", int m, char '.']
where
errmsg = kind ++ " has too " ++ quantity ++ " arguments"
quantity | m < n = "few"
| otherwise = "many"
- n_arguments | n == 0 = ppStr "no arguments"
- | n == 1 = ppStr "1 argument"
- | True = ppCat [ppInt n, ppStr "arguments"]
+ n_arguments | n == 0 = ptext SLIT("no arguments")
+ | n == 1 = ptext SLIT("1 argument")
+ | True = hsep [int n, ptext SLIT("arguments")]
\end{code}