X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypecheck%2FTcErrors.lhs;h=c30d70210c7f444ff57eb60299722324c3a8ad5c;hb=b598d8acf04b44f3b4e8187f1780bfc38c6abb33;hp=b3dfb9c6ff6e095d6fbd5c97953207ec757190cb;hpb=af2e0d24abe49e06fdee4a95530af8a5c33da4a3;p=ghc-hetmet.git diff --git a/compiler/typecheck/TcErrors.lhs b/compiler/typecheck/TcErrors.lhs index b3dfb9c..c30d702 100644 --- a/compiler/typecheck/TcErrors.lhs +++ b/compiler/typecheck/TcErrors.lhs @@ -158,7 +158,7 @@ reportTidyWanteds ctxt unsolved reportFlat :: ReportErrCtxt -> [PredType] -> CtOrigin -> TcM () reportFlat ctxt flats origin = do { unless (null dicts) $ reportDictErrs ctxt dicts origin - ; unless (null eqs) $ reportEqErrs ctxt eqs + ; unless (null eqs) $ reportEqErrs ctxt eqs origin ; unless (null ips) $ reportIPErrs ctxt ips origin ; ASSERT( null others ) return () } where @@ -277,12 +277,17 @@ reportIPErrs ctxt ips orig %************************************************************************ \begin{code} -reportEqErrs :: ReportErrCtxt -> [PredType] -> TcM () -reportEqErrs ctxt eqs +reportEqErrs :: ReportErrCtxt -> [PredType] -> CtOrigin -> TcM () +reportEqErrs ctxt eqs orig = mapM_ report_one eqs where - report_one (EqPred ty1 ty2) = reportEqErr ctxt ty1 ty2 - report_one pred = pprPanic "reportEqErrs" (ppr pred) + report_one (EqPred ty1 ty2) + = do { (env1, extra) <- getWantedEqExtra (cec_tidy ctxt) orig ty1 ty2 + ; let ctxt' = ctxt { cec_tidy = env1 + , cec_extra = cec_extra ctxt $$ extra } + ; reportEqErr ctxt' ty1 ty2 } + report_one pred + = pprPanic "reportEqErrs" (ppr pred) reportEqErr :: ReportErrCtxt -> TcType -> TcType -> TcM () reportEqErr ctxt ty1 ty2 @@ -653,23 +658,24 @@ kindErrorTcS fl ty1 ty2 = wrapErrTcS $ setCtFlavorLoc fl $ do { env0 <- tcInitTidyEnv - ; let (env1, ty1') = tidyOpenType env0 ty1 - (env2, ty2') = tidyOpenType env1 ty2 + ; (env1, extra) <- getEqExtra env0 fl ty1 ty2 + ; let (env2, ty1') = tidyOpenType env1 ty1 + (env3, ty2') = tidyOpenType env2 ty2 ctxt = CEC { cec_encl = [] - , cec_extra = empty - , cec_tidy = env2 } + , cec_extra = extra + , cec_tidy = env3 } ; reportEqErr ctxt ty1' ty2' } misMatchErrorTcS :: CtFlavor -> TcType -> TcType -> TcS a misMatchErrorTcS fl ty1 ty2 - = wrapErrTcS $ - setCtFlavorLocNoEq fl $ -- Don't add the "When matching t1 with t2" - -- part, because it duplciates what we say now + = wrapErrTcS $ + setCtFlavorLoc fl $ do { env0 <- tcInitTidyEnv ; let (env1, ty1') = tidyOpenType env0 ty1 (env2, ty2') = tidyOpenType env1 ty2 (env3, msg) = misMatchMsgWithExtras env2 ty1' ty2' - ; failWithTcM (env3, inaccessible_msg $$ msg) } + ; (env4, extra) <- getEqExtra env3 fl ty1 ty2 + ; failWithTcM (env4, inaccessible_msg $$ msg $$ extra) } where inaccessible_msg = case fl of @@ -685,13 +691,14 @@ misMatchErrorTcS fl ty1 ty2 occursCheckErrorTcS :: CtFlavor -> TcTyVar -> TcType -> TcS a occursCheckErrorTcS fl tv ty - = wrapErrTcS $ - setCtFlavorLoc fl $ - do { env0 <- tcInitTidyEnv - ; let (env1, tv') = tidyOpenTyVar env0 tv + = wrapErrTcS $ + setCtFlavorLoc fl $ + do { env0 <- tcInitTidyEnv + ; let (env1, tv') = tidyOpenTyVar env0 tv (env2, ty') = tidyOpenType env1 ty - extra = sep [ppr tv', char '=', ppr ty'] - ; failWithTcM (env2, hang msg 2 extra) } + extra1 = sep [ppr tv', char '=', ppr ty'] + ; (env3, extra2) <- getEqExtra env2 fl (mkTyVarTy tv) ty + ; failWithTcM (env3, hang msg 2 (extra1 $$ extra2)) } where msg = text $ "Occurs check: cannot construct the infinite type:" @@ -731,30 +738,33 @@ flattenForAllErrorTcS fl ty _bad_eqs %************************************************************************ \begin{code} -setCtFlavorLocNoEq :: CtFlavor -> TcM a -> TcM a -setCtFlavorLocNoEq (Wanted loc) thing = setCtLoc loc thing -setCtFlavorLocNoEq (Derived loc) thing = setCtLoc loc thing -setCtFlavorLocNoEq (Given loc) thing = setCtLoc loc thing - setCtFlavorLoc :: CtFlavor -> TcM a -> TcM a -setCtFlavorLoc (Wanted loc) thing = setWantedLoc loc thing -setCtFlavorLoc (Derived loc) thing = setWantedLoc loc thing -setCtFlavorLoc (Given loc) thing = setGivenLoc loc thing - -setWantedLoc :: WantedLoc -> TcM a -> TcM a -setWantedLoc loc thing_inside - = setCtLoc loc $ - add_origin (ctLocOrigin loc) $ - thing_inside - where - add_origin (TypeEqOrigin item) = addErrCtxtM (unifyCtxt item) - add_origin orig = addErrCtxt (ptext (sLit "At") <+> ppr orig) +setCtFlavorLoc (Wanted loc) thing = setCtLoc loc thing +setCtFlavorLoc (Derived loc) thing = setCtLoc loc thing +setCtFlavorLoc (Given loc) thing = setCtLoc loc thing + +getEqExtra :: TidyEnv -> CtFlavor -> TcType -> TcType -> TcM (TidyEnv, SDoc) +getEqExtra env (Wanted loc) ty1 ty2 = getWantedEqExtra env (ctLocOrigin loc) ty1 ty2 +getEqExtra env (Derived loc) ty1 ty2 = getWantedEqExtra env (ctLocOrigin loc) ty1 ty2 +getEqExtra env (Given _) _ _ = return (env, empty) + -- We could print more info, but it seems to be already coming out + +getWantedEqExtra :: TidyEnv -> CtOrigin -> TcType -> TcType -> TcM (TidyEnv, SDoc) +getWantedEqExtra env0 (TypeEqOrigin item) ty1 ty2 + -- If the types in the error message are the same + -- as the types we are unifying (remember to zonk the latter) + -- don't add the extra expected/actual message + = do { act <- zonkTcType (uo_actual item) + ; exp <- zonkTcType (uo_expected item) + ; if (act `tcEqType` ty1 && exp `tcEqType` ty2) + || (exp `tcEqType` ty1 && act `tcEqType` ty2) + then + return (env0, empty) + else do + { let (env1, exp') = tidyOpenType env0 exp + (env2, act') = tidyOpenType env1 act + ; return (env2, mkExpectedActualMsg act' exp') } } -setGivenLoc :: GivenLoc -> TcM a -> TcM a -setGivenLoc loc thing_inside - = setCtLoc loc $ - add_origin (ctLocOrigin loc) $ - thing_inside - where - add_origin skol = addErrCtxt (ptext (sLit "In") <+> pprSkolInfo skol) +getWantedEqExtra env0 orig _ _ + = return (env0, pprArising orig) \end{code}