on master help sign in
Improve error messages for bad return types (annotation /= def)
dcce951Evan Czaplicki
src/Reporting/Error/Helpers.hs+7−1
@@ -1,7 +1,8 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2module Reporting.Error.Helpers
2module Reporting.Error.Helpers
3 ( (|>)
3 ( (|>)
4+ , functionName, args
4− , functionName, hintLink, stack, reflowParagraph
5+ , hintLink, stack, reflowParagraph
5 , commaSep, capitalize, ordinalize, drawCycle
6 , commaSep, capitalize, ordinalize, drawCycle
6 , findPotentialTypos, findTypoPairs, vetTypos
7 , findPotentialTypos, findTypoPairs, vetTypos
7 , nearbyNames, distance, maybeYouWant
8 , nearbyNames, distance, maybeYouWant
@@ -47,6 +48,11 @@ functionName opName =
47 "`" ++ opName ++ "`"
48 "`" ++ opName ++ "`"
48
49
49
50
51+args :: Int -> String
52+args n =
53+ show n ++ if n == 1 then " argument" else " arguments"
54+
55+
50hintLink :: String -> String
56hintLink :: String -> String
51hintLink fileName =
57hintLink fileName =
52 "<https://github.com/elm-lang/elm-compiler/blob/"
58 "<https://github.com/elm-lang/elm-compiler/blob/"
src/Reporting/Error/Type.hs+53−26
@@ -69,7 +69,7 @@ data Hint
69 | Function (Maybe Var.Canonical)
69 | Function (Maybe Var.Canonical)
70 | UnexpectedArg (Maybe Var.Canonical) Int Int Region.Region
70 | UnexpectedArg (Maybe Var.Canonical) Int Int Region.Region
71 | FunctionArity (Maybe Var.Canonical) Int Int Region.Region
71 | FunctionArity (Maybe Var.Canonical) Int Int Region.Region
72− | ReturnType String Int
72+ | ReturnType String Int Int Region.Region
73 | Instance String
73 | Instance String
74 | Literal String
74 | Literal String
75 | Pattern Pattern
75 | Pattern Pattern
@@ -306,7 +306,7 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
306 UnexpectedArg maybeName 1 1 region ->
306 UnexpectedArg maybeName 1 1 region ->
307 report
307 report
308 (Just region)
308 (Just region)
309− ("The argument to " ++ funcName maybeName ++ " is causing a mismatch.")
309+ ("The argument to " ++ funcName maybeName ++ " is causing a mismatch.")
310 ( cmpHint
310 ( cmpHint
311 (Help.capitalize (funcName maybeName) ++ " is expecting the argument to be:")
311 (Help.capitalize (funcName maybeName) ++ " is expecting the argument to be:")
312 "But it is:"
312 "But it is:"
@@ -356,37 +356,34 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
356 (text "Maybe you forgot some parentheses? Or a comma?")
356 (text "Maybe you forgot some parentheses? Or a comma?")
357
357
358 FunctionArity maybeName expected actual region ->
358 FunctionArity maybeName expected actual region ->
359− let
360− s = if expected == 1 then "" else "s"
361− in
362− report
363− (Just region)
364− ( Help.capitalize (funcName maybeName) ++ " is expecting " ++ show expected
365− ++ " argument" ++ s ++ ", but was given " ++ show actual ++ "."
366− )
367− (text "Maybe you forgot some parentheses? Or a comma?")
368−
369− ReturnType name 0 ->
370 report
359 report
371− Nothing
360+ (Just region)
361+ ( Help.capitalize (funcName maybeName) ++ " is expecting "
362+ ++ Help.args expected ++ ", but was given " ++ show actual ++ "."
363+ )
364+ (text "Maybe you forgot some parentheses? Or a comma?")
365+
366+ ReturnType name typeArity argArity region ->
367+ if typeArity == 0 || argArity == 0 then
368+ report
369+ (Just region)
372− ("The type annotation for " ++ Help.functionName name ++ " does not match its definition.")
370+ ("The definition of " ++ Help.functionName name ++ " does not match its type annotation.")
373 ( cmpHint
371 ( cmpHint
374− ( "The type annotation says " ++ Help.functionName name
372+ ( "The type annotation for " ++ Help.functionName name ++ " says it is a:"
375− ++ " should be a:"
376 )
373 )
377− "But the value you defined has this type:"
374+ "But the definition (shown above) is a:"
378− []
375+ (arityHint typeArity argArity)
379 )
376 )
380
377
381− ReturnType name arity ->
378+ else
382− report
379+ report
383− Nothing
380+ (Just region)
384− ("The " ++ Help.functionName name ++ " function does not match the type annotation.")
381+ ("The definition of " ++ Help.functionName name ++ " does not match its type annotation.")
385 ( cmpHint
382 ( cmpHint
386− "The definition produces values of this type:"
387− ( "But type annotation says " ++ Help.functionName name ++ " should return:"
383+ ( "The type annotation for " ++ Help.functionName name ++ " says it always returns:"
388 )
384 )
389− []
385+ "But the returned value (shown above) is a:"
386+ (arityHint typeArity argArity)
390 )
387 )
391
388
392 Instance name ->
389 Instance name ->
@@ -571,6 +568,36 @@ functionHint maybeName =
571
568
572
569
573
570
571+-- ARITY HINTS
572+
573+
574+arityHint :: Int -> Int -> [String]
575+arityHint typeArity argArity =
576+ if typeArity == argArity then
577+ []
578+
579+ else
580+ [ "The type annotation says there " ++ sayArgs typeArity
581+ ++ ", but there " ++ sayArgs argArity ++ " named in the definition."
582+ ++ " It is best practice for each argument in the type to correspond"
583+ ++ " to a named argument in the definition, so try that first!"
584+ ]
585+
586+
587+sayArgs :: Int -> String
588+sayArgs n =
589+ case n of
590+ 0 ->
591+ "are NO arguments"
592+
593+ 1 ->
594+ "is 1 argument"
595+
596+ _ ->
597+ "are " ++ show n ++ " arguments"
598+
599+
600+
574-- MISMATCH HELPERS
601-- MISMATCH HELPERS
575
602
576
603