@@ -39,7 +39,6 @@ import Data.Either (lefts, rights)
39import Data.List
39import Data.List
40import Data.Maybe (fromMaybe)
40import Data.Maybe (fromMaybe)
41import qualified Data.Map as M
41import qualified Data.Map as M
42−import Data.String (IsString)
44import Control.Applicative
43import Control.Applicative
45import Control.Monad.Except
44import Control.Monad.Except
@@ -51,7 +50,6 @@ import Language.PureScript.Environment
51import Language.PureScript.Errors
50import Language.PureScript.Errors
52import Language.PureScript.Kinds
51import Language.PureScript.Kinds
53import Language.PureScript.Names
52import Language.PureScript.Names
54−import Language.PureScript.Pretty
55import Language.PureScript.Traversals
53import Language.PureScript.Traversals
56import Language.PureScript.TypeChecker.Entailment
54import Language.PureScript.TypeChecker.Entailment
57import Language.PureScript.TypeChecker.Kinds
55import Language.PureScript.TypeChecker.Kinds
@@ -184,7 +182,7 @@ replaceTypeClassDictionaries mn =
184-- Check the kind of a type, failing if it is not of kind *.
182-- Check the kind of a type, failing if it is not of kind *.
186checkTypeKind :: Kind -> UnifyT t Check ()
184checkTypeKind :: 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
190-- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns
188-- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns
@@ -207,7 +205,7 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)
207-- Infer a type for a value, rethrowing any error to provide a more useful error message
205-- Infer a type for a value, rethrowing any error to provide a more useful error message
209infer :: Expr -> UnifyT Type Check Expr
207infer :: 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
213-- Infer a type for a value
211-- Infer a type for a value
@@ -269,7 +267,7 @@ infer' (Var var) = do
269infer' v@(Constructor c) = do
267infer' v@(Constructor c) = do
270 env <- getEnv
268 env <- getEnv
271 case M.lookup c (dataConstructors env) of
269 case M.lookup c (dataConstructors env) of
272− Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
270+ Nothing -> throwError . errorMessage $ UnknownDataConstructor c Nothing
273 Just (_, _, ty, _) -> do (v', ty') <- sndM (introduceSkolemScope <=< replaceAllTypeSynonyms) <=< instantiatePolyTypeWithUnknowns v $ ty
271 Just (_, _, ty, _) -> do (v', ty') <- sndM (introduceSkolemScope <=< replaceAllTypeSynonyms) <=< instantiatePolyTypeWithUnknowns v $ ty
274 return $ TypedValue True v' ty'
272 return $ TypedValue True v' ty'
275infer' (Case vals binders) = do
273infer' (Case vals binders) = do
@@ -365,8 +363,8 @@ inferBinder val (ConstructorBinder ctor binders) = do
365 return M.empty
363 return M.empty
366 go (binder : binders') (TypeApp (TypeApp t obj) ret) | t == tyFunction =
364 go (binder : binders') (TypeApp (TypeApp t obj) ret) | t == tyFunction =
367 M.union <$> inferBinder obj binder <*> go binders' ret
365 M.union <$> inferBinder obj binder <*> go binders' ret
368− go _ _ = throwError . strMsg $ "Wrong number of arguments to constructor " ++ show ctor
366+ go _ _ = throwError . errorMessage $ IncorrectConstructorArity ctor
369− _ -> throwError . strMsg $ "Constructor " ++ show ctor ++ " is not defined"
367+ _ -> throwError . errorMessage $ UnknownDataConstructor ctor Nothing
370inferBinder val (ObjectBinder props) = do
368inferBinder val (ObjectBinder props) = do
371 row <- fresh
369 row <- fresh
372 rest <- fresh
370 rest <- fresh
@@ -404,7 +402,7 @@ inferBinder val (PositionedBinder pos _ binder) =
404checkBinders :: [Type] -> Type -> [CaseAlternative] -> UnifyT Type Check [CaseAlternative]
402checkBinders :: [Type] -> Type -> [CaseAlternative] -> UnifyT Type Check [CaseAlternative]
405checkBinders _ _ [] = return []
403checkBinders _ _ [] = return []
406checkBinders nvals ret (CaseAlternative binders result : bs) = do
404checkBinders nvals ret (CaseAlternative binders result : bs) = do
407− guardWith (strMsg "Overlapping binders in case statement") $
405+ guardWith (errorMessage $ OverlappingArgNames Nothing) $
408 let ns = concatMap binderNames binders in length (nub ns) == length ns
406 let ns = concatMap binderNames binders in length (nub ns) == length ns
409 Just moduleName <- checkCurrentModule <$> get
407 Just moduleName <- checkCurrentModule <$> get
410 m1 <- M.unions <$> zipWithM inferBinder nvals binders
408 m1 <- M.unions <$> zipWithM inferBinder nvals binders
@@ -427,13 +425,7 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
427-- Check the type of a value, rethrowing errors to provide a better error message
425-- Check the type of a value, rethrowing errors to provide a better error message
429check :: Expr -> Type -> UnifyT Type Check Expr
427check :: Expr -> Type -> UnifyT Type Check Expr
430−check val ty = rethrow (mkCompileError errorMessage (Just (ExprError val)) `combineErrors`) $ check' val ty
428+check val ty = rethrow (onErrorMessages (ErrorCheckingType val ty)) $ check' val ty
433− "Error checking type of term " ++
434− prettyPrintValue val ++
439-- Check the type of a value
431-- Check the type of a value
@@ -490,7 +482,7 @@ check' v@(Var var) ty = do
490 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
482 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
491 v' <- subsumes (Just v) repl ty'
483 v' <- subsumes (Just v) repl ty'
492 case v' of
484 case v' of
493− Nothing -> throwError . strMsg $ "Unable to check type subsumption"
485+ Nothing -> throwError . errorMessage $ SubsumptionCheckFailed
494 Just v'' -> return $ TypedValue True v'' ty'
486 Just v'' -> return $ TypedValue True v'' ty'
495check' (SuperClassDictionary className tys) _ = do
487check' (SuperClassDictionary className tys) _ = do
@@ -513,7 +505,7 @@ check' (TypedValue checkType val ty1) ty2 = do
513 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
505 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
514 val' <- subsumes (Just val) ty1' ty2'
506 val' <- subsumes (Just val) ty1' ty2'
515 case val' of
507 case val' of
516− Nothing -> throwError . strMsg $ "Unable to check type subsumption"
508+ Nothing -> throwError . errorMessage $ SubsumptionCheckFailed
517 Just val'' -> do
509 Just val'' -> do
518 val''' <- if checkType then withScopedTypeVars moduleName args (check val'' ty2') else return val''
510 val''' <- if checkType then withScopedTypeVars moduleName args (check val'' ty2') else return val''
519 return $ TypedValue checkType (TypedValue True val''' ty1') ty2'
511 return $ TypedValue checkType (TypedValue True val''' ty1') ty2'
@@ -551,7 +543,7 @@ check' (Accessor prop val) ty = do
551check' (Constructor c) ty = do
543check' (Constructor c) ty = do
552 env <- getEnv
544 env <- getEnv
553 case M.lookup c (dataConstructors env) of
545 case M.lookup c (dataConstructors env) of
554− Nothing -> throwError . strMsg $ "Constructor " ++ show c ++ " is undefined"
546+ Nothing -> throwError . errorMessage $ UnknownDataConstructor c Nothing
555 Just (_, _, ty1, _) -> do
547 Just (_, _, ty1, _) -> do
556 repl <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty1
548 repl <- introduceSkolemScope <=< replaceAllTypeSynonyms $ ty1
557 _ <- subsumes Nothing repl ty
549 _ <- subsumes Nothing repl ty
@@ -568,7 +560,7 @@ check' val kt@(KindedType ty kind) = do
568 return $ TypedValue True val' kt
560 return $ TypedValue True val' kt
569check' (PositionedValue pos _ val) ty =
561check' (PositionedValue pos _ val) ty =
570 rethrowWithPosition pos $ check' val ty
562 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
573containsTypeSynonyms :: Type -> Bool
565containsTypeSynonyms :: Type -> Bool
574containsTypeSynonyms = everythingOnTypes (||) go where
566containsTypeSynonyms = everythingOnTypes (||) go where
@@ -589,8 +581,8 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
589 return []
581 return []
590 go [] [] Skolem{} | lax = return []
582 go [] [] Skolem{} | lax = return []
591 go [] ((p, _): _) _ | lax = return []
583 go [] ((p, _): _) _ | lax = return []
592− | otherwise = throwError $ mkMultipleErrors ("Object does not have property " ++ p) (Just (ExprError (ObjectLiteral ps)))
584+ | otherwise = throwError . errorMessage $ PropertyIsMissing p row
593− go ((p,_):_) [] REmpty = throwError $ mkMultipleErrors ("Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row) (Just (ExprError (ObjectLiteral ps)))
585+ go ((p,_):_) [] REmpty = throwError . errorMessage $ PropertyIsMissing p row
594 go ((p,v):ps') ts r =
586 go ((p,v):ps') ts r =
595 case lookup p ts of
587 case lookup p ts of
596 Nothing -> do
588 Nothing -> do
@@ -603,19 +595,15 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
603 v' <- check v ty
595 v' <- check v ty
604 ps'' <- go ps' (delete (p, ty) ts) r
596 ps'' <- go ps' (delete (p, ty) ts) r
605 return $ (p, v') : ps''
597 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)
609-- Check the type of a function application, rethrowing errors to provide a better error message
601-- Check the type of a function application, rethrowing errors to provide a better error message
611checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
603checkFunctionApplication :: 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
613 subst <- unifyCurrentSubstitution <$> UnifyT get
605 subst <- unifyCurrentSubstitution <$> UnifyT get
614 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
606 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
616− errorMessage = "Error applying function of type "
617− ++ prettyPrintType fnTy
618− ++ " to argument " ++ prettyPrintValue arg
621-- Check the type of a function application
609-- Check the type of a function application
@@ -651,9 +639,7 @@ checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
651 checkFunctionApplication' (foldl App fn (map (flip (TypeClassDictionary True) dicts) constraints)) fnTy arg ret
639 checkFunctionApplication' (foldl App fn (map (flip (TypeClassDictionary True) dicts) constraints)) fnTy arg ret
652checkFunctionApplication' fn fnTy dict@TypeClassDictionary{} _ =
640checkFunctionApplication' fn fnTy dict@TypeClassDictionary{} _ =
653 return (fnTy, App fn dict)
641 return (fnTy, App fn dict)
654−checkFunctionApplication' _ fnTy arg _ = throwError . strMsg $ "Cannot apply a function of type "
642+checkFunctionApplication' _ fnTy arg _ = throwError . errorMessage $ CannotApplyFunction fnTy arg
655− ++ prettyPrintType fnTy
656− ++ " to argument " ++ prettyPrintValue arg
659-- Compute the meet of two types, i.e. the most general type which both types subsume.
645-- 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
674-- Ensure a set of property names and value does not contain duplicate labels
660-- Ensure a set of property names and value does not contain duplicate labels
676−ensureNoDuplicateProperties :: (IsString e, MonadError e m) => [(String, Expr)] -> m ()
662+ensureNoDuplicateProperties :: (MonadError MultipleErrors m) => [(String, Expr)] -> m ()
677−ensureNoDuplicateProperties ps = guardWith "Duplicate property names" $ length (nub . map fst $ ps) == length ps
663+ensureNoDuplicateProperties ps =
664+ let ls = map fst ps in
665+ case ls \\ nub ls of
666+ l : _ -> throwError . errorMessage $ DuplicateLabel l Nothing