on master help sign in
Get rid of a bunch of TODOs in type errors

To get things done, it makes sense to keep 0.18 quality as the bar I must achieve. That means I can skip the 1st vs 2nd special case for now. And the missing arg scenario for now. Plan is to improve those separately, since they do not block a release.

commit3d14963b615b12ecacd09f4145495a049764b784 authorEvan Czaplicki <evancz@users.noreply.github.com> dateFri 9 Feb 2018, 18:17 (9 years ago) parentdd2feec
1 file changed+129−198
src/Reporting/Error/Type.hs+129−198
src/Reporting/Error/Type.hs+129−198
@@ -230,7 +230,7 @@ toMismatchReport source localizer exprRegion category tipe expected =
230230 )
231231 )
232232
233− FromAnnotation name arity subContext expectedType ->
233+ FromAnnotation name _arity subContext expectedType ->
234234 Report.toCodeSnippet source exprRegion Nothing
235235 (
236236 H.reflow $
@@ -259,39 +259,33 @@ toMismatchReport source localizer exprRegion category tipe expected =
259259 ,
260260 "But the type annotation on `" <> N.toString name <> "` says it should be:"
261261 ,
262− [ error "TODO check for arity issues. Suggest that an arg is unlisted." arity
263− --, problem
264− ]
262+ []
265263 )
266264 )
267265
268266 FromContext region context expectedType ->
269267 case context of
270268 ListEntry index ->
271− if Index.toHuman index == 2 then
272− error "TODO 1st vs 2nd list entry"
273− else
274− Report.toCodeSnippet source region (Just exprRegion)
275− (
276− H.reflow $
277− "The " <> H.ordinalize (Index.toHuman index) <> " element of this list does not match all the previous elements:"
278− ,
279− typeComparison localizer tipe expectedType
280− (
281− toDescription category $
282− "The " <> H.ordinalize (Index.toHuman index) <> " element is"
283− ,
284− "But all the previous elements in the list are:"
285− ,
286− [ H.toSimpleHint $
287− "Everything in the list needs to be the same type of value.\
288− \ This way you never run into unexpected values partway through.\
289− \ To mix different types in a single list, create a \"union type\" as\
290− \ described in: <http://guide.elm-lang.org/types/union_types.html>"
291− --, problem
292− ]
293− )
294− )
269+ Report.toCodeSnippet source region (Just exprRegion)
270+ (
271+ H.reflow $
272+ "The " <> H.ordinalize (Index.toHuman index) <> " element of this list does not match all the previous elements:"
273+ ,
274+ typeComparison localizer tipe expectedType
275+ (
276+ toDescription category $
277+ "The " <> H.ordinalize (Index.toHuman index) <> " element is"
278+ ,
279+ "But all the previous elements in the list are:"
280+ ,
281+ [ H.toSimpleHint $
282+ "Everything in the list needs to be the same type of value.\
283+ \ This way you never run into unexpected values partway through.\
284+ \ To mix different types in a single list, create a \"union type\" as\
285+ \ described in: <http://guide.elm-lang.org/types/union_types.html>"
286+ ]
287+ )
288+ )
295289
296290 Negate ->
297291 Report.toCodeSnippet source region (Just exprRegion)
@@ -337,57 +331,48 @@ toMismatchReport source localizer exprRegion category tipe expected =
337331 )
338332
339333 IfBranch index ->
340− if Index.toHuman index == 2 then
341− error "TODO 1st vs 2nd if branches"
342− -- error "TODO if with no chaining"
343− else
344− Report.toCodeSnippet source region (Just exprRegion)
345− (
346− H.reflow $
347− "The " <> H.ordinalize (Index.toHuman index) <> " branch of this `if` does not match all the previous branches:"
348− ,
349− typeComparison localizer tipe expectedType
350− (
351− toDescription category $
352− "The " <> H.ordinalize (Index.toHuman index) <> " branch is"
353− ,
354− "But all the previous branches result in:"
355− ,
356− [ H.link "Hint"
357− "All branches in an `if` must produce the same type of values. This way, no\
358− \ matter which branch we take, the result is always a consistent shape. Read"
359− "union-types"
360− "to learn how to “mix” types."
361− --, problem
362− ]
363− )
364− )
334+ Report.toCodeSnippet source region (Just exprRegion)
335+ (
336+ H.reflow $
337+ "The " <> H.ordinalize (Index.toHuman index) <> " branch of this `if` does not match all the previous branches:"
338+ ,
339+ typeComparison localizer tipe expectedType
340+ (
341+ toDescription category $
342+ "The " <> H.ordinalize (Index.toHuman index) <> " branch is"
343+ ,
344+ "But all the previous branches result in:"
345+ ,
346+ [ H.link "Hint"
347+ "All branches in an `if` must produce the same type of values. This way, no\
348+ \ matter which branch we take, the result is always a consistent shape. Read"
349+ "union-types"
350+ "to learn how to “mix” types."
351+ ]
352+ )
353+ )
365354
366355 CaseBranch index ->
367− if Index.toHuman index == 2 then
368− error "TODO 1st vs 2nd case branches"
369− else
370− Report.toCodeSnippet source region (Just exprRegion)
371− (
372− H.reflow $
373− "The " <> H.ordinalize (Index.toHuman index) <> " branch of this `case` does not match all the previous branches:"
374− ,
375− typeComparison localizer tipe expectedType
376− (
377− toDescription category $
378− "The " <> H.ordinalize (Index.toHuman index) <> " branch is"
379− ,
380− "But all the previous branches result in:"
381− ,
382− [ H.link "Hint"
383− "All branches in a `case` must produce the same type of values. This way, no\
384− \ matter which branch we take, the result is always a consistent shape. Read"
385− "union-types"
386− "to learn how to “mix” types."
387− --, problem
388− ]
389− )
390− )
356+ Report.toCodeSnippet source region (Just exprRegion)
357+ (
358+ H.reflow $
359+ "The " <> H.ordinalize (Index.toHuman index) <> " branch of this `case` does not match all the previous branches:"
360+ ,
361+ typeComparison localizer tipe expectedType
362+ (
363+ toDescription category $
364+ "The " <> H.ordinalize (Index.toHuman index) <> " branch is"
365+ ,
366+ "But all the previous branches result in:"
367+ ,
368+ [ H.link "Hint"
369+ "All branches in a `case` must produce the same type of values. This way, no\
370+ \ matter which branch we take, the result is always a consistent shape. Read"
371+ "union-types"
372+ "to learn how to “mix” types."
373+ ]
374+ )
375+ )
391376
392377 CallArg maybeFuncName index ->
393378 let
@@ -508,7 +493,7 @@ toMismatchReport source localizer exprRegion category tipe expected =
508493
509494 RecordAccess field ->
510495 Report.toCodeSnippet source region (Just exprRegion) $
511− case error "TODO figure out record things" tipe of
496+ case tipe of
512497 T.Record _ _ ->
513498 (
514499 H.reflow $
@@ -521,62 +506,38 @@ toMismatchReport source localizer exprRegion category tipe expected =
521506 , H.reflow $
522507 "So maybe the ." <> N.toString field <> " field access is misspelled?"
523508 ]
524− ++
525− case error "TODO closeNames" of
526− [] ->
527− []
528−
529− [name] ->
530− [ H.toFancyHint $
531− ["It","may","also","be","a","typo","in","the","record","itself."
532− ,"Perhaps","the",H.dullyellow name,"field","is","misspelled?"
533− ]
534− ]
535−
536− names ->
537− [ H.toFancyHint $
538− ["It","may","also","be","a","typo","in","the","record","itself."
539− ,"Perhaps","the"
540− ]
541− ++ H.commaSep "or" H.dullyellow names
542− ++ ["field","is","misspelled?"]
543− ]
544− )
545−
546− T.Lambda _ _ _ ->
547− (
548− H.reflow $
549− "I cannot access field `" <> N.toString field <> "` of this " <> whatever <> ":"
550− ,
551− H.stack
552− [ H.reflow $
553− "The " <> whatever <> " is not a record! It is actually a function:"
554− , indentType localizer tipe
555− , H.toSimpleHint "Maybe it is missing some arguments?"
556− ]
557509 )
558510
559511 _ ->
560512 (
561513 H.reflow $
562− "I cannot access field `" <> N.toString field <> "` of this " <> whatever <> ":"
514+ "This is not a record, so it has no fields to access!"
563515 ,
564516 H.stack
565− [ H.reflow $
566− "The " <> whatever <> " is not a record though! It is a:"
517+ [ H.reflow $ toDescription category "It is"
567518 , indentType localizer tipe
519+ , H.fillSep
520+ ["But","I","need","a","record","with","a",H.dullyellow (H.nameToDoc field),"field!"]
568521 ]
569522 )
570523
571524 RecordUpdate ->
572− case error "TODO figure out record things" tipe of
525+ case tipe of
573526 T.Record _ _ ->
574− Report.toCodeSnippet source region Nothing
527+ Report.toCodeSnippet source region Nothing $
575528 (
576529 H.reflow $
577530 "I think there is a typo in one of these field names:"
578531 ,
579− error "TODO record update field name typo"
532+ typeComparison localizer tipe expectedType
533+ (
534+ "The record you want to update has type:"
535+ ,
536+ "But you are saying it should have these fields:"
537+ ,
538+ [ H.reflow "Maybe there is some typo?"
539+ ]
540+ )
580541 )
581542
582543 _ ->
@@ -585,14 +546,27 @@ toMismatchReport source localizer exprRegion category tipe expected =
585546 "The record update syntax does not work with this value:"
586547 ,
587548 H.stack
588− [ H.reflow $
589− "I can only update records, but this appears to be a " <> whatever <> ":"
549+ [ H.reflow $ toDescription category "It is"
590550 , indentType localizer tipe
551+ , H.reflow $ "But I need some kind of record here!"
591552 ]
592553 )
593554
594555 Destructure ->
595− error "TODO Destructure"
556+ Report.toCodeSnippet source region Nothing
557+ (
558+ H.reflow $
559+ "I cannot destructure "
560+ ,
561+ typeComparison localizer tipe expectedType
562+ (
563+ toDescription category "You are defining"
564+ ,
565+ "But then trying to destructure it as:"
566+ ,
567+ []
568+ )
569+ )
596570
597571
598572
@@ -618,15 +592,15 @@ opLeftToDocs localizer category op tipe expectedType =
618592 case op of
619593 "+"
620594 | isString tipe -> badStringAdd
621− | isList tipe -> badListAdd localizer "left" tipe
622− | otherwise -> badMath localizer "Addition" "left" "+" tipe []
595+ | isList tipe -> badListAdd localizer category "left" tipe
596+ | otherwise -> badMath localizer category "Addition" "left" "+" tipe []
623597
624598 "*"
625− | isList tipe -> badListMul localizer "left" tipe
626− | otherwise -> badMath localizer "Multiplication" "left" "*" tipe []
599+ | isList tipe -> badListMul localizer category "left" tipe
600+ | otherwise -> badMath localizer category "Multiplication" "left" "*" tipe []
627601
628− "-" -> badMath localizer "Subtraction" "left" "-" tipe []
629− "^" -> badMath localizer "Exponentiation" "left" "^" tipe []
602+ "-" -> badMath localizer category "Subtraction" "left" "-" tipe []
603+ "^" -> badMath localizer category "Exponentiation" "left" "^" tipe []
630604 "/" -> badFDiv localizer "left" tipe
631605 "//" -> badIDiv localizer "left" tipe
632606 "&&" -> badBool localizer "&&" "left" tipe
@@ -640,18 +614,9 @@ opLeftToDocs localizer category op tipe expectedType =
640614 ( "The left side of (<|) needs to be a function so I can pipe arguments to it!"
641615 ,
642616 H.stack
643− [ H.reflow $
644− "Instead of a function, I am seeing " <> whatever <> ":"
617+ [ H.reflow $ toDescription category "I am seeing"
645618 , indentType localizer tipe
646− , error "TODO"
647− {-
648− case category of
649− Call ->
650− "Maybe you gave " <> funcName <> " too many arguments already?"
651−
652− _ ->
653− []
654− -}
619+ , H.reflow $ "This needs to be some kind of function though!"
655620 ]
656621 )
657622
@@ -687,24 +652,24 @@ opRightToDocs localizer category op tipe expectedType =
687652 | isInt tipe -> badCast op FloatInt
688653 | isFloat tipe -> badCast op IntFloat
689654 | isString tipe -> EmphRight $ badStringAdd
690− | isList tipe -> EmphRight $ badListAdd localizer "right" tipe
691− | otherwise -> EmphRight $ badMath localizer "Addition" "right" "+" tipe []
655+ | isList tipe -> EmphRight $ badListAdd localizer category "right" tipe
656+ | otherwise -> EmphRight $ badMath localizer category "Addition" "right" "+" tipe []
692657
693658 "*"
694659 | isInt tipe -> badCast op FloatInt
695660 | isFloat tipe -> badCast op IntFloat
696− | isList tipe -> EmphRight $ badListMul localizer "right" tipe
697− | otherwise -> EmphRight $ badMath localizer "Multiplication" "right" "*" tipe []
661+ | isList tipe -> EmphRight $ badListMul localizer category "right" tipe
662+ | otherwise -> EmphRight $ badMath localizer category "Multiplication" "right" "*" tipe []
698663
699664 "-"
700665 | isInt tipe -> badCast op FloatInt
701666 | isFloat tipe -> badCast op IntFloat
702− | otherwise -> EmphRight $ badMath localizer "Subtraction" "right" "-" tipe []
667+ | otherwise -> EmphRight $ badMath localizer category "Subtraction" "right" "-" tipe []
703668
704669 "^"
705670 | isInt tipe -> badCast op FloatInt
706671 | isFloat tipe -> badCast op IntFloat
707− | otherwise -> EmphRight $ badMath localizer "Exponentiation" "right" "^" tipe []
672+ | otherwise -> EmphRight $ badMath localizer category "Exponentiation" "right" "^" tipe []
708673
709674 "/" -> EmphRight $ badFDiv localizer "right" tipe
710675 "//" -> EmphRight $ badIDiv localizer "right" tipe
@@ -724,7 +689,7 @@ opRightToDocs localizer category op tipe expectedType =
724689 EmphRight
725690 (
726691 H.reflow $
727− "I cannot pipe this " <> whatever <> " in as the final argument:"
692+ "I cannot send this through the (<|) pipe:"
728693 ,
729694 typeComparison localizer tipe expectedType
730695 (
@@ -732,9 +697,7 @@ opRightToDocs localizer category op tipe expectedType =
732697 ,
733698 "But (<|) is piping it a function that expects:"
734699 ,
735− [ "Maybe an argument is missing?"
736−-- , problem
737− ]
700+ []
738701 )
739702 )
740703
@@ -743,29 +706,15 @@ opRightToDocs localizer category op tipe expectedType =
743706 (T.Lambda expectedArgType _ _, T.Lambda argType _ _) ->
744707 EmphRight
745708 (
746− -- TODO try to say the function name instead of "this function"
747− "I cannot pipe the argument through to this function:"
709+ "This function cannot handle the argument sent through the (|>) pipe:"
748710 ,
749711 typeComparison localizer argType expectedArgType
750712 (
751713 "You are providing an argument of type:"
752714 ,
753715 "But (|>) is piping it a function that expects its next argument to be:"
754− {-
755− case maybeName of
756− Nothing ->
757− "But (|>) is piping it a function that expects the next argument to be:"
758−
759− Just (FuncName name) ->
760− "But (|>) is piping it to `" <> N.toString name <> "` which expects the next argument to be:"
761−
762− Just (OpName op) ->
763− "But (|>) is piping it to (" <> N.toString op <> ") which expects the next argument to be:"
764− -}
765716 ,
766− [ "Maybe an argument is missing?"
767−-- , problem
768− ]
717+ []
769718 )
770719 )
771720
@@ -775,18 +724,9 @@ opRightToDocs localizer category op tipe expectedType =
775724 "The right side of (|>) needs to be a function so I can pipe arguments to it!"
776725 ,
777726 H.stack
778− [ H.reflow $
779− "Instead of a function, I am seeing " <> whatever <> ":"
727+ [ H.reflow $ toDescription category $
728+ "Instead of a function, I am seeing "
780729 , indentType localizer tipe
781− , error "TODO"
782− {-
783− case category of
784− Call ->
785− "Maybe you gave " <> funcName <> " too many arguments already?"
786−
787− _ ->
788− []
789− -}
790730 ]
791731 )
792732
@@ -802,12 +742,11 @@ opRightToDocs localizer category op tipe expectedType =
802742 ,
803743 "But (" <> N.toString op <> ") needs the right argument to be:"
804744 ,
805− error "TODO"
806− {-
807− [ problem
808− , binopHint home op leftType rightType
745+ [ H.toSimpleHint $
746+ "With operators like (" ++ N.toString op ++ ") I always check the left\
747+ \ side first. If it seems fine, I assume it is correct and check the right\
748+ \ side. So the problem may be in how the left and right arguments interact!"
809749 ]
810− -}
811750 )
812751 )
813752
@@ -853,11 +792,6 @@ isList tipe =
853792 False
854793
855794
856−whatever :: String
857−whatever =
858− error "TODO whatever"
859−
860−
861795
862796-- BAD MATH
863797
@@ -920,14 +854,14 @@ badStringAdd =
920854 )
921855
922856
923−badListAdd :: T.Localizer -> String -> T.Type -> (H.Doc, H.Doc)
924−badListAdd localizer direction tipe =
857+badListAdd :: T.Localizer -> Category -> String -> T.Type -> (H.Doc, H.Doc)
858+badListAdd localizer category direction tipe =
925859 (
926860 "I cannot do addition with lists:"
927861 ,
928862 H.stack
929− [ H.reflow $
930− "The " <> direction <> " side of (+) is " <> whatever <> ":"
863+ [ H.reflow $ toDescription category $
864+ "The " <> direction <> " side of (+) is"
931865 , indentType localizer tipe
932866 , H.fillSep
933867 ["But","(+)","only","works","with",H.dullyellow "Int","and",H.dullyellow "Float","values."
@@ -939,9 +873,9 @@ badListAdd localizer direction tipe =
939873 )
940874
941875
942−badListMul :: T.Localizer -> String -> T.Type -> (H.Doc, H.Doc)
943−badListMul localizer direction tipe =
944− badMath localizer "Multiplication" direction "*" tipe
876+badListMul :: T.Localizer -> Category -> String -> T.Type -> (H.Doc, H.Doc)
877+badListMul localizer category direction tipe =
878+ badMath localizer category "Multiplication" direction "*" tipe
945879 [
946880 H.toFancyHint
947881 [ "Maybe", "you", "want"
@@ -951,21 +885,20 @@ badListMul localizer direction tipe =
951885 ]
952886
953887
954−badMath :: T.Localizer -> String -> String -> String -> T.Type -> [H.Doc] -> (H.Doc, H.Doc)
955−badMath localizer operation direction op tipe otherHints =
888+badMath :: T.Localizer -> Category -> String -> String -> String -> T.Type -> [H.Doc] -> (H.Doc, H.Doc)
889+badMath localizer category operation direction op tipe otherHints =
956890 (
957891 H.reflow $
958892 operation ++ " does not work with this value:"
959893 ,
960894 H.stack $
961− [ H.reflow $
962− "The " <> direction <> " side of (" <> op <> ") is a " <> whatever <> ":"
895+ [ H.reflow $ toDescription category $
896+ "The " <> direction <> " side of (" <> op <> ") is"
963897 , indentType localizer tipe
964898 , H.fillSep
965899 ["But","(" <> H.text op <> ")","only","works","with"
966900 ,H.dullyellow "Int","and",H.dullyellow "Float","values."
967901 ]
968− , error "TODO check for missing arguments"
969902 ]
970903 ++ otherHints
971904 )
@@ -1136,8 +1069,6 @@ badEquality localizer op tipe expectedType =
11361069 [ H.reflow $
11371070 "Different types can never be equal though! Which side is messed up?"
11381071 ]
1139−-- else
1140−-- error "TODO detect problems here instead?"
11411072 )
11421073 )
11431074