@@ -2,7 +2,23 @@
22{-# LANGUAGE OverloadedStrings #-}
33module Reporting.Error.Type
44 ( Error(..)
5+ -- expectations
56 , Origin(..)
7+ , Expected(..)
8+ , Context(..)
9+ , SubContext(..)
10+ , MaybeName(..)
11+ , Category(..)
12+ , PExpected(..)
13+ , PContext(..)
14+ , PCategory(..)
15+ , typeReplace
16+ , ptypeReplace
17+ -- error types
18+ , Type(..)
19+ , Extension(..)
20+ , Localizer
21+ -- make reports
622 , toReport
723 )
824 where
@@ -11,17 +27,14 @@ module Reporting.Error.Type
1127import Prelude hiding (round)
1228import Data.Monoid ((<>))
1329
14−import qualified AST.Canonical as Can
1530import qualified AST.Module.Name as ModuleName
16−import qualified AST.Utils.Type as Type
1731import qualified Data.Index as Index
32+import qualified Data.Map as Map
1833import qualified Elm.Name as N
1934import qualified Reporting.Helpers as H
2035import qualified Reporting.Region as R
2136import qualified Reporting.Render.Code as Code
22−import qualified Reporting.Render.Type as Type
2337import qualified Reporting.Report as Report
24−import qualified Type.Constraint as C
2538
2639
2740
@@ -29,22 +42,159 @@ import qualified Type.Constraint as C
2942
3043
3144data Error
32− = Mismatch Origin (C.Expected Can.Type)
33− | BadPattern R.Region C.PCategory Can.Type (C.PExpected Can.Type)
34− | InfiniteType Can.Type
45+ = Mismatch Origin (Expected Type)
46+ | BadPattern R.Region PCategory Type (PExpected Type)
47+ | InfiniteType Type
48+
49+
50+
51+-- EXPRESSION EXPECTATIONS
3552
3653
3754data Origin
38− = BadExpr R.Region C.Category Can.Type
39− | BadLocal R.Region N.Name Can.Type
40− | BadForeign R.Region N.Name Can.Type
55+ = BadExpr R.Region Category Type
56+ | BadLocal R.Region N.Name Type
57+ | BadForeign R.Region N.Name Type
58+
59+
60+data Expected tipe
61+ = NoExpectation tipe
62+ | FromContext R.Region Context tipe
63+ | FromAnnotation N.Name Int SubContext tipe
64+
65+
66+data Context
67+ = ListEntry Index.ZeroBased
68+ | Negate
69+ | OpLeft N.Name
70+ | OpRight N.Name
71+ | IfCondition
72+ | IfBranch Index.ZeroBased
73+ | CaseBranch Index.ZeroBased
74+ | CallArg MaybeName Index.ZeroBased
75+ | TooManyArgs MaybeName Int
76+ | RecordAccess N.Name
77+ | RecordUpdate
78+ | Destructure
79+
80+
81+data SubContext
82+ = TypedIfBranch Index.ZeroBased
83+ | TypedCaseBranch Index.ZeroBased
84+ | TypedBody
85+
86+
87+data MaybeName
88+ = FuncName N.Name
89+ | CtorName N.Name
90+ | OpName N.Name
91+ | NoName
92+
93+
94+data Category
95+ = List
96+ | Number
97+ | Float
98+ | String
99+ | Char
100+ | If
101+ | Case
102+ | CallResult MaybeName
103+ | LambdaExpr
104+ | Accessor N.Name
105+ | Access N.Name
106+ | RecordExpr
107+ | TupleExpr
108+ | UnitExpr
109+ | Shader
110+ | Effects
111+
112+
113+
114+-- PATTERN EXPECTATIONS
115+
116+
117+data PExpected tipe
118+ = PNoExpectation tipe
119+ | PFromContext R.Region PContext tipe
120+
121+
122+data PContext
123+ = PTypedArg N.Name Index.ZeroBased
124+ | PCaseMatch Index.ZeroBased
125+ | PCtorArg N.Name Index.ZeroBased
126+ | PListEntry Index.ZeroBased
127+ | PTail
128+
129+
130+data PCategory
131+ = PRecord
132+ | PUnit
133+ | PTuple
134+ | PList
135+ | PCtor N.Name
136+ | PInt
137+ | PStr
138+ | PChr
139+
140+
141+
142+-- HELPERS
143+
144+
145+typeReplace :: Expected a -> b -> Expected b
146+typeReplace expectation tipe =
147+ case expectation of
148+ NoExpectation _ ->
149+ NoExpectation tipe
150+
151+ FromContext region context _ ->
152+ FromContext region context tipe
153+
154+ FromAnnotation name arity context _ ->
155+ FromAnnotation name arity context tipe
156+
157+
158+ptypeReplace :: PExpected a -> b -> PExpected b
159+ptypeReplace expectation tipe =
160+ case expectation of
161+ PNoExpectation _ ->
162+ PNoExpectation tipe
163+
164+ PFromContext region context _ ->
165+ PFromContext region context tipe
166+
167+
168+
169+-- ERROR TYPES
170+
171+
172+data Type
173+ = Lambda Type [Type]
174+ | Infinite
175+ | Error
176+ | FlexVar N.Name
177+ | FlexSuper N.Name
178+ | RigidVar N.Name
179+ | RigidSuper N.Name
180+ | Type ModuleName.Canonical N.Name [Type]
181+ | Record (Map.Map N.Name Type) Extension
182+ | Unit
183+ | Tuple Type Type (Maybe Type)
184+ | Alias ModuleName.Canonical N.Name [(N.Name, Type)] Type
185+
186+
187+data Extension
188+ = Closed
189+ | FlexOpen N.Name
190+ | RigidOpen N.Name
41191
42192
43193
44194-- TO REPORT
45195
46196
47−toReport :: Code.Source -> Type.Localizer -> Error -> Report.Report
197+toReport :: Code.Source -> Localizer -> Error -> Report.Report
48198toReport source localizer err =
49199 case err of
50200 Mismatch origin expected ->
@@ -71,27 +221,7 @@ toReport source localizer err =
71221
72222data Thing
73223 = Var N.Name
74− | Category C.Category
75−
76−
77−typeComparison :: Type.Localizer -> Can.Type -> Can.Type -> ( String, String, [H.Doc] ) -> H.Doc
78−typeComparison localizer actual expected ( iAmSeeing, insteadOf, soHereAreSomeThoughts ) =
79− let
80− (actualDoc, expectedDoc) =
81− Type.diffToDocs localizer actual expected
82− in
83− H.stack $
84− [ H.reflow iAmSeeing
85− , H.indent 4 actualDoc
86− , H.reflow insteadOf
87− , H.indent 4 expectedDoc
88− ]
89− ++ soHereAreSomeThoughts
90−
91−
92−indentType :: Type.Localizer -> Can.Type -> H.Doc
93−indentType localizer tipe =
94− H.indent 4 (H.dullyellow (Type.toDoc localizer tipe))
224+ | Category Category
95225
96226
97227toDescription :: Thing -> String -> String
@@ -102,38 +232,38 @@ toDescription thing thatThingIs =
102232
103233 Category category ->
104234 case category of
105− C.List -> thatThingIs <> " a list of type:"
106− C.Number -> thatThingIs <> " a number of type:"
107− C.Float -> thatThingIs <> " a float of type:"
108− C.String -> thatThingIs <> " a string of type:"
109− C.Char -> thatThingIs <> " a character of type:"
110− C.If -> "This `if` expression produces a value of type:"
111− C.Case -> "This `case` expression produces a value of type:"
112− C.Lambda -> thatThingIs <> " an anonymous function of type:"
113− C.Accessor field -> "This ." <> N.toString field <> " field access function has type of type:"
114− C.Access field -> "The value at ." <> N.toString field <> " has type of type:"
115− C.Record -> thatThingIs <> " a record of type:"
116− C.Tuple -> thatThingIs <> " a tuple of type:"
117− C.Unit -> thatThingIs <> " a unit value:"
118− C.Shader -> thatThingIs <> " a GLSL shader of type:"
119− C.Effects -> thatThingIs <> " a thing for CORE LIBRARIES ONLY."
120− C.CallResult maybeName ->
235+ List -> thatThingIs <> " a list of type:"
236+ Number -> thatThingIs <> " a number of type:"
237+ Float -> thatThingIs <> " a float of type:"
238+ String -> thatThingIs <> " a string of type:"
239+ Char -> thatThingIs <> " a character of type:"
240+ If -> "This `if` expression produces a value of type:"
241+ Case -> "This `case` expression produces a value of type:"
242+ LambdaExpr -> thatThingIs <> " an anonymous function of type:"
243+ Accessor field -> "This ." <> N.toString field <> " field access function has type:"
244+ Access field -> "The value at ." <> N.toString field <> " has type:"
245+ RecordExpr -> thatThingIs <> " a record of type:"
246+ TupleExpr -> thatThingIs <> " a tuple of type:"
247+ UnitExpr -> thatThingIs <> " a unit value:"
248+ Shader -> thatThingIs <> " a GLSL shader of type:"
249+ Effects -> thatThingIs <> " a thing for CORE LIBRARIES ONLY."
250+ CallResult maybeName ->
121251 case maybeName of
122− C.NoName -> thatThingIs <> ":"
123− C.FuncName name -> "This `" <> N.toString name <> "` call produces:"
124− C.CtorName name -> "This `" <> N.toString name <> "` call produces:"
125− C.OpName _ -> thatThingIs <> ":"
252+ NoName -> thatThingIs <> ":"
253+ FuncName name -> "This `" <> N.toString name <> "` call produces:"
254+ CtorName name -> "This `" <> N.toString name <> "` call produces:"
255+ OpName _ -> thatThingIs <> ":"
126256
127257
128258
129259-- TO MISMATCH REPORT
130260
131261
132−toMismatchReport :: Code.Source -> Type.Localizer -> R.Region -> Thing -> Can.Type -> C.Expected Can.Type -> Report.Report
262+toMismatchReport :: Code.Source -> Localizer -> R.Region -> Thing -> Type -> Expected Type -> Report.Report
133263toMismatchReport source localizer exprRegion thing tipe expected =
134264 Report.Report "TYPE MISMATCH" exprRegion [] $
135265 case expected of
136− C.NoExpectation expectedType ->
266+ NoExpectation expectedType ->
137267 Report.toCodeSnippet source exprRegion Nothing
138268 (
139269 "This expression is being used in an unexpected way:"
@@ -150,31 +280,31 @@ toMismatchReport source localizer exprRegion thing tipe expected =
150280 )
151281 )
152282
153− C.FromAnnotation name arity subContext expectedType ->
283+ FromAnnotation name arity subContext expectedType ->
154284 Report.toCodeSnippet source exprRegion Nothing
155285 (
156286 H.reflow $
157287 case subContext of
158− C.TypedIfBranch index ->
288+ TypedIfBranch index ->
159289 "Something is off with the " <> H.ordinalize (Index.toHuman index) <> " branch of this `if` experssion:"
160290
161− C.TypedCaseBranch index ->
291+ TypedCaseBranch index ->
162292 "Something is off with the " <> H.ordinalize (Index.toHuman index) <> " branch of this `case` expression:"
163293
164− C.TypedBody ->
294+ TypedBody ->
165295 "Something is off with the body of the `" <> N.toString name <> "` definition:"
166296 ,
167297 typeComparison localizer tipe expectedType
168298 (
169299 toDescription thing $
170300 case subContext of
171− C.TypedIfBranch index ->
301+ TypedIfBranch index ->
172302 "The " <> H.ordinalize (Index.toHuman index) <> " branch is"
173303
174− C.TypedCaseBranch index ->
304+ TypedCaseBranch index ->
175305 "The " <> H.ordinalize (Index.toHuman index) <> " branch is"
176306
177− C.TypedBody ->
307+ TypedBody ->
178308 "The body is"
179309 ,
180310 "But the type annotation on `" <> N.toString name <> "` says it should be:"
@@ -185,9 +315,9 @@ toMismatchReport source localizer exprRegion thing tipe expected =
185315 )
186316 )
187317
188− C.FromContext region context expectedType ->
318+ FromContext region context expectedType ->
189319 case context of
190− C.ListEntry index ->
320+ ListEntry index ->
191321 if Index.toHuman index == 2 then
192322 error "TODO 1st vs 2nd list entry"
193323 else
@@ -213,7 +343,7 @@ toMismatchReport source localizer exprRegion thing tipe expected =
213343 )
214344 )
215345
216− C.Negate ->
346+ Negate ->
217347 Report.toCodeSnippet source region (Just exprRegion)
218348 (
219349 "I do not know how to negate this type of value:"
@@ -229,15 +359,19 @@ toMismatchReport source localizer exprRegion thing tipe expected =
229359 ]
230360 )
231361
232− C.OpLeft op ->
362+ OpLeft op ->
233363 Report.toCodeSnippet source region (Just exprRegion) $
234364 opLeftToDocs localizer thing op tipe expectedType
235365
236− C.OpRight op ->
237− Report.toCodeSnippet source region (Just exprRegion) $
238− opRightToDocs localizer thing op tipe expectedType
366+ OpRight op ->
367+ case opRightToDocs localizer thing op tipe expectedType of
368+ EmphBoth details ->
369+ Report.toCodeSnippet source region Nothing details
239370
240− C.IfCondition ->
371+ EmphRight details ->
372+ Report.toCodeSnippet source region (Just exprRegion) details
373+
374+ IfCondition ->
241375 Report.toCodeSnippet source region (Just exprRegion)
242376 (
243377 "This `if` condition does not evaluate to a boolean value, True or False."
@@ -252,7 +386,7 @@ toMismatchReport source localizer exprRegion thing tipe expected =
252386 ]
253387 )
254388
255− C.IfBranch index ->
389+ IfBranch index ->
256390 if Index.toHuman index == 2 then
257391 error "TODO 1st vs 2nd if branches"
258392 -- error "TODO if with no chaining"
@@ -279,7 +413,7 @@ toMismatchReport source localizer exprRegion thing tipe expected =
279413 )
280414 )
281415
282− C.CaseBranch index ->
416+ CaseBranch index ->
283417 if Index.toHuman index == 2 then
284418 error "TODO 1st vs 2nd case branches"
285419 else
@@ -305,20 +439,20 @@ toMismatchReport source localizer exprRegion thing tipe expected =
305439 )
306440 )
307441
308− C.CallArg maybeFuncName index ->
442+ CallArg maybeFuncName index ->
309443 let
310444 thisFunction =
311445 case maybeFuncName of
312− C.NoName ->
446+ NoName ->
313447 "this function"
314448
315− C.FuncName name ->
449+ FuncName name ->
316450 "`" <> N.toString name <> "`"
317451
318− C.CtorName name ->
452+ CtorName name ->
319453 "`" <> N.toString name <> "`"
320454
321− C.OpName op ->
455+ OpName op ->
322456 "(" <> N.toString op <> ")"
323457
324458 in
@@ -345,38 +479,38 @@ toMismatchReport source localizer exprRegion thing tipe expected =
345479 )
346480 )
347481
348− C.TooManyArgs maybeName numGivenArgs ->
349− case length (Type.delambda tipe) - 1 of
482+ TooManyArgs maybeName numGivenArgs ->
483+ case countArgs tipe of
350484 0 ->
351485 Report.toCodeSnippet source region (Just exprRegion)
352486 (
353487 H.reflow $
354488 case maybeName of
355− C.NoName ->
489+ NoName ->
356490 "You are giving " <> H.args numGivenArgs <> " to something that is not a function!"
357491
358− C.FuncName name ->
492+ FuncName name ->
359493 "`" <> N.toString name <> "` is not a function, but you are giving it " <> H.args numGivenArgs <> "!"
360494
361− C.CtorName name ->
495+ CtorName name ->
362496 "`" <> N.toString name <> "` is not a function, but you are giving it " <> H.args numGivenArgs <> "!"
363497
364− C.OpName op ->
498+ OpName op ->
365499 "(" <> N.toString op <> ") is not a function, but you are giving it " <> H.args numGivenArgs <> "!"
366500 ,
367501 typeComparison localizer tipe expectedType
368502 (
369503 case maybeName of
370− C.NoName ->
504+ NoName ->
371505 "It is a value of type:"
372506
373− C.FuncName name ->
507+ FuncName name ->
374508 "`" <> N.toString name <> "` is a value of type:"
375509
376− C.CtorName name ->
510+ CtorName name ->
377511 "`" <> N.toString name <> "` is a constructor of type:"
378512
379− C.OpName op ->
513+ OpName op ->
380514 "(" <> N.toString op <> ") is a value of type:"
381515 ,
382516 "But you are giving it " <> H.args numGivenArgs <> " as if its type was:"
@@ -390,16 +524,16 @@ toMismatchReport source localizer exprRegion thing tipe expected =
390524 let
391525 thisFunction =
392526 case maybeName of
393− C.NoName ->
527+ NoName ->
394528 "This function"
395529
396− C.FuncName name ->
530+ FuncName name ->
397531 "The `" <> N.toString name <> "` function"
398532
399− C.CtorName name ->
533+ CtorName name ->
400534 "The `" <> N.toString name <> "` constructor"
401535
402− C.OpName op ->
536+ OpName op ->
403537 "The (" <> N.toString op <> ") function"
404538 in
405539 Report.toCodeSnippet source region (Just exprRegion)
@@ -422,10 +556,10 @@ toMismatchReport source localizer exprRegion thing tipe expected =
422556 )
423557 )
424558
425− C.RecordAccess field ->
559+ RecordAccess field ->
426560 Report.toCodeSnippet source region (Just exprRegion) $
427− case Type.deepDealias tipe of
428− Can.TRecord _ _ ->
561+ case error "TODO figure out record things" tipe of
562+ Record _ _ ->
429563 (
430564 H.reflow $
431565 "This record does not have a `" <> N.toString field <> "` field:"
@@ -459,7 +593,7 @@ toMismatchReport source localizer exprRegion thing tipe expected =
459593 ]
460594 )
461595
462− Can.TLambda _ _ ->
596+ Lambda _ _ ->
463597 (
464598 H.reflow $
465599 "I cannot access field `" <> N.toString field <> "` of this " <> whatever <> ":"
@@ -484,9 +618,9 @@ toMismatchReport source localizer exprRegion thing tipe expected =
484618 ]
485619 )
486620
487− C.RecordUpdate ->
488− case Type.deepDealias tipe of
489− Can.TRecord _ _ ->
621+ RecordUpdate ->
622+ case error "TODO figure out record things" tipe of
623+ Record _ _ ->
490624 Report.toCodeSnippet source region Nothing
491625 (
492626 H.reflow $
@@ -507,15 +641,29 @@ toMismatchReport source localizer exprRegion thing tipe expected =
507641 ]
508642 )
509643
510− C.Destructure ->
644+ Destructure ->
511645 error "TODO Destructure"
512646
513647
514648
649+-- COUNT ARGS
650+
651+
652+countArgs :: Type -> Int
653+countArgs tipe =
654+ case tipe of
655+ Lambda _ stuff ->
656+ length stuff
657+
658+ _ ->
659+ 0
660+
661+
662+
515663-- OP LEFT
516664
517665
518−opLeftToDocs :: Type.Localizer -> Thing -> N.Name -> Can.Type -> Can.Type -> (H.Doc, H.Doc)
666+opLeftToDocs :: Localizer -> Thing -> N.Name -> Type -> Type -> (H.Doc, H.Doc)
519667opLeftToDocs localizer thing op tipe expectedType =
520668 case op of
521669 "+"
@@ -533,10 +681,10 @@ opLeftToDocs localizer thing op tipe expectedType =
533681 "//" -> badIDiv localizer "left" tipe
534682 "&&" -> badBool localizer "&&" "left" tipe
535683 "||" -> badBool localizer "||" "left" tipe
536− "<" -> badCompArg localizer thing "<" "left" tipe
537− ">" -> badCompArg localizer thing ">" "left" tipe
538− "<=" -> badCompArg localizer thing "<=" "left" tipe
539− ">=" -> badCompArg localizer thing ">=" "left" tipe
684+ "<" -> badCompLeft localizer thing "<" "left" tipe
685+ ">" -> badCompLeft localizer thing ">" "left" tipe
686+ "<=" -> badCompLeft localizer thing "<=" "left" tipe
687+ ">=" -> badCompLeft localizer thing ">=" "left" tipe
540688
541689 "<|" ->
542690 ( "The left side of (<|) needs to be a function so I can pipe arguments to it!"
@@ -548,7 +696,7 @@ opLeftToDocs localizer thing op tipe expectedType =
548696 , error "TODO"
549697 {-
550698 case category of
551− C.Call ->
699+ Call ->
552700 "Maybe you gave " <> funcName <> " too many arguments already?"
553701
554702 _ ->
@@ -577,44 +725,53 @@ opLeftToDocs localizer thing op tipe expectedType =
577725-- OP RIGHT
578726
579727
580−opRightToDocs :: Type.Localizer -> Thing -> N.Name -> Can.Type -> Can.Type -> (H.Doc, H.Doc)
728+data RightDocs
729+ = EmphBoth (H.Doc, H.Doc)
730+ | EmphRight (H.Doc, H.Doc)
731+
732+
733+opRightToDocs :: Localizer -> Thing -> N.Name -> Type -> Type -> RightDocs
581734opRightToDocs localizer thing op tipe expectedType =
582735 case op of
583736 "+"
584737 | isInt tipe -> badCast op FloatInt
585738 | isFloat tipe -> badCast op IntFloat
586− | isString tipe -> badStringAdd
587− | isList tipe -> badListAdd localizer "right" tipe
588− | otherwise -> badMath localizer "Addition" "right" "+" tipe []
739+ | isString tipe -> EmphRight $ badStringAdd
740+ | isList tipe -> EmphRight $ badListAdd localizer "right" tipe
741+ | otherwise -> EmphRight $ badMath localizer "Addition" "right" "+" tipe []
589742
590743 "*"
591744 | isInt tipe -> badCast op FloatInt
592745 | isFloat tipe -> badCast op IntFloat
593− | isList tipe -> badListMul localizer "right" tipe
594− | otherwise -> badMath localizer "Multiplication" "right" "*" tipe []
746+ | isList tipe -> EmphRight $ badListMul localizer "right" tipe
747+ | otherwise -> EmphRight $ badMath localizer "Multiplication" "right" "*" tipe []
595748
596749 "-"
597750 | isInt tipe -> badCast op FloatInt
598751 | isFloat tipe -> badCast op IntFloat
599− | otherwise -> badMath localizer "Subtraction" "right" "-" tipe []
752+ | otherwise -> EmphRight $ badMath localizer "Subtraction" "right" "-" tipe []
600753
601754 "^"
602755 | isInt tipe -> badCast op FloatInt
603756 | isFloat tipe -> badCast op IntFloat
604− | otherwise -> badMath localizer "Exponentiation" "right" "^" tipe []
605−
606− "/" -> badFDiv localizer "right" tipe
607− "//" -> badIDiv localizer "right" tipe
608− "&&" -> badBool localizer "&&" "right" tipe
609− "||" -> badBool localizer "||" "right" tipe
610− "<" -> badCompRight localizer thing "<" tipe expectedType
611− ">" -> badCompRight localizer thing ">" tipe expectedType
612− "<=" -> badCompRight localizer thing "<=" tipe expectedType
613− ">=" -> badCompRight localizer thing ">=" tipe expectedType
757+ | otherwise -> EmphRight $ badMath localizer "Exponentiation" "right" "^" tipe []
758+
759+ "/" -> EmphRight $ badFDiv localizer "right" tipe
760+ "//" -> EmphRight $ badIDiv localizer "right" tipe
761+ "&&" -> EmphRight $ badBool localizer "&&" "right" tipe
762+ "||" -> EmphRight $ badBool localizer "||" "right" tipe
763+ "<" -> badCompRight localizer "<" tipe expectedType
764+ ">" -> badCompRight localizer ">" tipe expectedType
765+ "<=" -> badCompRight localizer "<=" tipe expectedType
766+ ">=" -> badCompRight localizer ">=" tipe expectedType
614767 "==" -> badEquality localizer "==" tipe expectedType
615768 "/=" -> badEquality localizer "/=" tipe expectedType
616769
770+ "::" ->
771+ error "TODO see if people want ++ instead?"
772+
617773 "<|" ->
774+ EmphRight
618775 (
619776 H.reflow $
620777 "I cannot pipe this " <> whatever <> " in as the final argument:"
@@ -633,7 +790,8 @@ opRightToDocs localizer thing op tipe expectedType =
633790
634791 "|>" ->
635792 case (tipe, expectedType) of
636− (Can.TLambda expectedArgType _, Can.TLambda argType _) ->
793+ (Lambda expectedArgType _, Lambda argType _) ->
794+ EmphRight
637795 (
638796 "I cannot pipe the argument through to this function:"
639797 ,
@@ -647,10 +805,10 @@ opRightToDocs localizer thing op tipe expectedType =
647805 Nothing ->
648806 "But (|>) is piping it a function that expects the next argument to be:"
649807
650− Just (C.FuncName name) ->
808+ Just (FuncName name) ->
651809 "But (|>) is piping it to `" <> N.toString name <> "` which expects the next argument to be:"
652810
653− Just (C.OpName op) ->
811+ Just (OpName op) ->
654812 "But (|>) is piping it to (" <> N.toString op <> ") which expects the next argument to be:"
655813 -}
656814 ,
@@ -661,6 +819,7 @@ opRightToDocs localizer thing op tipe expectedType =
661819 )
662820
663821 _ ->
822+ EmphRight
664823 (
665824 "The right side of (|>) needs to be a function so I can pipe arguments to it!"
666825 ,
@@ -681,6 +840,7 @@ opRightToDocs localizer thing op tipe expectedType =
681840 )
682841
683842 _ ->
843+ EmphRight
684844 (
685845 H.reflow $
686846 "The right argument of (" <> N.toString op <> ") is causing problems."
@@ -702,40 +862,40 @@ opRightToDocs localizer thing op tipe expectedType =
702862
703863
704864
705−isInt :: Can.Type -> Bool
865+isInt :: Type -> Bool
706866isInt tipe =
707867 case tipe of
708− Can.TType home name [] ->
868+ Type home name [] ->
709869 home == ModuleName.basics && name == N.int
710870
711871 _ ->
712872 False
713873
714874
715−isFloat :: Can.Type -> Bool
875+isFloat :: Type -> Bool
716876isFloat tipe =
717877 case tipe of
718− Can.TType home name [] ->
878+ Type home name [] ->
719879 home == ModuleName.basics && name == N.float
720880
721881 _ ->
722882 False
723883
724884
725−isString :: Can.Type -> Bool
885+isString :: Type -> Bool
726886isString tipe =
727887 case tipe of
728− Can.TType home name [] ->
888+ Type home name [] ->
729889 home == ModuleName.string && name == N.string
730890
731891 _ ->
732892 False
733893
734894
735−isList :: Can.Type -> Bool
895+isList :: Type -> Bool
736896isList tipe =
737897 case tipe of
738− Can.TType home name [_] ->
898+ Type home name [_] ->
739899 home == ModuleName.list && name == N.list
740900
741901 _ ->
@@ -754,25 +914,26 @@ whatever =
754914data ThisThenThat = FloatInt | IntFloat
755915
756916
757−badCast :: N.Name -> ThisThenThat -> (H.Doc, H.Doc)
917+badCast :: N.Name -> ThisThenThat -> RightDocs
758918badCast op thisThenThat =
759− (
760− H.text $
761− "I need both sides of (" <> N.toString op <> ") to be the exact same type. Both Int or both Float."
762− ,
763− let
764− anInt = ["an", H.dullyellow "Int"]
765− aFloat = ["a", H.dullyellow "Float"]
766− toFloat = H.green "toFloat"
767− round = H.green "round"
768− in
769− case thisThenThat of
770− FloatInt ->
771− badCastHelp aFloat anInt round toFloat
772−
773− IntFloat ->
774− badCastHelp anInt aFloat toFloat round
775− )
919+ EmphBoth
920+ (
921+ H.text $
922+ "I need both sides of (" <> N.toString op <> ") to be the exact same type. Both Int or both Float."
923+ ,
924+ let
925+ anInt = ["an", H.dullyellow "Int"]
926+ aFloat = ["a", H.dullyellow "Float"]
927+ toFloat = H.green "toFloat"
928+ round = H.green "round"
929+ in
930+ case thisThenThat of
931+ FloatInt ->
932+ badCastHelp aFloat anInt round toFloat
933+
934+ IntFloat ->
935+ badCastHelp anInt aFloat toFloat round
936+ )
776937
777938
778939badCastHelp :: [H.Doc] -> [H.Doc] -> H.Doc -> H.Doc -> H.Doc
@@ -808,7 +969,7 @@ badStringAdd =
808969 )
809970
810971
811−badListAdd :: Type.Localizer -> String -> Can.Type -> (H.Doc, H.Doc)
972+badListAdd :: Localizer -> String -> Type -> (H.Doc, H.Doc)
812973badListAdd localizer direction tipe =
813974 (
814975 "I cannot do addition with lists:"
@@ -827,7 +988,7 @@ badListAdd localizer direction tipe =
827988 )
828989
829990
830−badListMul :: Type.Localizer -> String -> Can.Type -> (H.Doc, H.Doc)
991+badListMul :: Localizer -> String -> Type -> (H.Doc, H.Doc)
831992badListMul localizer direction tipe =
832993 badMath localizer "Multiplication" direction "*" tipe
833994 [
@@ -839,7 +1000,7 @@ badListMul localizer direction tipe =
8391000 ]
8401001
8411002
842−badMath :: Type.Localizer -> String -> String -> String -> Can.Type -> [H.Doc] -> (H.Doc, H.Doc)
1003+badMath :: Localizer -> String -> String -> String -> Type -> [H.Doc] -> (H.Doc, H.Doc)
8431004badMath localizer operation direction op tipe otherHints =
8441005 (
8451006 H.reflow $
@@ -859,7 +1020,7 @@ badMath localizer operation direction op tipe otherHints =
8591020 )
8601021
8611022
862−badFDiv :: Type.Localizer -> H.Doc -> Can.Type -> (H.Doc, H.Doc)
1023+badFDiv :: Localizer -> H.Doc -> Type -> (H.Doc, H.Doc)
8631024badFDiv localizer direction tipe =
8641025 (
8651026 H.reflow $
@@ -892,7 +1053,7 @@ badFDiv localizer direction tipe =
8921053 )
8931054
8941055
895−badIDiv :: Type.Localizer -> H.Doc -> Can.Type -> (H.Doc, H.Doc)
1056+badIDiv :: Localizer -> H.Doc -> Type -> (H.Doc, H.Doc)
8961057badIDiv localizer direction tipe =
8971058 (
8981059 H.reflow $
@@ -931,7 +1092,7 @@ badIDiv localizer direction tipe =
9311092-- BAD BOOLS
9321093
9331094
934−badBool :: Type.Localizer -> H.Doc -> H.Doc -> Can.Type -> (H.Doc, H.Doc)
1095+badBool :: Localizer -> H.Doc -> H.Doc -> Type -> (H.Doc, H.Doc)
9351096badBool localizer op direction tipe =
9361097 (
9371098 H.reflow $
@@ -954,18 +1115,8 @@ badBool localizer op direction tipe =
9541115-- BAD COMPARISON
9551116
9561117
957−badCompRight :: Type.Localizer -> Thing -> String -> Can.Type -> Can.Type -> (H.Doc, H.Doc)
958−badCompRight localizer thing op tipe expectedType =
959− case tipe of
960− Can.TVar name | N.startsWith "comparable" name ->
961− badCompArg localizer thing op "right" tipe
962−
963− _ ->
964− badCompMix localizer op tipe expectedType
965−
966−
967−badCompArg :: Type.Localizer -> Thing -> String -> String -> Can.Type -> (H.Doc, H.Doc)
968−badCompArg localizer thing op direction tipe =
1118+badCompLeft :: Localizer -> Thing -> String -> String -> Type -> (H.Doc, H.Doc)
1119+badCompLeft localizer thing op direction tipe =
9691120 (
9701121 H.reflow $
9711122 "I cannot do a comparison with this value:"
@@ -988,51 +1139,81 @@ badCompArg localizer thing op direction tipe =
9881139 )
9891140
9901141
991−badCompMix :: Type.Localizer -> String -> Can.Type -> Can.Type -> (H.Doc, H.Doc)
992−badCompMix localizer op tipe expectedType =
993− (
994− H.reflow $
995− "I need both sides of (" <> op <> ") to be the same type:"
996− ,
997− typeComparison localizer expectedType tipe
998− (
999− "The left side of is:"
1000− ,
1001− "But the right side is:"
1002− ,
1003− [ H.reflow $
1004− "I cannot compare different types though! Which side of (" <> op <> ") is the problem?"
1005− ]
1006− )
1007− )
1142+badCompRight :: Localizer -> String -> Type -> Type -> RightDocs
1143+badCompRight localizer op tipe expectedType =
1144+ EmphBoth
1145+ (
1146+ H.reflow $
1147+ "I need both sides of (" <> op <> ") to be the same type:"
1148+ ,
1149+ typeComparison localizer expectedType tipe
1150+ (
1151+ "The left side of is:"
1152+ ,
1153+ "But the right side is:"
1154+ ,
1155+ [ H.reflow $
1156+ "I cannot compare different types though! Which side of (" <> op <> ") is the problem?"
1157+ ]
1158+ )
1159+ )
10081160
10091161
10101162
10111163-- BAD EQUALITY
10121164
10131165
1014−badEquality :: Type.Localizer -> String -> Can.Type -> Can.Type -> (H.Doc, H.Doc)
1166+badEquality :: Localizer -> String -> Type -> Type -> RightDocs
10151167badEquality localizer op tipe expectedType =
1016− (
1017− H.reflow $
1018− "I need both sides of (" <> op <> ") to be the same type:"
1019− ,
1020− typeComparison localizer expectedType tipe
1021− (
1022− "The left side of is:"
1023− ,
1024− "But the right side is:"
1025− ,
1026− if isFloat tipe || isFloat expectedType then
1027− [ H.toSimpleNote $
1028− "Equality on floats is not 100% reliable due to the design of IEEE 754. I\
1029− \ recommend a check like (abs (x - y) < 0.0001) instead."
1030− ]
1031− else
1032− [ H.reflow $
1033− "Different types can never be equal though! Which side is messed up?"
1034− ]
1035−-- else
1036−-- error "TODO detect problems here instead?"
1037− )
1038− )
1168+ EmphBoth
1169+ (
1170+ H.reflow $
1171+ "I need both sides of (" <> op <> ") to be the same type:"
1172+ ,
1173+ typeComparison localizer expectedType tipe
1174+ (
1175+ "The left side of is:"
1176+ ,
1177+ "But the right side is:"
1178+ ,
1179+ if isFloat tipe || isFloat expectedType then
1180+ [ H.toSimpleNote $
1181+ "Equality on floats is not 100% reliable due to the design of IEEE 754. I\
1182+ \ recommend a check like (abs (x - y) < 0.0001) instead."
1183+ ]
1184+ else
1185+ [ H.reflow $
1186+ "Different types can never be equal though! Which side is messed up?"
1187+ ]
1188+-- else
1189+-- error "TODO detect problems here instead?"
1190+ )
1191+ )
1192+
1193+
1194+
1195+-- DIFF TYPES
1196+
1197+
1198+type Localizer = Map.Map N.Name ()
1199+
1200+
1201+typeComparison :: Localizer -> Type -> Type -> ( String, String, [H.Doc] ) -> H.Doc
1202+typeComparison localizer actual expected ( iAmSeeing, insteadOf, soHereAreSomeThoughts ) =
1203+ let
1204+ (actualDoc, expectedDoc) =
1205+ error "TODO diff" localizer actual expected
1206+ in
1207+ H.stack $
1208+ [ H.reflow iAmSeeing
1209+ , H.indent 4 actualDoc
1210+ , H.reflow insteadOf
1211+ , H.indent 4 expectedDoc
1212+ ]
1213+ ++ soHereAreSomeThoughts
1214+
1215+
1216+indentType :: Localizer -> Type -> H.Doc
1217+indentType localizer tipe =
1218+ H.indent 4 (H.dullyellow (error "TODO Type.toDoc" localizer tipe))
1219+