on master help sign in
Clean up check for duplicate arguments

Try to make the error message a bit clearer. Explain why it is an error. Also switch the implementation to be O(n * log n) like in the other duplicate check in this file.

commit74bc3f29fb1512f7fa2aa218c63f468be770f53b authorEvan Czaplicki <info@elm-lang.org> dateWed 27 Apr 2016, 19:17 (11 years ago) parentef280ed
2 files changed+30−43
src/Reporting/Error/Syntax.hs+15−12 src/Validate.hs+15−31
src/Reporting/Error/Syntax.hs+15−12
@@ -19,6 +19,7 @@ data Error
1919 | TypeWithoutDefinition String
2020 | PortWithoutAnnotation String
2121 | UnexpectedPort
22+ | DuplicateArgument String String
2223 | DuplicateFieldName String
2324 | DuplicateValueDeclaration String
2425 | DuplicateTypeDeclaration String
@@ -27,7 +28,6 @@ data Error
2728 | UnboundTypeVarsInAlias String [String] [String]
2829 | UnusedTypeVarsInAlias String [String] [String]
2930 | MessyTypeVarsInAlias String [String] [String] [String]
30− | RepeatedArgument String
3131
3232
3333-- TO REPORT
@@ -110,6 +110,20 @@ toReport _localizer err =
110110 \ if the module is imported twice, do we send values out the port twice?"
111111 )
112112
113+ DuplicateArgument funcName argName ->
114+ Report.report
115+ "DUPLICATE ARGUMENT"
116+ Nothing
117+ ( "The name `" ++ argName
118+ ++ "` is used more than once in the arguments of `"
119+ ++ funcName ++ "`."
120+ )
121+ ( Help.reflowParagraph $
122+ "Rename things until `" ++ argName ++ "` is used only once.\
123+ \ Otherwise how can we tell which one you want when you\
124+ \ say `" ++ argName ++ "` it in the body of your function?"
125+ )
126+
113127 DuplicateFieldName name ->
114128 Report.report
115129 "DUPLICATE FIELD"
@@ -190,17 +204,6 @@ toReport _localizer err =
190204 ]
191205 )
192206
193− RepeatedArgument name ->
194− Report.report
195− "FUNCTION ARGUMENT REPEATED"
196− Nothing
197− ( "The argument `" ++ name ++ "` is defined multiple times."
198− )
199− ( Help.reflowParagraph $
200− "You should rename one of the occurrences of `" ++ name
201− ++ "` so that each argument is defined only once."
202− )
203−
204207
205208unboundTypeVars :: String -> String -> [String] -> [String] -> Report.Report
206209unboundTypeVars declKind typeName givenVars unboundVars@(tvar:_) =
src/Validate.hs+15−31
@@ -1,7 +1,7 @@
11{-# OPTIONS_GHC -Wall #-}
22module Validate (declarations) where
33
4−import Control.Monad (foldM)
4+import Control.Monad (foldM_)
55import qualified Data.Map as Map
66import qualified Data.Set as Set
77import qualified Data.Foldable as F
@@ -183,8 +183,8 @@ checkDefinition (Valid.Definition pattern body _) =
183183
184184 args ->
185185 case pattern of
186− A.A _ (Pattern.Var _) ->
187− checkArguments args
186+ A.A _ (Pattern.Var funcName) ->
187+ checkArguments funcName args
188188
189189 _ ->
190190 let
@@ -194,36 +194,20 @@ checkDefinition (Valid.Definition pattern body _) =
194194 Result.throw (R.merge start end) (Error.BadFunctionName (length args))
195195
196196
197−
198−checkArguments :: [Pattern.Pattern R.Region var] -> Result.Result wrn Error.Error ()
199−checkArguments args =
197+checkArguments :: String -> [Pattern.RawPattern] -> Result.Result wrn Error.Error ()
198+checkArguments funcName args =
200199 let
201− vars = concatMap (Pattern.boundVarList) args
202− in
203− case firstDuplicate vars of
204− Nothing ->
205− return ()
206−
207− Just var ->
208− let
209− (A.A start _) = head args
210− (A.A end _) = last args
211− in
212− Result.throw (R.merge start end) (Error.RepeatedArgument var)
213−
200+ vars =
201+ concatMap Pattern.boundVars args
214202
215−firstDuplicate :: [String] -> Maybe String
216−firstDuplicate vars =
217− case vars of
218− [] ->
219− Nothing
220−
221− var : rest ->
222− if var `elem` rest then
223− Just var
203+ checkDups seenArgs (A.A region arg) =
204+ if Set.member arg seenArgs then
205+ Result.throw region (Error.DuplicateArgument funcName arg)
224206
225− else
226− firstDuplicate rest
207+ else
208+ return (Set.insert arg seenArgs)
209+ in
210+ foldM_ checkDups Set.empty vars
227211
228212
229213-- VALIDATE EXPRESSIONS
@@ -294,7 +278,7 @@ expression (A.A ann sourceExpression) =
294278 else
295279 return (Set.insert field seenFields)
296280 in
297− do _ <- foldM checkDups Set.empty fields
281+ do foldM_ checkDups Set.empty fields
298282 Record <$> T.traverse second fields
299283
300284 Let defs body ->