on master help sign in
Check in intermediate forms of error tracking code

The error types are shuffling around a bit as more things are caught and as the code for catching those errors moves from the validation phase to the canonicalization phase.

commitad7ff0b46b657c465c2c7562c4f8ab09dd613b01 authorEvan Czaplicki <evancz@users.noreply.github.com> dateMon 6 Nov 2017, 15:49 (9 years ago) parent9bdfe2b
2 files changed+375−275
src/Reporting/Error/Canonicalize.hs+179−154 src/Reporting/Error/Type.hs+196−121
src/Reporting/Error/Canonicalize.hs+179−154
@@ -2,31 +2,28 @@
22{-# LANGUAGE OverloadedStrings #-}
33module Reporting.Error.Canonicalize
44 ( Error(..)
5+ , Args(..)
56 , CtorType(..)
7+ , CycleNode(..)
8+ , InvalidPayload(..)
69 , variable
710 , VarKind(..)
811 , VarProblem(..)
9− , argMismatch
10− , port
1112 , toReport
1213 , extractSuggestions
1314 )
1415 where
1516
16−import Control.Arrow ((***))
17+
1718import qualified Data.Char as Char
18−import qualified Data.Map as Map
1919import qualified Data.Text as Text
2020import Data.Text (Text)
2121
22−import qualified AST.Binop as Binop
23−import qualified AST.Expression.Canonical as Canonical
24−import qualified AST.Module.Name as ModuleName
22+import qualified AST.Expression.Canonical as Can
2523import qualified AST.Type as Type
26−import qualified AST.Variable as Var
2724import qualified Elm.Name as N
2825import qualified Reporting.Annotation as A
29−import qualified Reporting.Region as Region
26+import qualified Reporting.Region as R
3027import qualified Reporting.Render.Type as RenderType
3128import qualified Reporting.Report as Report
3229import qualified Reporting.Helpers as Help
@@ -38,29 +35,43 @@ import Reporting.Helpers ( Doc, (<>), dullyellow, fillSep, green, i2t, indent, r
3835
3936
4037data Error
41− = Var VarError
42− | AliasArgMismatch Var.Canonical Int Int
43− | AliasRecursion N.Name [N.Name] Type.Raw [N.Name]
44− | BadRecursion Region.Region Canonical.Def [Canonical.Def]
45− | BadInfix Region.Region Int Var.Canonical Binop.Associativity Var.Canonical Binop.Associativity
46− | Pattern PatternError
47− | DuplicateDecl N.Name
48− | DuplicateType N.Name
49− | DuplicateCtor N.Name CtorType CtorType
50− | DuplicateBinop N.Name
51− | DuplicateField N.Name
52− | DuplicateAliasArg N.Name N.Name [N.Name]
53− | DuplicateUnionArg N.Name N.Name [N.Name]
54− | ImportNotFound ModuleName.Raw [ModuleName.Raw]
55− | ImportCtorNotFound N.Name N.Name
56− | ImportOpenAlias N.Name
57− | ImportExposingNotFound ModuleName.Raw N.Name [N.Name]
58− | Export Text [Text]
59− | DuplicateExport Text
60− | Port PortError
61− | BadPort Text Type.Canonical
62− | TypeVarsUnboundInUnion N.Name [N.Name] [A.Located N.Name]
63− | TypeVarsMessedUpInAlias N.Name [N.Name] [A.Located N.Name] [A.Located N.Name]
38+ = Var VarError
39+ | Binop N.Name N.Name
40+ | DuplicateArg N.Name
41+ | DuplicateDecl N.Name
42+ | DuplicateType N.Name
43+ | DuplicateCtor N.Name CtorType CtorType
44+ | DuplicateBinop N.Name
45+ | DuplicateField N.Name
46+ | DuplicateAliasArg N.Name N.Name [N.Name]
47+ | DuplicateUnionArg N.Name N.Name [N.Name]
48+ | DuplicateBindingName N.Name
49+ | EffectNotFound N.Name
50+ | EffectFunctionNotFound N.Name
51+ | ExportDuplicate N.Name
52+ | ExportNotFound VarKind N.Name [N.Name]
53+ | ExportOpenAlias N.Name
54+ | ImportNotFound N.Name [N.Name]
55+ | ImportCtorNotFound N.Name N.Name
56+ | ImportOpenAlias N.Name
57+ | ImportExposingNotFound N.Name N.Name [N.Name]
58+ | PortPayloadInvalid N.Name Type.Canonical InvalidPayload
59+ | PortTypeInvalid N.Name Type.Canonical
60+ | RecursiveAlias N.Name [N.Name] Type.Raw [N.Name]
61+ | RecursiveDecl R.Region N.Name [N.Name]
62+ | RecursiveLet [CycleNode]
63+ | Shadowing N.Name
64+ | TooFew Args N.Name Int Int
65+ | TooMany Args N.Name Int Int R.Region
66+ | TupleLargerThanThree R.Region
67+ | TypeVarsUnboundInUnion N.Name [N.Name] [A.Located N.Name]
68+ | TypeVarsMessedUpInAlias N.Name [N.Name] [A.Located N.Name] [A.Located N.Name]
69+
70+
71+data Args
72+ = UnionArgs
73+ | AliasArgs
74+ | PatternArgs
6475
6576
6677data CtorType
@@ -68,6 +79,19 @@ data CtorType
6879 | RecordCtor
6980
7081
82+data CycleNode
83+ = CycleFunc (A.Located N.Name)
84+ | CycleValue (A.Located N.Name)
85+ | CyclePattern Can.Pattern
86+
87+
88+data InvalidPayload
89+ = ExtendedRecord
90+ | Function
91+ | TypeVariable N.Name
92+ | UnsupportedType N.Name
93+
94+
7195
7296-- VARIABLES
7397
@@ -121,36 +145,6 @@ toKindInfo kind name =
121145
122146
123147
124−-- PATTERN
125−
126−
127−data PatternError
128− = PatternArgMismatch Var.Canonical Int Int
129−
130−
131−argMismatch :: Var.Canonical -> Int -> Int -> Error
132−argMismatch name expected actual =
133− Pattern (PatternArgMismatch name expected actual)
134−
135−
136−
137−-- PORTS
138−
139−
140−data PortError =
141− PortError
142− { _portName :: Text
143− , _portType :: Type.Canonical
144− , _portMessage :: Maybe Text
145− }
146−
147−
148−port :: Text -> Type.Canonical -> Maybe Text -> Error
149−port name tipe maybeMessage =
150− Port (PortError name tipe maybeMessage)
151−
152−
153−
154148-- EXTRACT SUGGESTIONS
155149
156150
@@ -160,16 +154,10 @@ extractSuggestions err =
160154 Var (VarError _ _ _ suggestions) ->
161155 Just suggestions
162156
163− AliasArgMismatch _ _ _ ->
164− Nothing
165−
166− AliasRecursion _ _ _ _ ->
167− Nothing
168−
169− BadRecursion _ _ _ ->
157+ Binop _ _ ->
170158 Nothing
171159
172− BadInfix _ _ _ _ _ _ ->
160+ DuplicateArg _ ->
173161 Nothing
174162
175163 DuplicateDecl _ ->
@@ -193,11 +181,26 @@ extractSuggestions err =
193181 DuplicateUnionArg _ _ _ ->
194182 Nothing
195183
196− Pattern _ ->
184+ DuplicateBindingName _ ->
185+ Nothing
186+
187+ EffectNotFound _ ->
188+ Nothing
189+
190+ EffectFunctionNotFound _ ->
191+ Nothing
192+
193+ ExportDuplicate _ ->
194+ Nothing
195+
196+ ExportNotFound _ _ suggestions ->
197+ Just suggestions
198+
199+ ExportOpenAlias _ ->
197200 Nothing
198201
199202 ImportNotFound _ suggestions ->
200− Just (map ModuleName.toText suggestions)
203+ Just suggestions
201204
202205 ImportExposingNotFound _ _ suggestions ->
203206 Just suggestions
@@ -208,16 +211,31 @@ extractSuggestions err =
208211 ImportOpenAlias _ ->
209212 Nothing
210213
211− Export _ suggestions ->
212− Just suggestions
214+ PortPayloadInvalid _ _ _ ->
215+ Nothing
216+
217+ PortTypeInvalid _ _ ->
218+ Nothing
219+
220+ RecursiveAlias _ _ _ _ ->
221+ Nothing
222+
223+ RecursiveDecl _ _ _ ->
224+ Nothing
225+
226+ RecursiveLet _ ->
227+ Nothing
213228
214− DuplicateExport _ ->
229+ Shadowing _ ->
215230 Nothing
216231
217− Port _ ->
232+ TooFew _ _ _ _ ->
218233 Nothing
219234
220− BadPort _ _ ->
235+ TooMany _ _ _ _ _ ->
236+ Nothing
237+
238+ TupleLargerThanThree _ ->
221239 Nothing
222240
223241 TypeVarsUnboundInUnion _ _ _ ->
@@ -237,19 +255,11 @@ toReport localizer err =
237255 Var varError ->
238256 varErrorToReport varError
239257
240− BadRecursion region def defs ->
241− case defs of
242− [] ->
243− badSelfRecursion region (defToText def)
244−
245− _ ->
246− badMutualRecursion region (defToText def) (map (defToText) defs)
247−
248− BadInfix region _prec (Var.Canonical _ name1) _assoc1 (Var.Canonical _ name2) _assoc2 ->
258+ Binop op1 op2 ->
249259 Report.report
250260 "INFIX PROBLEM"
251− (Just region)
252− ("You cannot mix (" <> name1 <> ") and (" <> name2 <> ") without parentheses." )
261+ Nothing
262+ ("You cannot mix (" <> op1 <> ") and (" <> op2 <> ") without parentheses." )
253263 (
254264 Help.stack
255265 [ reflowParagraph $
@@ -257,6 +267,9 @@ toReport localizer err =
257267 ]
258268 )
259269
270+ DuplicateArg _ ->
271+ error "TODO DuplicateArg"
272+
260273 DuplicateDecl _ ->
261274 error "TODO DuplicateDecl"
262275
@@ -278,20 +291,34 @@ toReport localizer err =
278291 DuplicateUnionArg _ _ _ ->
279292 error "TODO DuplicateUnionArg"
280293
281− Pattern patternError ->
282− case patternError of
283− PatternArgMismatch var expected actual ->
284− argMismatchReport "Pattern" var expected actual
294+ DuplicateBindingName _ ->
295+ error "TODO DuplicateBindingName"
285296
286− AliasArgMismatch var expected actual ->
287− argMismatchReport "Type" var expected actual
297+ EffectNotFound _ ->
298+ error "TODO EffectNotFound"
288299
289− AliasRecursion name args tipe others ->
290− aliasRecursionReport localizer name args tipe others
300+ EffectFunctionNotFound _ ->
301+ error "TODO EffectFunctionNotFound"
302+
303+ ExportDuplicate name ->
304+ Report.report "EXPOSING ERROR" Nothing
305+ ("You are trying to expose `" <> name <> "` multiple times!")
306+ "Remove duplicates until there is only one listed."
307+
308+ ExportNotFound kind rawName suggestions ->
309+ let (a, thing, name) = toKindInfo kind rawName in
310+ Report.reportDoc "EXPOSING ERROR" Nothing
311+ ["You","are","trying","to","expose",a,thing,"named"
312+ ,name,"but","I","cannot","find","its","definition."
313+ ]
314+ (Help.maybeYouWant Nothing suggestions)
315+
316+ ExportOpenAlias name ->
317+ error "TODO" name
291318
292319 ImportNotFound name suggestions ->
293320 Report.report "IMPORT ERROR" Nothing
294− ("Could not find a module named `" <> ModuleName.toText name <> "`")
321+ ("Could not find a module named `" <> name <> "`")
295322 (Help.maybeYouWant Nothing suggestions)
296323
297324 ImportCtorNotFound ctor tipe ->
@@ -320,30 +347,33 @@ toReport localizer err =
320347
321348 ImportExposingNotFound name value suggestions ->
322349 Report.report "IMPORT ERROR" Nothing
323− ("Module `" <> ModuleName.toText name <> "` does not expose `" <> value <> "`")
324− (Help.maybeYouWant Nothing suggestions)
325−
326− Export name suggestions ->
327− Report.report "EXPOSING ERROR" Nothing
328− ("Could not expose `" <> name <> "` which is not defined in this module.")
350+ ("Module `" <> name <> "` does not expose `" <> value <> "`")
329351 (Help.maybeYouWant Nothing suggestions)
330352
331− DuplicateExport name ->
332− Report.report "EXPOSING ERROR" Nothing
333− ("You are trying to expose `" <> name <> "` multiple times!")
334− "Remove duplicates until there is only one listed."
335−
336− Port (PortError name tipe maybeMessage) ->
353+ PortPayloadInvalid portName tipe invalidPayload ->
337354 let
338355 context =
339− maybe "" (" the following " <> ) maybeMessage
356+ case invalidPayload of
357+ ExtendedRecord ->
358+ "an extended record"
359+
360+ Function ->
361+ "a function"
362+
363+ TypeVariable name ->
364+ const "an unknown type" (error "TODO" name)
365+ -- "Notice the `" <> name <> "` type variable. It must be a concrete type, like Int or Float."
366+
367+ UnsupportedType name ->
368+ "a `" <> name <> "` value"
340369 in
341370 Report.report
342371 "PORT ERROR"
343372 Nothing
344− ("Port `" <> name <> "` is trying to communicate an unsupported type."
373+ ("Port `" <> portName <> "` is trying to transmit " <> context <> ":"
345374 )
346− ( Help.stack
375+ (error "TODO" tipe)
376+ {- Help.stack
347377 [ text ("The specific unsupported type is" <> context <> ":")
348378 , indent 4 (RenderType.toDoc localizer tipe)
349379 , text "The types of values that can flow through in and out of Elm include:"
@@ -352,9 +382,9 @@ toReport localizer err =
352382 \ Tuples, Json.Values, and concrete records."
353383 -- TODO add a note about custom decoders and encoders when they exist!
354384 ]
355− )
385+ -}
356386
357− BadPort name tipe ->
387+ PortTypeInvalid name tipe ->
358388 Report.report
359389 "PORT ERROR"
360390 Nothing
@@ -369,6 +399,35 @@ toReport localizer err =
369399 ]
370400 )
371401
402+ RecursiveAlias name args tipe others ->
403+ aliasRecursionReport localizer name args tipe others
404+
405+ RecursiveDecl region name names ->
406+ error "TODO" region name names
407+
408+ RecursiveLet cycles ->
409+ case cycles of
410+ [] ->
411+ error "TODO"
412+
413+ [_] ->
414+ error "TODO" badSelfRecursion
415+
416+ _ ->
417+ error "TODO" badMutualRecursion
418+
419+ Shadowing _ ->
420+ error "TODO Shadowing"
421+
422+ TooFew _ _ _ _ ->
423+ error "TODO TooFew"
424+
425+ TooMany _ _ _ _ _ ->
426+ error "TODO TooMany"
427+
428+ TupleLargerThanThree _ ->
429+ error "TODO TupleLargerThanThree"
430+
372431 TypeVarsUnboundInUnion _ _ _ ->
373432 error "TODO TypeVarsUnboundInUnion"
374433
@@ -377,8 +436,6 @@ toReport localizer err =
377436
378437
379438
380−
381−
382439-- VAR ERROR
383440
384441
@@ -467,8 +524,8 @@ modHint =
467524-- ARG MISMATCH
468525
469526
470−argMismatchReport :: Text -> Var.Canonical -> Int -> Int -> Report.Report
471−argMismatchReport kind var expected actual =
527+_argMismatchReport :: Text -> N.Name -> Int -> Int -> Report.Report
528+_argMismatchReport kind name expected actual =
472529 let
473530 numArgs =
474531 "too "
@@ -478,7 +535,7 @@ argMismatchReport kind var expected actual =
478535 Report.report
479536 (Text.map Char.toUpper numArgs)
480537 Nothing
481− ( kind <> " " <> Var.toText var <> " has " <> numArgs <> "."
538+ ( kind <> " " <> name <> " has " <> numArgs <> "."
482539 )
483540 ( text $
484541 "Expecting " <> i2t expected <> ", but got " <> i2t actual <> "."
@@ -489,7 +546,7 @@ argMismatchReport kind var expected actual =
489546-- BAD RECURSION
490547
491548
492−badSelfRecursion :: Region.Region -> Text -> Report.Report
549+badSelfRecursion :: R.Region -> Text -> Report.Report
493550badSelfRecursion region name =
494551 let
495552 header =
@@ -517,7 +574,7 @@ badSelfRecursionHelp intro body =
517574 ++ map text (Text.words body)
518575
519576
520−badMutualRecursion :: Region.Region -> Text -> [Text] -> Report.Report
577+badMutualRecursion :: R.Region -> Text -> [Text] -> Report.Report
521578badMutualRecursion region name names =
522579 let
523580 header =
@@ -535,11 +592,6 @@ badMutualRecursion region name names =
535592 ]
536593
537594
538−defToText :: Canonical.Def -> Text
539−defToText (Canonical.Def _ pattern _ _) =
540− error "TODO P.toText" pattern
541−
542−
543595
544596-- BAD ALIAS RECURSION
545597
@@ -556,7 +608,7 @@ aliasRecursionReport localizer name args tipe others =
556608 "When I expand a recursive type alias, it just keeps getting bigger and bigger.\
557609 \ So dealiasing results in an infinitely large type! Try this instead:"
558610 , indent 4 $
559− RenderType.decl localizer name args [(name, [unsafePromote tipe])]
611+ RenderType.decl localizer name args [(name, [error "TODO" tipe])]
560612 , text $
561613 "This is kind of a subtle distinction. I suggested the naive fix, but you can\n"
562614 <> "often do something a bit nicer. So I would recommend reading more at:\n"
@@ -576,30 +628,3 @@ aliasRecursionReport localizer name args tipe others =
576628 <> Help.hintLink "recursive-alias"
577629 ]
578630 )
579−
580−
581−unsafePromote :: Type.Raw -> Type.Canonical
582−unsafePromote (A.A _ rawType) =
583− case rawType of
584− Type.RLambda arg result ->
585− Type.Lambda (unsafePromote arg) (unsafePromote result)
586−
587− Type.RVar x ->
588− Type.Var x
589−
590− Type.RType _ _ name args ->
591− Type.Type (error "TODO unsafePromote better") name (map unsafePromote args)
592−
593− Type.RRecord fields ext ->
594− Type.Record
595− (Map.fromList (map (A.drop *** unsafePromote) fields))
596− (fmap unsafePromote ext)
597−
598− Type.RUnit ->
599− Type.Unit
600−
601− Type.RTuple a b cs ->
602− Type.Tuple
603− (unsafePromote a)
604− (unsafePromote b)
605− (map unsafePromote cs)
src/Reporting/Error/Type.hs+196−121
@@ -2,9 +2,12 @@
22{-# LANGUAGE OverloadedStrings #-}
33module Reporting.Error.Type
44 ( Error(..)
5− , Mismatch(..), Hint(..)
6− , Reason(..), SpecificThing(..)
7− , Pattern(..)
5+ , Mismatch(..)
6+ , Hint(..)
7+ , Reason(..)
8+ , SpecificThing(..)
9+ , PatternContext(..)
10+ , PatternCategory(..)
811 , toReport
912 , flipReason
1013 )
@@ -16,15 +19,16 @@ import qualified Data.Text as Text
1619import Data.Text (Text)
1720import Data.Monoid ((<>))
1821
19−import qualified AST.Helpers as Help
22+import qualified AST.Module.Name as ModuleName
2023import qualified AST.Type as Type
2124import 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
2327import qualified Reporting.Render.Type as RenderType
2428import qualified Reporting.Report as Report
2529import qualified Reporting.Helpers as Help
2630import Reporting.Helpers
27− ( Doc, (<+>), capitalize, dullyellow, functionName, i2t
31+ ( Doc, capitalize, dullyellow, functionName, i2t
2832 , indent, ordinalize, reflowParagraph, stack, text
2933 )
3034
@@ -54,7 +58,6 @@ data Reason
5458 = BadFields [(Text, Maybe Reason)]
5559 | MessyFields [Text] [Text] [Text]
5660 | IntFloat
57− | TooLongComparableTuple Int
5861 | MissingArgs Int
5962 | RigidClash Text Text
6063 | NotPartOfSuper Type.Super
@@ -64,45 +67,59 @@ data Reason
6467
6568data SpecificThing
6669 = SpecificSuper Type.Super
67− | SpecificType Var.Canonical
70+ | SpecificType N.Name
6871 | SpecificFunction
6972 | SpecificRecord
73+ | SpecificUnit
74+ | SpecificTuple
7075
7176
7277data Hint
73− = CaseBranch Int Region.Region
78+ = CaseBranch Int R.Region
7479 | Case
7580 | IfCondition
7681 | IfBranches
77− | MultiIfBranch Int Region.Region
82+ | MultiIfBranch Int R.Region
7883 | If
7984 | List
80− | ListElement Int Region.Region
81− | BinopLeft Var.Canonical Region.Region
82− | BinopRight Var.Canonical Region.Region
83− | Binop Var.Canonical
85+ | ListElement Int R.Region
86+ | BinopLeft ModuleName.Canonical N.Name R.Region
87+ | BinopRight ModuleName.Canonical N.Name R.Region
88+ | Binop ModuleName.Canonical N.Name
8489 | Function (Maybe Var.Canonical)
85− | UnexpectedArg (Maybe Var.Canonical) Int Int Region.Region
86− | FunctionArity (Maybe Var.Canonical) Int Int Region.Region
87− | ReturnType Text Int Int Region.Region
90+ | UnexpectedArg (Maybe Var.Canonical) Int Int R.Region
91+ | FunctionArity (Maybe Var.Canonical) Int Int R.Region
92+ | ReturnType Text Int Int R.Region
8893 | Instance Text
8994 | Literal Text
90− | Pattern Pattern
95+ | Pattern PatternContext PatternCategory
96+ | PatternCons
9197 | Shader
9298 | Lambda
99+ | Accessor Text
93100 | Access (Maybe Text) Text
94101 | Record
102+ | Unit
103+ | Tuple
95104 -- effect manager problems
96105 | Manager Text
97106 | State Text
98107 | SelfMsg
99108
100109
101−data Pattern
102− = PVar Text
103− | PAlias Text
104− | PCtor Var.Canonical
105− | PRecord
110+data PatternContext
111+ = PatternArg N.Name Int
112+ | PatternTail
113+ | PatternList Int
114+ | PatternUnknown
115+
116+
117+data PatternCategory
118+ = PRecord
119+ | PUnit
120+ | PTuple
121+ | PList
122+ | PCtor N.Name
106123
107124
108125
@@ -272,37 +289,37 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
272289 []
273290 )
274291
275− BinopLeft op region ->
292+ BinopLeft home op region ->
276293 report
277294 (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.")
279296 ( cmpHint
280− (varName op <> " is expecting the left argument to be a:")
297+ ("(" <> op <> ") is expecting the left argument to be a:")
281298 "But the left argument is:"
282− (binopHint op leftType rightType)
299+ (binopHint home op leftType rightType)
283300 )
284301
285− BinopRight op region ->
302+ BinopRight home op region ->
286303 report
287304 (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.")
289306 ( cmpHint
290− (varName op <> " is expecting the right side to be a:")
307+ ("(" <> op <> ") is expecting the right side to be a:")
291308 "But the right side is:"
292− ( binopHint op leftType rightType
309+ ( binopHint home op leftType rightType
293310 ++
294− [ "With operators like " <> varName op <> " I always check the left\
311+ [ "With operators like (" <> op <> ") I always check the left\
295312 \ side first. If it seems fine, I assume it is correct and check the right\
296313 \ side. So the problem may be in how the left and right arguments interact."
297314 ]
298315 )
299316 )
300317
301− Binop op ->
318+ Binop _ op ->
302319 report
303320 Nothing
304− ( "The two arguments to " <> varName op <>
305− " are fine, but the overall type of this expression\
321+ ( "The two arguments to (" <> op <>
322+ ") are fine, but the overall type of this expression\
306323 \ does not match how it is used elsewhere."
307324 )
308325 ( cmpHint
@@ -329,7 +346,7 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
329346 ( cmpHint
330347 (capitalize (maybeFuncName maybeName) <> " is expecting the argument to be:")
331348 "But it is:"
332− (functionHint maybeName)
349+ []
333350 )
334351
335352 UnexpectedArg maybeName index _totalArgs region ->
@@ -343,9 +360,7 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
343360 <> ordinalize index <> " argument to be:"
344361 )
345362 "But it is:"
346− ( functionHint maybeName
347− ++
348− if index == 1 then
363+ ( if index == 1 then
349364 []
350365 else
351366 [ "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
430445 []
431446 )
432447
433− Pattern patErr ->
434− let
435− thing =
436− case patErr of
437− PVar name ->
438− "variable `" <> name <> "`"
448+ Pattern context category ->
449+ let (overview, lineOne, lineTwo) = toPatternMessage context category in
450+ report Nothing overview (cmpHint lineOne lineTwo [])
439451
440− PAlias name ->
441− "alias `" <> name <> "`"
442−
443− PRecord ->
444− "this record"
445−
446− PCtor (Var.Canonical Var.BuiltIn name) | Help.isTuple name ->
447− "this tuple"
448−
449− PCtor name ->
450− "tag `" <> Var.toText name <> "`"
451− in
452− report
453− Nothing
454− ( capitalize thing <> " is causing problems in this pattern match."
455− )
456− ( cmpHint
457− "The pattern matches things of type:"
458− "But the values it will actually be trying to match are:"
459− []
460− )
452+ PatternCons ->
453+ report Nothing "This list pattern is mixing types:" $
454+ cmpHint
455+ "The head of the list matches this type of value:"
456+ "But the tail of the list matches:"
457+ []
461458
462459 Shader ->
463460 report
@@ -479,6 +476,15 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
479476 []
480477 )
481478
479+ Accessor field ->
480+ report Nothing
481+ ("The ." <> field <> " accessor is being used in an unexpected way.")
482+ ( cmpHint
483+ "It has type:"
484+ "But you are trying to use it as:"
485+ []
486+ )
487+
482488 Access (Just body) field ->
483489 let
484490 header = "`" <> body <> "` does not have a field named `" <> field <> "`."
@@ -511,6 +517,26 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
511517 []
512518 )
513519
520+ Unit ->
521+ report
522+ Nothing
523+ "This “unit” value is being used in an unexpected way."
524+ ( cmpHint
525+ "It has type:"
526+ "But you are trying to use it as:"
527+ []
528+ )
529+
530+ Tuple ->
531+ report
532+ Nothing
533+ "This tuple is being used in an unexpected way."
534+ ( cmpHint
535+ "The tuple has type:"
536+ "But you are trying to use it as:"
537+ []
538+ )
539+
514540 Manager name ->
515541 report
516542 Nothing
@@ -551,6 +577,67 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
551577
552578
553579
580+-- PATTERN REPORT
581+
582+
583+toPatternMessage :: PatternContext -> PatternCategory -> (Text, Text, Text)
584+toPatternMessage context category =
585+ case context of
586+ PatternArg name index ->
587+ toPatternHelp category $
588+ "But as the " <> ordinalize index
589+ <> " value of a `" <> name <> "` pattern, it must be:"
590+
591+ PatternTail ->
592+ toPatternHelp category $
593+ "But as the pattern after a (::), it must be a list like: "
594+
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:"
599+ )
600+
601+ PatternUnknown ->
602+ toPatternHelp category $
603+ "But the values flowing through here need to be:"
604+
605+
606+toPatternHelp :: PatternCategory -> Text -> (Text, Text, Text)
607+toPatternHelp category lineTwo =
608+ case category of
609+ PRecord ->
610+ ( "This record pattern will cause problems:"
611+ , "It matches record values with this type:"
612+ , lineTwo
613+ )
614+
615+ PUnit ->
616+ ( "This “unit” pattern will cause problems:"
617+ , "It matches unit values with this type:"
618+ , lineTwo
619+ )
620+
621+ PTuple ->
622+ ( "This tuple pattern will cause problems:"
623+ , "It matches tuples with this type:"
624+ , lineTwo
625+ )
626+
627+ PList ->
628+ ( "This list pattern will cause problems:"
629+ , "It matches lists with this type:"
630+ , lineTwo
631+ )
632+
633+ PCtor name ->
634+ ( "This `" <> name <> "` value will cause problems:"
635+ , "It matches `" <> name <> "` values with this type:"
636+ , lineTwo
637+ )
638+
639+
640+
554641-- COMPARISON HINT
555642
556643
@@ -592,48 +679,26 @@ jsonDecoderHint =
592679-- BINOP HINTS
593680
594681
595−binopHint :: Var.Canonical -> Type.Canonical -> Type.Canonical -> [Text]
596−binopHint op leftType rightType =
682+binopHint :: ModuleName.Canonical -> N.Name -> Type.Canonical -> Type.Canonical -> [Text]
683+binopHint home op leftType rightType =
597684 let
598− leftString =
599− show (RenderType.toDoc Map.empty leftType)
600−
601− rightString =
602− show (RenderType.toDoc Map.empty rightType)
685+ leftString = show (RenderType.toDoc Map.empty leftType)
686+ rightString = show (RenderType.toDoc Map.empty rightType)
603687 in
604− if Var.is "Basics" "+" op && elem "String" [leftString, rightString] then
605− [ "To append strings in Elm, you need to use the (++) operator, not (+).\
606− \ <http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#++>"
607− ]
608−
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."
613− ]
614−
615− else
616− []
617−
618−
619−
620−-- FUNCTION HINTS
688+ if home == ModuleName.basics && op == "+" && elem "String" [leftString, rightString] then
689+ [ "To append strings in Elm, you need to use the (++) operator, not (+).\
690+ \ <http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#++>"
691+ ]
621692
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."
697+ ]
622698
623−functionHint :: Maybe Var.Canonical -> [Text]
624−functionHint maybeName =
625− case maybeName of
626− Nothing ->
699+ else
627700 []
628701
629− Just name ->
630− if Var.inHtml "Html" "program" == name then
631− [ "Does your program have flags? Maybe you want `programWithFlags` instead."
632− ]
633−
634− else
635− []
636−
637702
638703
639704-- ARITY HINTS
@@ -706,9 +771,6 @@ flipReason reason =
706771 IntFloat ->
707772 IntFloat
708773
709− TooLongComparableTuple len ->
710− TooLongComparableTuple len
711−
712774 MissingArgs num ->
713775 MissingArgs num
714776
@@ -796,11 +858,6 @@ reasonToDocHelp reason =
796858 \ `toFloat` and `round` to do specific conversions.\
797859 \ <http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#toFloat>"
798860
799− TooLongComparableTuple len ->
800− simpleDoc $
801− "Although tuples are comparable, this is currently only supported\
802− \ for tuples with 6 or fewer entries, not " <> i2t len <> "."
803−
804861 MissingArgs num ->
805862 simpleDoc $
806863 "It looks like a function needs " <> Help.moreArgs num <> "."
@@ -867,11 +924,8 @@ specificThingToText specific =
867924 SpecificSuper Type.CompAppend ->
868925 "comparable AND appendable"
869926
870− SpecificType var@(Var.Canonical _ name) ->
871− if Var.isTuple var then
872− "a tuple"
873−
874− else if Text.isInfixOf (Text.take 1 name) "AEIOU" then
927+ SpecificType name ->
928+ if Text.isInfixOf (Text.take 1 name) "AEIOU" then
875929 "an " <> name
876930
877931 else
@@ -883,6 +937,12 @@ specificThingToText specific =
883937 SpecificFunction ->
884938 "a function"
885939
940+ SpecificUnit ->
941+ "a unit value"
942+
943+ SpecificTuple ->
944+ "a tuple"
945+
886946
887947badFieldElaboration :: Text
888948badFieldElaboration =
@@ -893,6 +953,9 @@ badFieldElaboration =
893953
894954messyFieldsHelp :: [Text] -> [Text] -> [Text] -> (Text, [Doc])
895955messyFieldsHelp both leftOnly rightOnly =
956+ error "TODO messyFieldsHelp" both leftOnly rightOnly
957+
958+{-
896959 case (leftOnly, rightOnly) of
897960 ([], [missingField]) ->
898961 oneMissingField both missingField
@@ -983,7 +1046,7 @@ padTypo arrow maxLen (missingField, knownField) =
9831046 <> dullyellow (text missingField)
9841047 <+> text arrow
9851048 <+> dullyellow (text knownField)
986−
1049+-}
9871050
9881051
9891052-- INFINITE TYPES
@@ -1017,7 +1080,7 @@ infiniteTypeToReport localizer context overallType =
10171080 )
10181081
10191082
1020−infiniteHint :: Hint -> (Maybe Region.Region, Text)
1083+infiniteHint :: Hint -> (Maybe R.Region, Text)
10211084infiniteHint hint =
10221085 case hint of
10231086 CaseBranch n region ->
@@ -1044,13 +1107,13 @@ infiniteHint hint =
10441107 ListElement n region ->
10451108 ( Just region, "the " <> ordinalize n <> " list entry" )
10461109
1047− BinopLeft _ region ->
1110+ BinopLeft _ _ region ->
10481111 ( Just region, "the left argument" )
10491112
1050− BinopRight _ region ->
1113+ BinopRight _ _ region ->
10511114 ( Just region, "the right argument" )
10521115
1053− Binop _ ->
1116+ Binop _ _ ->
10541117 ( Nothing, "this expression" )
10551118
10561119 Function maybeName ->
@@ -1074,7 +1137,10 @@ infiniteHint hint =
10741137 Literal name ->
10751138 ( Nothing, name )
10761139
1077− Pattern _ ->
1140+ Pattern _ _ ->
1141+ ( Nothing, "this pattern" )
1142+
1143+ PatternCons ->
10781144 ( Nothing, "this pattern" )
10791145
10801146 Shader ->
@@ -1083,12 +1149,21 @@ infiniteHint hint =
10831149 Lambda ->
10841150 ( Nothing, "this function" )
10851151
1152+ Accessor _ ->
1153+ ( Nothing, "this record accessor" )
1154+
10861155 Access _ _ ->
10871156 ( Nothing, "this field access" )
10881157
10891158 Record ->
10901159 ( Nothing, "this record" )
10911160
1161+ Unit ->
1162+ ( Nothing, "this “unit” value" )
1163+
1164+ Tuple ->
1165+ ( Nothing, "this tuple" )
1166+
10921167 -- effect manager problems
10931168 Manager name ->
10941169 ( Nothing, functionName name )