diff --git a/LICENSE b/LICENSE
index 1a3d87074..41652b863 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012-2015, Evan Czaplicki
+Copyright (c) 2012-2016, Evan Czaplicki
All rights reserved.
diff --git a/README.md b/README.md
index 22156126f..c822009ec 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,13 @@
Learn about the Elm programming language at [elm-lang.org](http://elm-lang.org/).
-[![Build Status](https://travis-ci.org/elm-lang/elm-compiler.svg)](https://travis-ci.org/elm-lang/elm-compiler)
+[![Build Status](https://travis-ci.org/elm-lang/elm-compiler.svg?branch=master)](https://travis-ci.org/elm-lang/elm-compiler)
## Install
Follow [these instructions][installer] to use Elm on your machine. Be sure to use
the platform specific installers if you are on Mac or Windows. It's way easier!
- [installer]: https://github.com/elm-lang/elm-platform/blob/master/README.md#elm-platform
+ [installer]: https://github.com/elm-lang/elm-platform/blob/master/README.md#elm-platform
## Build from source / Contribute
@@ -22,4 +22,4 @@ how the script works and what your workflow will be like.
If you are stuck, email
[the list](https://groups.google.com/forum/?fromgroups#!forum/elm-discuss)
or ask a question in the
-[#Elm IRC channel](http://webchat.freenode.net/?channels=elm).
+[#Elm IRC channel](http://webchat.freenode.net/?channels=elm).
diff --git a/src/Canonicalize/Effects.hs b/src/Canonicalize/Effects.hs
index b35ad3cb5..af4fbefd5 100644
--- a/src/Canonicalize/Effects.hs
+++ b/src/Canonicalize/Effects.hs
@@ -73,7 +73,7 @@ figureOutKind region name rootType =
<* checkPortType (makeError region name) incomingType
_ ->
- Result.throw region (error "TODO - bad overall type")
+ Result.throw region (Error.BadPort name rootType)
makeError :: R.Region -> String -> T.Canonical -> Maybe String -> A.Located Error.Error
diff --git a/src/Parse/Pattern.hs b/src/Parse/Pattern.hs
index 5d653662b..3e7e18e0c 100644
--- a/src/Parse/Pattern.hs
+++ b/src/Parse/Pattern.hs
@@ -18,23 +18,21 @@ basic =
addLocation $
choice
[ char '_' >> return P.Anything
- , stringToPattern <$> var
+ , P.Var <$> lowVar
+ , chunksToPatterns <$> dotSep1 capVar
, P.Literal <$> Literal.literal
]
where
- stringToPattern str =
- case str of
- "True" ->
- P.Literal (L.Boolean True)
+ chunksToPatterns chunks =
+ case List.intercalate "." chunks of
+ "True" ->
+ P.Literal (L.Boolean True)
- "False" ->
- P.Literal (L.Boolean False)
+ "False" ->
+ P.Literal (L.Boolean False)
- c:_ | isUpper c ->
- P.Data (Var.Raw str) []
-
- _ ->
- P.Var str
+ name ->
+ P.Data (Var.Raw name) []
asPattern :: IParser P.Raw -> IParser P.Raw
@@ -94,11 +92,16 @@ term =
patternConstructor :: IParser P.Raw
patternConstructor =
addLocation $
- do v <- List.intercalate "." <$> dotSep1 capVar
- case v of
- "True" -> return $ P.Literal (L.Boolean True)
- "False" -> return $ P.Literal (L.Boolean False)
- _ -> P.Data (Var.Raw v) <$> spacePrefix term
+ do name <- List.intercalate "." <$> dotSep1 capVar
+ case name of
+ "True" ->
+ return $ P.Literal (L.Boolean True)
+
+ "False" ->
+ return $ P.Literal (L.Boolean False)
+
+ _ ->
+ P.Data (Var.Raw name) <$> spacePrefix term
expr :: IParser P.Raw
diff --git a/src/Reporting/Error/Canonicalize.hs b/src/Reporting/Error/Canonicalize.hs
index 7d13b7de3..d3c298bfb 100644
--- a/src/Reporting/Error/Canonicalize.hs
+++ b/src/Reporting/Error/Canonicalize.hs
@@ -23,6 +23,7 @@ data Error
| Export String [String]
| DuplicateExport String
| Port PortError
+ | BadPort String Type.Canonical
@@ -242,6 +243,21 @@ toReport localizer err =
]
)
+ BadPort name tipe ->
+ Report.report
+ "PORT ERROR"
+ Nothing
+ ("Port `" ++ name ++ "` has an invalid type."
+ )
+ ( Help.stack
+ [ text ("You are saying it should be:")
+ , indent 4 (RenderType.toDoc localizer tipe)
+ , Help.reflowParagraph $
+ "But you need to use the particular format described here:\
+ \ "
+ ]
+ )
+
argMismatchReport :: String -> Var.Canonical -> Int -> Int -> Report.Report
argMismatchReport kind var expected actual =
@@ -288,6 +304,9 @@ extractSuggestions err =
Port _ ->
Nothing
+ BadPort _ _ ->
+ Nothing
+
unsafePromote :: Type.Raw -> Type.Canonical
unsafePromote (A.A _ rawType) =
diff --git a/src/Reporting/Error/Syntax.hs b/src/Reporting/Error/Syntax.hs
index 240b59655..07898b636 100644
--- a/src/Reporting/Error/Syntax.hs
+++ b/src/Reporting/Error/Syntax.hs
@@ -28,6 +28,8 @@ data Error
| InfixDuplicate String
| TypeWithoutDefinition String
+
+ | DuplicateArgument String String
| DuplicateFieldName String
| DuplicateValueDeclaration String
| DuplicateTypeDeclaration String
@@ -135,7 +137,7 @@ toReport _localizer err =
"If you just wanted a normal module, change the keywords `effect module`\
\ to `module` and you should be all set. If you want a proper effect module,\
\ you need to specify your commands and/or subscriptions. Read more about this\
- \ here: (please forgive me if I forgot to fill this in!)"
+ \ here: "
)
MissingManagerOnEffectModule name ->
@@ -147,7 +149,7 @@ toReport _localizer err =
"There is a small set of top-level functions and values that must be defined\
\ in any complete effect module. The best thing is probably to just read more\
\ about effect modules here:\
- \ (please forgive me if I forgot to fill this in!)"
+ \ "
)
UnexpectedPort name ->
@@ -184,6 +186,20 @@ toReport _localizer err =
++ " " ++ valueName ++ " = 42"
)
+ DuplicateArgument funcName argName ->
+ Report.report
+ "DUPLICATE ARGUMENT"
+ Nothing
+ ( "The name `" ++ argName
+ ++ "` is used more than once in the arguments of `"
+ ++ funcName ++ "`."
+ )
+ ( Help.reflowParagraph $
+ "Rename things until `" ++ argName ++ "` is used only once.\
+ \ Otherwise how can we tell which one you want when you\
+ \ say `" ++ argName ++ "` it in the body of your function?"
+ )
+
DuplicateFieldName name ->
Report.report
"DUPLICATE FIELD"
@@ -282,7 +298,7 @@ unboundTypeVars declKind typeName givenVars unboundVars =
, Help.reflowParagraph $
"Here's why. Imagine one `" ++ typeName ++ "` where `" ++ head unboundVars ++
"` is an Int and another where it is a Bool. When we explicitly list the type\
- \ variables, type checker can see that they are actually different types."
+ \ variables, the type checker can see that they are actually different types."
]
)
diff --git a/src/Reporting/Error/Type.hs b/src/Reporting/Error/Type.hs
index 3675eb5b5..ddd3fe00a 100644
--- a/src/Reporting/Error/Type.hs
+++ b/src/Reporting/Error/Type.hs
@@ -458,7 +458,8 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
( cmpHint
("Your `" ++ name ++ "` function has this type:")
"But it needs to have a type like this:"
- [ "TODO - link to overview of effect managers"
+ [ "You can read more about setting up effect managers properly here:\
+ \ "
]
)
@@ -471,8 +472,8 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
( cmpHint
"The state created by `init` has this type:"
("But `" ++ name ++ "` expects state of this type:")
- [ "Make the two state types match and you should be all set!"
- , "TODO - link to overview of effect managers"
+ [ "Make the two state types match and you should be all set! More info here:\
+ \ "
]
)
@@ -483,8 +484,8 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
( cmpHint
"The `onEffects` function can send this type of message:"
"But the `onSelfMsg` function receives this type:"
- [ "Make the two message types match and you should be all set!"
- , "TODO - link to overview of effect managers"
+ [ "Make the two message types match and you should be all set! More info here:\
+ \ "
]
)
diff --git a/src/Type/Unify.hs b/src/Type/Unify.hs
index 42590d889..79faa3c70 100644
--- a/src/Type/Unify.hs
+++ b/src/Type/Unify.hs
@@ -519,8 +519,8 @@ unifyAlias context name args realVar otherContent =
Alias otherName otherArgs otherRealVar ->
if name == otherName then
- do merge context otherContent
- zipWithM_ (subUnify context) (map snd args) (map snd otherArgs)
+ do zipWithM_ (subUnify context) (map snd args) (map snd otherArgs)
+ merge context otherContent
else
subUnify context realVar otherRealVar
diff --git a/src/Validate.hs b/src/Validate.hs
index f3d99a911..552e4e4a7 100644
--- a/src/Validate.hs
+++ b/src/Validate.hs
@@ -1,8 +1,7 @@
{-# OPTIONS_GHC -Wall #-}
module Validate (Result, module') where
-import Prelude hiding (init)
-import Control.Monad (foldM, when)
+import Control.Monad (foldM_, when)
import qualified Data.Map as Map
import qualified Data.Maybe as Maybe
import qualified Data.Set as Set
@@ -428,8 +427,8 @@ validateDefPattern pattern body =
args ->
case pattern of
- A.A _ (Pattern.Var _) ->
- return ()
+ A.A _ (Pattern.Var funcName) ->
+ checkArguments funcName args
_ ->
let
@@ -439,6 +438,22 @@ validateDefPattern pattern body =
Result.throw (R.merge start end) (Error.BadFunctionName (length args))
+checkArguments :: String -> [Pattern.Raw] -> Result wrn ()
+checkArguments funcName args =
+ let
+ vars =
+ concatMap Pattern.boundVars args
+
+ checkDups seenArgs (A.A region arg) =
+ if Set.member arg seenArgs then
+ Result.throw region (Error.DuplicateArgument funcName arg)
+
+ else
+ return (Set.insert arg seenArgs)
+ in
+ foldM_ checkDups Set.empty vars
+
+
-- VALIDATE EXPRESSIONS
@@ -509,7 +524,7 @@ expression (A.A ann sourceExpression) =
else
return (Set.insert field seenFields)
in
- do _ <- foldM checkDups Set.empty fields
+ do foldM_ checkDups Set.empty fields
Record <$> T.traverse second fields
Let defs body ->
diff --git a/tests/test-files/bad/RepeatedArgument.elm b/tests/test-files/bad/RepeatedArgument.elm
new file mode 100644
index 000000000..52f4c8fa0
--- /dev/null
+++ b/tests/test-files/bad/RepeatedArgument.elm
@@ -0,0 +1,4 @@
+
+foo x x = 42
+
+bar x (x, y) = 42