@@ -2,9 +2,12 @@
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Type
3module Reporting.Error.Type
4 ( Error(..)
4 ( Error(..)
5− , Mismatch(..), Hint(..)
5+ , Mismatch(..)
6− , Reason(..), SpecificThing(..)
8+ , SpecificThing(..)
7− , Pattern(..)
9+ , PatternContext(..)
10+ , PatternCategory(..)
8 , toReport
11 , toReport
9 , flipReason
12 , flipReason
@@ -16,15 +19,16 @@ import qualified Data.Text as Text
16import Data.Text (Text)
19import Data.Text (Text)
17import Data.Monoid ((<>))
20import Data.Monoid ((<>))
19−import qualified AST.Helpers as Help
22+import qualified AST.Module.Name as ModuleName
20import qualified AST.Type as Type
23import qualified AST.Type as Type
21import qualified AST.Variable as Var
24import qualified AST.Variable as Var
22−import qualified Reporting.Region as Region
25+import qualified Elm.Name as N
26+import qualified Reporting.Region as R
23import qualified Reporting.Render.Type as RenderType
27import qualified Reporting.Render.Type as RenderType
24import qualified Reporting.Report as Report
28import qualified Reporting.Report as Report
25import qualified Reporting.Helpers as Help
29import qualified Reporting.Helpers as Help
26import Reporting.Helpers
30import Reporting.Helpers
27− ( Doc, (<+>), capitalize, dullyellow, functionName, i2t
31+ ( Doc, capitalize, dullyellow, functionName, i2t
28 , indent, ordinalize, reflowParagraph, stack, text
32 , indent, ordinalize, reflowParagraph, stack, text
@@ -54,7 +58,6 @@ data Reason
54 = BadFields [(Text, Maybe Reason)]
58 = BadFields [(Text, Maybe Reason)]
55 | MessyFields [Text] [Text] [Text]
59 | MessyFields [Text] [Text] [Text]
56 | IntFloat
60 | IntFloat
57− | TooLongComparableTuple Int
58 | MissingArgs Int
61 | MissingArgs Int
59 | RigidClash Text Text
62 | RigidClash Text Text
60 | NotPartOfSuper Type.Super
63 | NotPartOfSuper Type.Super
@@ -64,45 +67,59 @@ data Reason
65data SpecificThing
68data SpecificThing
66 = SpecificSuper Type.Super
69 = SpecificSuper Type.Super
67− | SpecificType Var.Canonical
70+ | SpecificType N.Name
68 | SpecificFunction
71 | SpecificFunction
69 | SpecificRecord
72 | SpecificRecord
73− = CaseBranch Int Region.Region
78+ = CaseBranch Int R.Region
75 | IfCondition
80 | IfCondition
76 | IfBranches
81 | IfBranches
77− | MultiIfBranch Int Region.Region
82+ | MultiIfBranch Int R.Region
80− | ListElement Int Region.Region
85+ | ListElement Int R.Region
81− | BinopLeft Var.Canonical Region.Region
86+ | BinopLeft ModuleName.Canonical N.Name R.Region
82− | BinopRight Var.Canonical Region.Region
87+ | BinopRight ModuleName.Canonical N.Name R.Region
83− | Binop Var.Canonical
88+ | Binop ModuleName.Canonical N.Name
84 | Function (Maybe Var.Canonical)
89 | Function (Maybe Var.Canonical)
85− | UnexpectedArg (Maybe Var.Canonical) Int Int Region.Region
90+ | UnexpectedArg (Maybe Var.Canonical) Int Int R.Region
86− | FunctionArity (Maybe Var.Canonical) Int Int Region.Region
91+ | FunctionArity (Maybe Var.Canonical) Int Int R.Region
87− | ReturnType Text Int Int Region.Region
92+ | ReturnType Text Int Int R.Region
88 | Instance Text
93 | Instance Text
89 | Literal Text
94 | Literal Text
90− | Pattern Pattern
95+ | Pattern PatternContext PatternCategory
93 | Access (Maybe Text) Text
100 | Access (Maybe Text) Text
95 -- effect manager problems
104 -- effect manager problems
96 | Manager Text
105 | Manager Text
97 | State Text
106 | State Text
98 | SelfMsg
107 | SelfMsg
101−data Pattern
110+data PatternContext
102− = PVar Text
111+ = PatternArg N.Name Int
103− | PAlias Text
112+ | PatternTail
104− | PCtor Var.Canonical
113+ | PatternList Int
105− | PRecord
118+ = PRecord
@@ -272,37 +289,37 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
275− BinopLeft op region ->
292+ BinopLeft home op region ->
277 (Just region)
294 (Just region)
278− ("The left argument of " <> varName op <> " is causing a type mismatch.")
295+ ("The left argument of (" <> op <> ") is causing a type mismatch.")
279 ( cmpHint
296 ( cmpHint
280− (varName op <> " is expecting the left argument to be a:")
297+ ("(" <> op <> ") is expecting the left argument to be a:")
281 "But the left argument is:"
298 "But the left argument is:"
282− (binopHint op leftType rightType)
299+ (binopHint home op leftType rightType)
285− BinopRight op region ->
302+ BinopRight home op region ->
287 (Just region)
304 (Just region)
288− ("The right side of " <> varName op <> " is causing a type mismatch.")
305+ ("The right side of (" <> op <> ") is causing a type mismatch.")
289 ( cmpHint
306 ( cmpHint
290− (varName op <> " is expecting the right side to be a:")
307+ ("(" <> op <> ") is expecting the right side to be a:")
291 "But the right side is:"
308 "But the right side is:"
292− ( binopHint op leftType rightType
309+ ( binopHint home op leftType rightType
294− [ "With operators like " <> varName op <> " I always check the left\
311+ [ "With operators like (" <> op <> ") I always check the left\
295 \ side first. If it seems fine, I assume it is correct and check the right\
312 \ side first. If it seems fine, I assume it is correct and check the right\
296 \ side. So the problem may be in how the left and right arguments interact."
313 \ side. So the problem may be in how the left and right arguments interact."
301− Binop op ->
318+ Binop _ op ->
304− ( "The two arguments to " <> varName op <>
321+ ( "The two arguments to (" <> op <>
305− " are fine, but the overall type of this expression\
322+ ") are fine, but the overall type of this expression\
306 \ does not match how it is used elsewhere."
323 \ does not match how it is used elsewhere."
308 ( cmpHint
325 ( cmpHint
@@ -329,7 +346,7 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
329 ( cmpHint
346 ( cmpHint
330 (capitalize (maybeFuncName maybeName) <> " is expecting the argument to be:")
347 (capitalize (maybeFuncName maybeName) <> " is expecting the argument to be:")
331 "But it is:"
348 "But it is:"
332− (functionHint maybeName)
349+ []
335 UnexpectedArg maybeName index _totalArgs region ->
352 UnexpectedArg maybeName index _totalArgs region ->
@@ -343,9 +360,7 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
343 <> ordinalize index <> " argument to be:"
360 <> ordinalize index <> " argument to be:"
345 "But it is:"
362 "But it is:"
346− ( functionHint maybeName
348− if index == 1 then
363+ ( if index == 1 then
351 [ "I always figure out the type of arguments from left to right. If an argument\
366 [ "I always figure out the type of arguments from left to right. If an argument\
@@ -430,34 +445,16 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
433− Pattern patErr ->
448+ Pattern context category ->
434− let
449+ let (overview, lineOne, lineTwo) = toPatternMessage context category in
435− thing =
450+ report Nothing overview (cmpHint lineOne lineTwo [])
438− "variable `" <> name <> "`"
440− PAlias name ->
452+ PatternCons ->
441− "alias `" <> name <> "`"
453+ report Nothing "This list pattern is mixing types:" $
446− PCtor (Var.Canonical Var.BuiltIn name) | Help.isTuple name ->
450− "tag `" <> Var.toText name <> "`"
454− ( capitalize thing <> " is causing problems in this pattern match."
456− ( cmpHint
454+ cmpHint
457− "The pattern matches things of type:"
455+ "The head of the list matches this type of value:"
458− "But the values it will actually be trying to match are:"
456+ "But the tail of the list matches:"
462 Shader ->
459 Shader ->
@@ -479,6 +476,15 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
481+ ("The ." <> field <> " accessor is being used in an unexpected way.")
484+ "But you are trying to use it as:"
482 Access (Just body) field ->
488 Access (Just body) field ->
484 header = "`" <> body <> "` does not have a field named `" <> field <> "`."
490 header = "`" <> body <> "` does not have a field named `" <> field <> "`."
@@ -511,6 +517,26 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
523+ "This “unit” value is being used in an unexpected way."
526+ "But you are trying to use it as:"
533+ "This tuple is being used in an unexpected way."
535+ "The tuple has type:"
536+ "But you are trying to use it as:"
514 Manager name ->
540 Manager name ->
@@ -551,6 +577,67 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
583+toPatternMessage :: PatternContext -> PatternCategory -> (Text, Text, Text)
584+toPatternMessage context category =
586+ PatternArg name index ->
587+ toPatternHelp category $
588+ "But as the " <> ordinalize index
589+ <> " value of a `" <> name <> "` pattern, it must be:"
592+ toPatternHelp category $
593+ "But as the pattern after a (::), it must be a list like: "
595+ PatternList index ->
596+ ( "The patterns in this list match different types of values:"
597+ , "The " <> ordinalize index <> " pattern matches type:"
598+ , "But all the previous patterns in the list match:"
602+ toPatternHelp category $
603+ "But the values flowing through here need to be:"
606+toPatternHelp :: PatternCategory -> Text -> (Text, Text, Text)
607+toPatternHelp category lineTwo =
610+ ( "This record pattern will cause problems:"
611+ , "It matches record values with this type:"
616+ ( "This “unit” pattern will cause problems:"
617+ , "It matches unit values with this type:"
622+ ( "This tuple pattern will cause problems:"
623+ , "It matches tuples with this type:"
628+ ( "This list pattern will cause problems:"
629+ , "It matches lists with this type:"
634+ ( "This `" <> name <> "` value will cause problems:"
635+ , "It matches `" <> name <> "` values with this type:"
554-- COMPARISON HINT
641-- COMPARISON HINT
@@ -592,48 +679,26 @@ jsonDecoderHint =
592-- BINOP HINTS
679-- BINOP HINTS
595−binopHint :: Var.Canonical -> Type.Canonical -> Type.Canonical -> [Text]
682+binopHint :: ModuleName.Canonical -> N.Name -> Type.Canonical -> Type.Canonical -> [Text]
596−binopHint op leftType rightType =
683+binopHint home op leftType rightType =
599− show (RenderType.toDoc Map.empty leftType)
685+ leftString = show (RenderType.toDoc Map.empty leftType)
602− show (RenderType.toDoc Map.empty rightType)
686+ rightString = show (RenderType.toDoc Map.empty rightType)
604− if Var.is "Basics" "+" op && elem "String" [leftString, rightString] then
688+ if home == ModuleName.basics && op == "+" && elem "String" [leftString, rightString] then
605− [ "To append strings in Elm, you need to use the (++) operator, not (+).\
689+ [ "To append strings in Elm, you need to use the (++) operator, not (+).\
606− \ <http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#++>"
690+ \ <http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#++>"
609− else if Var.is "Basics" "/" op && elem "Int" [leftString, rightString] then
610− [ "The (/) operator is specifically for floating point division, and (//) is\
611− \ for integer division. You may need to do some conversions between ints and\
612− \ floats to get both arguments matching the division operator you want."
693+ else if home == ModuleName.basics && op == "/" && elem "Int" [leftString, rightString] then
694+ [ "The (/) operator is specifically for floating point division, and (//) is\
695+ \ for integer division. You may need to do some conversions between ints and\
696+ \ floats to get both arguments matching the division operator you want."
623−functionHint :: Maybe Var.Canonical -> [Text]
699+ else
624−functionHint maybeName =
630− if Var.inHtml "Html" "program" == name then
631− [ "Does your program have flags? Maybe you want `programWithFlags` instead."
639-- ARITY HINTS
704-- ARITY HINTS
@@ -706,9 +771,6 @@ flipReason reason =
706 IntFloat ->
771 IntFloat ->
709− TooLongComparableTuple len ->
710− TooLongComparableTuple len
712 MissingArgs num ->
774 MissingArgs num ->
713 MissingArgs num
775 MissingArgs num
@@ -796,11 +858,6 @@ reasonToDocHelp reason =
796 \ `toFloat` and `round` to do specific conversions.\
858 \ `toFloat` and `round` to do specific conversions.\
797 \ <http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#toFloat>"
859 \ <http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#toFloat>"
799− TooLongComparableTuple len ->
801− "Although tuples are comparable, this is currently only supported\
802− \ for tuples with 6 or fewer entries, not " <> i2t len <> "."
804 MissingArgs num ->
861 MissingArgs num ->
805 simpleDoc $
862 simpleDoc $
806 "It looks like a function needs " <> Help.moreArgs num <> "."
863 "It looks like a function needs " <> Help.moreArgs num <> "."
@@ -867,11 +924,8 @@ specificThingToText specific =
867 SpecificSuper Type.CompAppend ->
924 SpecificSuper Type.CompAppend ->
868 "comparable AND appendable"
925 "comparable AND appendable"
870− SpecificType var@(Var.Canonical _ name) ->
927+ SpecificType name ->
871− if Var.isTuple var then
874− else if Text.isInfixOf (Text.take 1 name) "AEIOU" then
928+ if Text.isInfixOf (Text.take 1 name) "AEIOU" then
875 "an " <> name
929 "an " <> name
@@ -883,6 +937,12 @@ specificThingToText specific =
883 SpecificFunction ->
937 SpecificFunction ->
884 "a function"
938 "a function"
887badFieldElaboration :: Text
947badFieldElaboration :: Text
888badFieldElaboration =
948badFieldElaboration =
@@ -893,6 +953,9 @@ badFieldElaboration =
894messyFieldsHelp :: [Text] -> [Text] -> [Text] -> (Text, [Doc])
954messyFieldsHelp :: [Text] -> [Text] -> [Text] -> (Text, [Doc])
895messyFieldsHelp both leftOnly rightOnly =
955messyFieldsHelp both leftOnly rightOnly =
956+ error "TODO messyFieldsHelp" both leftOnly rightOnly
896 case (leftOnly, rightOnly) of
959 case (leftOnly, rightOnly) of
897 ([], [missingField]) ->
960 ([], [missingField]) ->
898 oneMissingField both missingField
961 oneMissingField both missingField
@@ -983,7 +1046,7 @@ padTypo arrow maxLen (missingField, knownField) =
983 <> dullyellow (text missingField)
1046 <> dullyellow (text missingField)
984 <+> text arrow
1047 <+> text arrow
985 <+> dullyellow (text knownField)
1048 <+> dullyellow (text knownField)
989-- INFINITE TYPES
1052-- INFINITE TYPES
@@ -1017,7 +1080,7 @@ infiniteTypeToReport localizer context overallType =
1020−infiniteHint :: Hint -> (Maybe Region.Region, Text)
1083+infiniteHint :: Hint -> (Maybe R.Region, Text)
1021infiniteHint hint =
1084infiniteHint hint =
1022 case hint of
1085 case hint of
1023 CaseBranch n region ->
1086 CaseBranch n region ->
@@ -1044,13 +1107,13 @@ infiniteHint hint =
1044 ListElement n region ->
1107 ListElement n region ->
1045 ( Just region, "the " <> ordinalize n <> " list entry" )
1108 ( Just region, "the " <> ordinalize n <> " list entry" )
1047− BinopLeft _ region ->
1110+ BinopLeft _ _ region ->
1048 ( Just region, "the left argument" )
1111 ( Just region, "the left argument" )
1050− BinopRight _ region ->
1113+ BinopRight _ _ region ->
1051 ( Just region, "the right argument" )
1114 ( Just region, "the right argument" )
1053− Binop _ ->
1116+ Binop _ _ ->
1054 ( Nothing, "this expression" )
1117 ( Nothing, "this expression" )
1056 Function maybeName ->
1119 Function maybeName ->
@@ -1074,7 +1137,10 @@ infiniteHint hint =
1074 Literal name ->
1137 Literal name ->
1075 ( Nothing, name )
1138 ( Nothing, name )
1077− Pattern _ ->
1140+ Pattern _ _ ->
1141+ ( Nothing, "this pattern" )
1078 ( Nothing, "this pattern" )
1144 ( Nothing, "this pattern" )
1080 Shader ->
1146 Shader ->
@@ -1083,12 +1149,21 @@ infiniteHint hint =
1083 Lambda ->
1149 Lambda ->
1084 ( Nothing, "this function" )
1150 ( Nothing, "this function" )
1153+ ( Nothing, "this record accessor" )
1086 Access _ _ ->
1155 Access _ _ ->
1087 ( Nothing, "this field access" )
1156 ( Nothing, "this field access" )
1089 Record ->
1158 Record ->
1090 ( Nothing, "this record" )
1159 ( Nothing, "this record" )
1162+ ( Nothing, "this “unit” value" )
1165+ ( Nothing, "this tuple" )
1092 -- effect manager problems
1167 -- effect manager problems
1093 Manager name ->
1168 Manager name ->
1094 ( Nothing, functionName name )
1169 ( Nothing, functionName name )