on master help sign in
Avoid repeated arguments at compile time. Fix #809
ef280edYoann Blein
src/Reporting/Error/Syntax.hs+12
@@ -27,6 +27,7 @@ data Error
27 | UnboundTypeVarsInAlias String [String] [String]
27 | UnboundTypeVarsInAlias String [String] [String]
28 | UnusedTypeVarsInAlias String [String] [String]
28 | UnusedTypeVarsInAlias String [String] [String]
29 | MessyTypeVarsInAlias String [String] [String] [String]
29 | MessyTypeVarsInAlias String [String] [String] [String]
30+ | RepeatedArgument String
30
31
31
32
32-- TO REPORT
33-- TO REPORT
@@ -189,6 +190,17 @@ toReport _localizer err =
189 ]
190 ]
190 )
191 )
191
192
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+
192
204
193unboundTypeVars :: String -> String -> [String] -> [String] -> Report.Report
205unboundTypeVars :: String -> String -> [String] -> [String] -> Report.Report
194unboundTypeVars declKind typeName givenVars unboundVars@(tvar:_) =
206unboundTypeVars declKind typeName givenVars unboundVars@(tvar:_) =
src/Validate.hs+33−1
@@ -184,7 +184,7 @@ checkDefinition (Valid.Definition pattern body _) =
184 args ->
184 args ->
185 case pattern of
185 case pattern of
186 A.A _ (Pattern.Var _) ->
186 A.A _ (Pattern.Var _) ->
187− return ()
187+ checkArguments args
188
188
189 _ ->
189 _ ->
190 let
190 let
@@ -194,6 +194,38 @@ checkDefinition (Valid.Definition pattern body _) =
194 Result.throw (R.merge start end) (Error.BadFunctionName (length args))
194 Result.throw (R.merge start end) (Error.BadFunctionName (length args))
195
195
196
196
197+
198+checkArguments :: [Pattern.Pattern R.Region var] -> Result.Result wrn Error.Error ()
199+checkArguments args =
200+ 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+
214+
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
224+
225+ else
226+ firstDuplicate rest
227+
228+
197-- VALIDATE EXPRESSIONS
229-- VALIDATE EXPRESSIONS
198
230
199expression :: Source.Expr -> Result.Result wrn Error.Error Valid.Expr
231expression :: Source.Expr -> Result.Result wrn Error.Error Valid.Expr
tests/test-files/bad/RepeatedArgument.elmnew file+4
@@ -0,0 +1,4 @@
1+
2+foo x x = 42
3+
4+bar x (x, y) = 42