on master help sign in
Check in intermediate forms of error tracking code
ad7ff0bEvan Czaplicki
src/Reporting/Error/Canonicalize.hs+179−154
@@ -2,31 +2,28 @@
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Canonicalize
3module Reporting.Error.Canonicalize
4 ( Error(..)
4 ( Error(..)
5+ , Args(..)
5 , CtorType(..)
6 , CtorType(..)
7+ , CycleNode(..)
8+ , InvalidPayload(..)
6 , variable
9 , variable
7 , VarKind(..)
10 , VarKind(..)
8 , VarProblem(..)
11 , VarProblem(..)
9− , argMismatch
10− , port
11 , toReport
12 , toReport
12 , extractSuggestions
13 , extractSuggestions
13 )
14 )
14 where
15 where
15
16
16−import Control.Arrow ((***))
17+
17import qualified Data.Char as Char
18import qualified Data.Char as Char
18−import qualified Data.Map as Map
19import qualified Data.Text as Text
19import qualified Data.Text as Text
20import Data.Text (Text)
20import Data.Text (Text)
21
21
22−import qualified AST.Binop as Binop
22+import qualified AST.Expression.Canonical as Can
23−import qualified AST.Expression.Canonical as Canonical
24−import qualified AST.Module.Name as ModuleName
25import qualified AST.Type as Type
23import qualified AST.Type as Type
26−import qualified AST.Variable as Var
27import qualified Elm.Name as N
24import qualified Elm.Name as N
28import qualified Reporting.Annotation as A
25import qualified Reporting.Annotation as A
29−import qualified Reporting.Region as Region
26+import qualified Reporting.Region as R
30import qualified Reporting.Render.Type as RenderType
27import qualified Reporting.Render.Type as RenderType
31import qualified Reporting.Report as Report
28import qualified Reporting.Report as Report
32import qualified Reporting.Helpers as Help
29import qualified Reporting.Helpers as Help
@@ -38,29 +35,43 @@ import Reporting.Helpers ( Doc, (<>), dullyellow, fillSep, green, i2t, indent, r
38
35
39
36
40data Error
37data Error
41− = Var VarError
38+ = Var VarError
42− | AliasArgMismatch Var.Canonical Int Int
39+ | Binop N.Name N.Name
43− | AliasRecursion N.Name [N.Name] Type.Raw [N.Name]
40+ | DuplicateArg 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
41+ | DuplicateDecl N.Name
48− | DuplicateType N.Name
42+ | DuplicateType N.Name
49− | DuplicateCtor N.Name CtorType CtorType
43+ | DuplicateCtor N.Name CtorType CtorType
50− | DuplicateBinop N.Name
44+ | DuplicateBinop N.Name
51− | DuplicateField N.Name
45+ | DuplicateField N.Name
52− | DuplicateAliasArg N.Name N.Name [N.Name]
46+ | DuplicateAliasArg N.Name N.Name [N.Name]
53− | DuplicateUnionArg 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 ModuleName.Raw [ModuleName.Raw]
54+ | ImportNotFound N.Name [N.Name]
55− | ImportCtorNotFound N.Name N.Name
55+ | ImportCtorNotFound N.Name N.Name
56− | ImportOpenAlias N.Name
56+ | ImportOpenAlias N.Name
57− | ImportExposingNotFound ModuleName.Raw N.Name [N.Name]
57+ | ImportExposingNotFound N.Name N.Name [N.Name]
58− | Export Text [Text]
58+ | PortPayloadInvalid N.Name Type.Canonical InvalidPayload
59− | DuplicateExport Text
59+ | PortTypeInvalid N.Name Type.Canonical
60− | Port PortError
60+ | RecursiveAlias N.Name [N.Name] Type.Raw [N.Name]
61− | BadPort Text Type.Canonical
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
62− | TypeVarsUnboundInUnion N.Name [N.Name] [A.Located N.Name]
67+ | TypeVarsUnboundInUnion N.Name [N.Name] [A.Located N.Name]
63− | TypeVarsMessedUpInAlias N.Name [N.Name] [A.Located 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
64
75
65
76
66data CtorType
77data CtorType
@@ -68,6 +79,19 @@ data CtorType
68 | RecordCtor
79 | RecordCtor
69
80
70
81
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+
71
95
72-- VARIABLES
96-- VARIABLES
73
97
@@ -121,36 +145,6 @@ toKindInfo kind name =
121
145
122
146
123
147
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−
154-- EXTRACT SUGGESTIONS
148-- EXTRACT SUGGESTIONS
155
149
156
150
@@ -160,16 +154,10 @@ extractSuggestions err =
160 Var (VarError _ _ _ suggestions) ->
154 Var (VarError _ _ _ suggestions) ->
161 Just suggestions
155 Just suggestions
162
156
163− AliasArgMismatch _ _ _ ->
157+ Binop _ _ ->
164− Nothing
165−
166− AliasRecursion _ _ _ _ ->
167− Nothing
168−
169− BadRecursion _ _ _ ->
170 Nothing
158 Nothing
171
159
172− BadInfix _ _ _ _ _ _ ->
160+ DuplicateArg _ ->
173 Nothing
161 Nothing
174
162
175 DuplicateDecl _ ->
163 DuplicateDecl _ ->
@@ -193,11 +181,26 @@ extractSuggestions err =
193 DuplicateUnionArg _ _ _ ->
181 DuplicateUnionArg _ _ _ ->
194 Nothing
182 Nothing
195
183
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 _ ->
197 Nothing
200 Nothing
198
201
199 ImportNotFound _ suggestions ->
202 ImportNotFound _ suggestions ->
200− Just (map ModuleName.toText suggestions)
203+ Just suggestions
201
204
202 ImportExposingNotFound _ _ suggestions ->
205 ImportExposingNotFound _ _ suggestions ->
203 Just suggestions
206 Just suggestions
@@ -208,16 +211,31 @@ extractSuggestions err =
208 ImportOpenAlias _ ->
211 ImportOpenAlias _ ->
209 Nothing
212 Nothing
210
213
211− Export _ suggestions ->
214+ PortPayloadInvalid _ _ _ ->
212− Just suggestions
215+ Nothing
216+
217+ PortTypeInvalid _ _ ->
218+ Nothing
219+
220+ RecursiveAlias _ _ _ _ ->
221+ Nothing
222+
223+ RecursiveDecl _ _ _ ->
224+ Nothing
225+
226+ RecursiveLet _ ->
227+ Nothing
213
228
214− DuplicateExport _ ->
229+ Shadowing _ ->
215 Nothing
230 Nothing
216
231
217− Port _ ->
232+ TooFew _ _ _ _ ->
218 Nothing
233 Nothing
219
234
220− BadPort _ _ ->
235+ TooMany _ _ _ _ _ ->
236+ Nothing
237+
238+ TupleLargerThanThree _ ->
221 Nothing
239 Nothing
222
240
223 TypeVarsUnboundInUnion _ _ _ ->
241 TypeVarsUnboundInUnion _ _ _ ->
@@ -237,19 +255,11 @@ toReport localizer err =
237 Var varError ->
255 Var varError ->
238 varErrorToReport varError
256 varErrorToReport varError
239
257
240− BadRecursion region def defs ->
258+ Binop op1 op2 ->
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 ->
249 Report.report
259 Report.report
250 "INFIX PROBLEM"
260 "INFIX PROBLEM"
251− (Just region)
261+ Nothing
252− ("You cannot mix (" <> name1 <> ") and (" <> name2 <> ") without parentheses." )
262+ ("You cannot mix (" <> op1 <> ") and (" <> op2 <> ") without parentheses." )
253 (
263 (
254 Help.stack
264 Help.stack
255 [ reflowParagraph $
265 [ reflowParagraph $
@@ -257,6 +267,9 @@ toReport localizer err =
257 ]
267 ]
258 )
268 )
259
269
270+ DuplicateArg _ ->
271+ error "TODO DuplicateArg"
272+
260 DuplicateDecl _ ->
273 DuplicateDecl _ ->
261 error "TODO DuplicateDecl"
274 error "TODO DuplicateDecl"
262
275
@@ -278,20 +291,34 @@ toReport localizer err =
278 DuplicateUnionArg _ _ _ ->
291 DuplicateUnionArg _ _ _ ->
279 error "TODO DuplicateUnionArg"
292 error "TODO DuplicateUnionArg"
280
293
281− Pattern patternError ->
294+ DuplicateBindingName _ ->
282− case patternError of
295+ error "TODO DuplicateBindingName"
283− PatternArgMismatch var expected actual ->
284− argMismatchReport "Pattern" var expected actual
285
296
286− AliasArgMismatch var expected actual ->
297+ EffectNotFound _ ->
287− argMismatchReport "Type" var expected actual
298+ error "TODO EffectNotFound"
288
299
289− AliasRecursion name args tipe others ->
300+ EffectFunctionNotFound _ ->
290− aliasRecursionReport localizer name args tipe others
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
291
318
292 ImportNotFound name suggestions ->
319 ImportNotFound name suggestions ->
293 Report.report "IMPORT ERROR" Nothing
320 Report.report "IMPORT ERROR" Nothing
294− ("Could not find a module named `" <> ModuleName.toText name <> "`")
321+ ("Could not find a module named `" <> name <> "`")
295 (Help.maybeYouWant Nothing suggestions)
322 (Help.maybeYouWant Nothing suggestions)
296
323
297 ImportCtorNotFound ctor tipe ->
324 ImportCtorNotFound ctor tipe ->
@@ -320,30 +347,33 @@ toReport localizer err =
320
347
321 ImportExposingNotFound name value suggestions ->
348 ImportExposingNotFound name value suggestions ->
322 Report.report "IMPORT ERROR" Nothing
349 Report.report "IMPORT ERROR" Nothing
323− ("Module `" <> ModuleName.toText name <> "` does not expose `" <> value <> "`")
350+ ("Module `" <> 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.")
329 (Help.maybeYouWant Nothing suggestions)
351 (Help.maybeYouWant Nothing suggestions)
330
352
331− DuplicateExport name ->
353+ PortPayloadInvalid portName tipe invalidPayload ->
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) ->
337 let
354 let
338 context =
355 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"
340 in
369 in
341 Report.report
370 Report.report
342 "PORT ERROR"
371 "PORT ERROR"
343 Nothing
372 Nothing
344− ("Port `" <> name <> "` is trying to communicate an unsupported type."
373+ ("Port `" <> portName <> "` is trying to transmit " <> context <> ":"
345 )
374 )
375+ (error "TODO" tipe)
346− ( Help.stack
376+ {- Help.stack
347 [ text ("The specific unsupported type is" <> context <> ":")
377 [ text ("The specific unsupported type is" <> context <> ":")
348 , indent 4 (RenderType.toDoc localizer tipe)
378 , indent 4 (RenderType.toDoc localizer tipe)
349 , text "The types of values that can flow through in and out of Elm include:"
379 , text "The types of values that can flow through in and out of Elm include:"
@@ -352,9 +382,9 @@ toReport localizer err =
352 \ Tuples, Json.Values, and concrete records."
382 \ Tuples, Json.Values, and concrete records."
353 -- TODO add a note about custom decoders and encoders when they exist!
383 -- TODO add a note about custom decoders and encoders when they exist!
354 ]
384 ]
355− )
385+ -}
356
386
357− BadPort name tipe ->
387+ PortTypeInvalid name tipe ->
358 Report.report
388 Report.report
359 "PORT ERROR"
389 "PORT ERROR"
360 Nothing
390 Nothing
@@ -369,6 +399,35 @@ toReport localizer err =
369 ]
399 ]
370 )
400 )
371
401
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+
372 TypeVarsUnboundInUnion _ _ _ ->
431 TypeVarsUnboundInUnion _ _ _ ->
373 error "TODO TypeVarsUnboundInUnion"
432 error "TODO TypeVarsUnboundInUnion"
374
433
@@ -377,8 +436,6 @@ toReport localizer err =
377
436
378
437
379
438
380−
381−
382-- VAR ERROR
439-- VAR ERROR
383
440
384
441
@@ -467,8 +524,8 @@ modHint =
467-- ARG MISMATCH
524-- ARG MISMATCH
468
525
469
526
470−argMismatchReport :: Text -> Var.Canonical -> Int -> Int -> Report.Report
527+_argMismatchReport :: Text -> N.Name -> Int -> Int -> Report.Report
471−argMismatchReport kind var expected actual =
528+_argMismatchReport kind name expected actual =
472 let
529 let
473 numArgs =
530 numArgs =
474 "too "
531 "too "
@@ -478,7 +535,7 @@ argMismatchReport kind var expected actual =
478 Report.report
535 Report.report
479 (Text.map Char.toUpper numArgs)
536 (Text.map Char.toUpper numArgs)
480 Nothing
537 Nothing
481− ( kind <> " " <> Var.toText var <> " has " <> numArgs <> "."
538+ ( kind <> " " <> name <> " has " <> numArgs <> "."
482 )
539 )
483 ( text $
540 ( text $
484 "Expecting " <> i2t expected <> ", but got " <> i2t actual <> "."
541 "Expecting " <> i2t expected <> ", but got " <> i2t actual <> "."
@@ -489,7 +546,7 @@ argMismatchReport kind var expected actual =
489-- BAD RECURSION
546-- BAD RECURSION
490
547
491
548
492−badSelfRecursion :: Region.Region -> Text -> Report.Report
549+badSelfRecursion :: R.Region -> Text -> Report.Report
493badSelfRecursion region name =
550badSelfRecursion region name =
494 let
551 let
495 header =
552 header =
@@ -517,7 +574,7 @@ badSelfRecursionHelp intro body =
517 ++ map text (Text.words body)
574 ++ map text (Text.words body)
518
575
519
576
520−badMutualRecursion :: Region.Region -> Text -> [Text] -> Report.Report
577+badMutualRecursion :: R.Region -> Text -> [Text] -> Report.Report
521badMutualRecursion region name names =
578badMutualRecursion region name names =
522 let
579 let
523 header =
580 header =
@@ -535,11 +592,6 @@ badMutualRecursion region name names =
535 ]
592 ]
536
593
537
594
538−defToText :: Canonical.Def -> Text
539−defToText (Canonical.Def _ pattern _ _) =
540− error "TODO P.toText" pattern
541−
542−
543
595
544-- BAD ALIAS RECURSION
596-- BAD ALIAS RECURSION
545
597
@@ -556,7 +608,7 @@ aliasRecursionReport localizer name args tipe others =
556 "When I expand a recursive type alias, it just keeps getting bigger and bigger.\
608 "When I expand a recursive type alias, it just keeps getting bigger and bigger.\
557 \ So dealiasing results in an infinitely large type! Try this instead:"
609 \ So dealiasing results in an infinitely large type! Try this instead:"
558 , indent 4 $
610 , indent 4 $
559− RenderType.decl localizer name args [(name, [unsafePromote tipe])]
611+ RenderType.decl localizer name args [(name, [error "TODO" tipe])]
560 , text $
612 , text $
561 "This is kind of a subtle distinction. I suggested the naive fix, but you can\n"
613 "This is kind of a subtle distinction. I suggested the naive fix, but you can\n"
562 <> "often do something a bit nicer. So I would recommend reading more at:\n"
614 <> "often do something a bit nicer. So I would recommend reading more at:\n"
@@ -576,30 +628,3 @@ aliasRecursionReport localizer name args tipe others =
576 <> Help.hintLink "recursive-alias"
628 <> Help.hintLink "recursive-alias"
577 ]
629 ]
578 )
630 )
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 @@
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Type
3module Reporting.Error.Type
4 ( Error(..)
4 ( Error(..)
5− , Mismatch(..), Hint(..)
5+ , Mismatch(..)
6+ , Hint(..)
7+ , Reason(..)
6− , Reason(..), SpecificThing(..)
8+ , SpecificThing(..)
7− , Pattern(..)
9+ , PatternContext(..)
10+ , PatternCategory(..)
8 , toReport
11 , toReport
9 , flipReason
12 , flipReason
10 )
13 )
@@ -16,15 +19,16 @@ import qualified Data.Text as Text
16import Data.Text (Text)
19import Data.Text (Text)
17import Data.Monoid ((<>))
20import Data.Monoid ((<>))
18
21
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
29 )
33 )
30
34
@@ -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
64
67
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+ | SpecificUnit
74+ | SpecificTuple
70
75
71
76
72data Hint
77data Hint
73− = CaseBranch Int Region.Region
78+ = CaseBranch Int R.Region
74 | Case
79 | Case
75 | IfCondition
80 | IfCondition
76 | IfBranches
81 | IfBranches
77− | MultiIfBranch Int Region.Region
82+ | MultiIfBranch Int R.Region
78 | If
83 | If
79 | List
84 | List
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
96+ | PatternCons
91 | Shader
97 | Shader
92 | Lambda
98 | Lambda
99+ | Accessor Text
93 | Access (Maybe Text) Text
100 | Access (Maybe Text) Text
94 | Record
101 | Record
102+ | Unit
103+ | Tuple
95 -- effect manager problems
104 -- effect manager problems
96 | Manager Text
105 | Manager Text
97 | State Text
106 | State Text
98 | SelfMsg
107 | SelfMsg
99
108
100
109
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
114+ | PatternUnknown
115+
116+
117+data PatternCategory
105− | PRecord
118+ = PRecord
119+ | PUnit
120+ | PTuple
121+ | PList
122+ | PCtor N.Name
106
123
107
124
108
125
@@ -272,37 +289,37 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
272 []
289 []
273 )
290 )
274
291
275− BinopLeft op region ->
292+ BinopLeft home op region ->
276 report
293 report
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)
283 )
300 )
284
301
285− BinopRight op region ->
302+ BinopRight home op region ->
286 report
303 report
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
293 ++
310 ++
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."
297 ]
314 ]
298 )
315 )
299 )
316 )
300
317
301− Binop op ->
318+ Binop _ op ->
302 report
319 report
303 Nothing
320 Nothing
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."
307 )
324 )
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+ []
333 )
350 )
334
351
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:"
344 )
361 )
345 "But it is:"
362 "But it is:"
346− ( functionHint maybeName
347− ++
348− if index == 1 then
363+ ( if index == 1 then
349 []
364 []
350 else
365 else
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
430 []
445 []
431 )
446 )
432
447
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 [])
436− case patErr of
437− PVar name ->
438− "variable `" <> name <> "`"
439
451
440− PAlias name ->
452+ PatternCons ->
441− "alias `" <> name <> "`"
453+ report Nothing "This list pattern is mixing types:" $
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
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:"
459− []
457+ []
460− )
461
458
462 Shader ->
459 Shader ->
463 report
460 report
@@ -479,6 +476,15 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
479 []
476 []
480 )
477 )
481
478
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+
482 Access (Just body) field ->
488 Access (Just body) field ->
483 let
489 let
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
511 []
517 []
512 )
518 )
513
519
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+
514 Manager name ->
540 Manager name ->
515 report
541 report
516 Nothing
542 Nothing
@@ -551,6 +577,67 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType decoders maybeR
551
577
552
578
553
579
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+
554-- COMPARISON HINT
641-- COMPARISON HINT
555
642
556
643
@@ -592,48 +679,26 @@ jsonDecoderHint =
592-- BINOP HINTS
679-- BINOP HINTS
593
680
594
681
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 =
597 let
684 let
598− leftString =
599− show (RenderType.toDoc Map.empty leftType)
685+ leftString = show (RenderType.toDoc Map.empty leftType)
600−
601− rightString =
602− show (RenderType.toDoc Map.empty rightType)
686+ rightString = show (RenderType.toDoc Map.empty rightType)
603 in
687 in
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#++>"
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− []
691+ ]
617−
618−
619−
620−-- FUNCTION HINTS
621
692
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+ ]
622
698
623−functionHint :: Maybe Var.Canonical -> [Text]
699+ else
624−functionHint maybeName =
625− case maybeName of
626− Nothing ->
627 []
700 []
628
701
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−
637
702
638
703
639-- ARITY HINTS
704-- ARITY HINTS
@@ -706,9 +771,6 @@ flipReason reason =
706 IntFloat ->
771 IntFloat ->
707 IntFloat
772 IntFloat
708
773
709− TooLongComparableTuple len ->
710− TooLongComparableTuple len
711−
712 MissingArgs num ->
774 MissingArgs num ->
713 MissingArgs num
775 MissingArgs num
714
776
@@ -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>"
798
860
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−
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"
869
926
870− SpecificType var@(Var.Canonical _ name) ->
927+ SpecificType name ->
871− if Var.isTuple var then
872− "a tuple"
873−
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
876
930
877 else
931 else
@@ -883,6 +937,12 @@ specificThingToText specific =
883 SpecificFunction ->
937 SpecificFunction ->
884 "a function"
938 "a function"
885
939
940+ SpecificUnit ->
941+ "a unit value"
942+
943+ SpecificTuple ->
944+ "a tuple"
945+
886
946
887badFieldElaboration :: Text
947badFieldElaboration :: Text
888badFieldElaboration =
948badFieldElaboration =
@@ -893,6 +953,9 @@ badFieldElaboration =
893
953
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
957+
958+{-
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)
986−
1049+-}
987
1050
988
1051
989-- INFINITE TYPES
1052-- INFINITE TYPES
@@ -1017,7 +1080,7 @@ infiniteTypeToReport localizer context overallType =
1017 )
1080 )
1018
1081
1019
1082
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" )
1046
1109
1047− BinopLeft _ region ->
1110+ BinopLeft _ _ region ->
1048 ( Just region, "the left argument" )
1111 ( Just region, "the left argument" )
1049
1112
1050− BinopRight _ region ->
1113+ BinopRight _ _ region ->
1051 ( Just region, "the right argument" )
1114 ( Just region, "the right argument" )
1052
1115
1053− Binop _ ->
1116+ Binop _ _ ->
1054 ( Nothing, "this expression" )
1117 ( Nothing, "this expression" )
1055
1118
1056 Function maybeName ->
1119 Function maybeName ->
@@ -1074,7 +1137,10 @@ infiniteHint hint =
1074 Literal name ->
1137 Literal name ->
1075 ( Nothing, name )
1138 ( Nothing, name )
1076
1139
1077− Pattern _ ->
1140+ Pattern _ _ ->
1141+ ( Nothing, "this pattern" )
1142+
1143+ PatternCons ->
1078 ( Nothing, "this pattern" )
1144 ( Nothing, "this pattern" )
1079
1145
1080 Shader ->
1146 Shader ->
@@ -1083,12 +1149,21 @@ infiniteHint hint =
1083 Lambda ->
1149 Lambda ->
1084 ( Nothing, "this function" )
1150 ( Nothing, "this function" )
1085
1151
1152+ Accessor _ ->
1153+ ( Nothing, "this record accessor" )
1154+
1086 Access _ _ ->
1155 Access _ _ ->
1087 ( Nothing, "this field access" )
1156 ( Nothing, "this field access" )
1088
1157
1089 Record ->
1158 Record ->
1090 ( Nothing, "this record" )
1159 ( Nothing, "this record" )
1091
1160
1161+ Unit ->
1162+ ( Nothing, "this “unit” value" )
1163+
1164+ Tuple ->
1165+ ( Nothing, "this tuple" )
1166+
1092 -- effect manager problems
1167 -- effect manager problems
1093 Manager name ->
1168 Manager name ->
1094 ( Nothing, functionName name )
1169 ( Nothing, functionName name )