@@ -39,7 +39,6 @@ import Data.Either (lefts, rights)
3939import Data.List
4040import Data.Maybe (fromMaybe)
4141import qualified Data.Map as M
42−import Data.String (IsString)
4342
4443import Control.Applicative
4544import Control.Monad.Except
@@ -51,7 +50,6 @@ import Language.PureScript.Environment
5150import Language.PureScript.Errors
5251import Language.PureScript.Kinds
5352import Language.PureScript.Names
54−import Language.PureScript.Pretty
5553import Language.PureScript.Traversals
5654import Language.PureScript.TypeChecker.Entailment
5755import Language.PureScript.TypeChecker.Kinds
@@ -184,7 +182,7 @@ replaceTypeClassDictionaries mn =
184182-- Check the kind of a type, failing if it is not of kind *.
185183--
186184checkTypeKind :: Kind -> UnifyT t Check ()
187−checkTypeKind kind = guardWith (strMsg $ "Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
185+checkTypeKind kind = guardWith (errorMessage (ExpectedType kind)) $ kind == Star
188186
189187-- |
190188-- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns
@@ -207,7 +205,7 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)
207205-- Infer a type for a value, rethrowing any error to provide a more useful error message
208206--
209207infer :: Expr -> UnifyT Type Check Expr
210−infer val = rethrow (mkCompileError "Error inferring type of value" (Just (ExprError val)) `combineErrors`) $ infer' val
208+infer val = rethrow (onErrorMessages (ErrorInferringType val)) $ infer' val
211209
212210-- |
213211-- Infer a type for a value
@@ -269,7 +267,7 @@ infer' (Var var) = do
269267infer' v@(Constructor c) = do
270268 env <- getEnv
271269 case M.lookup c (dataConstructors env) of
272− Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
270+ Nothing -> throwError . errorMessage $ UnknownDataConstructor c Nothing
273271 Just (_, _, ty, _) -> do (v', ty') <- sndM (introduceSkolemScope <=< replaceAllTypeSynonyms) <=< instantiatePolyTypeWithUnknowns v $ ty
274272 return $ TypedValue True v' ty'
275273infer' (Case vals binders) = do
@@ -365,8 +363,8 @@ inferBinder val (ConstructorBinder ctor binders) = do
365363 return M.empty
366364 go (binder : binders') (TypeApp (TypeApp t obj) ret) | t == tyFunction =
367365 M.union <$> inferBinder obj binder <*> go binders' ret
368− go _ _ = throwError . strMsg $ "Wrong number of arguments to constructor " ++ show ctor
369− _ -> throwError . strMsg $ "Constructor " ++ show ctor ++ " is not defined"
366+ go _ _ = throwError . errorMessage $ IncorrectConstructorArity ctor
367+ _ -> throwError . errorMessage $ UnknownDataConstructor ctor Nothing
370368inferBinder val (ObjectBinder props) = do
371369 row <- fresh
372370 rest <- fresh
@@ -404,7 +402,7 @@ inferBinder val (PositionedBinder pos _ binder) =
404402checkBinders :: [Type] -> Type -> [CaseAlternative] -> UnifyT Type Check [CaseAlternative]
405403checkBinders _ _ [] = return []
406404checkBinders nvals ret (CaseAlternative binders result : bs) = do
407− guardWith (strMsg "Overlapping binders in case statement") $
405+ guardWith (errorMessage $ OverlappingArgNames Nothing) $
408406 let ns = concatMap binderNames binders in length (nub ns) == length ns
409407 Just moduleName <- checkCurrentModule <$> get
410408 m1 <- M.unions <$> zipWithM inferBinder nvals binders
@@ -427,13 +425,7 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
427425-- Check the type of a value, rethrowing errors to provide a better error message
428426--
429427check :: Expr -> Type -> UnifyT Type Check Expr
430−check val ty = rethrow (mkCompileError errorMessage (Just (ExprError val)) `combineErrors`) $ check' val ty
431− where
432− errorMessage =
433− "Error checking type of term " ++
434− prettyPrintValue val ++
435− " against type " ++
436− prettyPrintType ty
428+check val ty = rethrow (onErrorMessages (ErrorCheckingType val ty)) $ check' val ty
437429
438430-- |
439431-- Check the type of a value
@@ -490,7 +482,7 @@ check' v@(Var var) ty = do
490482 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
491483 v' <- subsumes (Just v) repl ty'
492484 case v' of
493− Nothing -> throwError . strMsg $ "Unable to check type subsumption"
485+ Nothing -> throwError . errorMessage $ SubsumptionCheckFailed
494486 Just v'' -> return $ TypedValue True v'' ty'
495487check' (SuperClassDictionary className tys) _ = do
496488 {-
@@ -513,7 +505,7 @@ check' (TypedValue checkType val ty1) ty2 = do
513505 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
514506 val' <- subsumes (Just val) ty1' ty2'
515507 case val' of
516− Nothing -> throwError . strMsg $ "Unable to check type subsumption"
508+ Nothing -> throwError . errorMessage $ SubsumptionCheckFailed
517509 Just val'' -> do
518510 val''' <- if checkType then withScopedTypeVars moduleName args (check val'' ty2') else return val''
519511 return $ TypedValue checkType (TypedValue True val''' ty1') ty2'
@@ -551,7 +543,7 @@ check' (Accessor prop val) ty = do
551543check' (Constructor c) ty = do
552544 env <- getEnv
553545 case M.lookup c (dataConstructors env) of
554− Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
546+ Nothing -> throwError . errorMessage $ UnknownDataConstructor c Nothing
555547 Just (_, _, ty1, _) -> do
556548 repl <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty1
557549 _ <- subsumes Nothing repl ty
@@ -568,7 +560,7 @@ check' val kt@(KindedType ty kind) = do
568560 return $ TypedValue True val' kt
569561check' (PositionedValue pos _ val) ty =
570562 rethrowWithPosition pos $ check' val ty
571−check' val ty = throwError $ mkMultipleErrors ("Expr does not have type " ++ prettyPrintType ty) (Just (ExprError val))
563+check' val ty = throwError . errorMessage $ ExprDoesNotHaveType val ty
572564
573565containsTypeSynonyms :: Type -> Bool
574566containsTypeSynonyms = everythingOnTypes (||) go where
@@ -589,8 +581,8 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
589581 return []
590582 go [] [] Skolem{} | lax = return []
591583 go [] ((p, _): _) _ | lax = return []
592− | otherwise = throwError $ mkMultipleErrors ("Object does not have property " ++ p) (Just (ExprError (ObjectLiteral ps)))
593− go ((p,_):_) [] REmpty = throwError $ mkMultipleErrors ("Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row) (Just (ExprError (ObjectLiteral ps)))
584+ | otherwise = throwError . errorMessage $ PropertyIsMissing p row
585+ go ((p,_):_) [] REmpty = throwError . errorMessage $ PropertyIsMissing p row
594586 go ((p,v):ps') ts r =
595587 case lookup p ts of
596588 Nothing -> do
@@ -603,19 +595,15 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
603595 v' <- check v ty
604596 ps'' <- go ps' (delete (p, ty) ts) r
605597 return $ (p, v') : ps''
606− go _ _ _ = throwError $ mkMultipleErrors ("Object does not have type " ++ prettyPrintType (TypeApp tyObject row)) (Just (ExprError (ObjectLiteral ps)))
598+ go _ _ _ = throwError . errorMessage $ ExprDoesNotHaveType (ObjectLiteral ps) (TypeApp tyObject row)
607599
608600-- |
609601-- Check the type of a function application, rethrowing errors to provide a better error message
610602--
611603checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
612−checkFunctionApplication fn fnTy arg ret = rethrow (mkCompileError errorMessage (Just (ExprError fn)) `combineErrors`) $ do
604+checkFunctionApplication fn fnTy arg ret = rethrow (onErrorMessages (ErrorInApplication fn fnTy arg)) $ do
613605 subst <- unifyCurrentSubstitution <$> UnifyT get
614606 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
615− where
616− errorMessage = "Error applying function of type "
617− ++ prettyPrintType fnTy
618− ++ " to argument " ++ prettyPrintValue arg
619607
620608-- |
621609-- Check the type of a function application
@@ -651,9 +639,7 @@ checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
651639 checkFunctionApplication' (foldl App fn (map (flip (TypeClassDictionary True) dicts) constraints)) fnTy arg ret
652640checkFunctionApplication' fn fnTy dict@TypeClassDictionary{} _ =
653641 return (fnTy, App fn dict)
654−checkFunctionApplication' _ fnTy arg _ = throwError . strMsg $ "Cannot apply a function of type "
655− ++ prettyPrintType fnTy
656− ++ " to argument " ++ prettyPrintValue arg
642+checkFunctionApplication' _ fnTy arg _ = throwError . errorMessage $ CannotApplyFunction fnTy arg
657643
658644-- |
659645-- Compute the meet of two types, i.e. the most general type which both types subsume.
@@ -673,5 +659,9 @@ meet e1 e2 t1 t2 = do
673659-- |
674660-- Ensure a set of property names and value does not contain duplicate labels
675661--
676−ensureNoDuplicateProperties :: (IsString e, MonadError e m) => [(String, Expr)] -> m ()
677−ensureNoDuplicateProperties ps = guardWith "Duplicate property names" $ length (nub . map fst $ ps) == length ps
662+ensureNoDuplicateProperties :: (MonadError MultipleErrors m) => [(String, Expr)] -> m ()
663+ensureNoDuplicateProperties ps =
664+ let ls = map fst ps in
665+ case ls \\ nub ls of
666+ l : _ -> throwError . errorMessage $ DuplicateLabel l Nothing
667+ _ -> return ()