@@ -26,6 +26,7 @@ import Data.Monoid ((<>))
2626import qualified AST.Canonical as Can
2727import qualified Data.Index as Index
2828import qualified Elm.Name as N
29+import qualified Reporting.Annotation as A
2930import qualified Reporting.Doc as D
3031import qualified Reporting.Region as R
3132import qualified Reporting.Render.Code as Code
@@ -66,7 +67,8 @@ data Context
6667 | CallArity MaybeName Int
6768 | CallArg MaybeName Index.ZeroBased
6869 | RecordAccess N.Name
69− | RecordUpdate N.Name (Map.Map N.Name Can.Expr)
70+ | RecordUpdateKeys N.Name (Map.Map N.Name Can.FieldUpdate)
71+ | RecordUpdateValue N.Name
7072 | Destructure
7173
7274
@@ -384,7 +386,7 @@ addCategory thisIs category maybeAlias =
384386 let
385387 definitely whatever =
386388 case maybeAlias of
387− Just alias -> " a `" <> N.toString alias <> "` value:"
389+ Just alias -> " a `" <> N.toString alias <> "`:"
388390 Nothing -> whatever
389391 in
390392 D.reflow $
@@ -701,6 +703,10 @@ toExprReport source localizer exprRegion category tipe expected =
701703 ( D.reflow problem
702704 , loneType localizer tipe expectedType (addCategory thisIs category) furtherDetails
703705 )
706+
707+ custom maybeHighlight docPair =
708+ Report.Report "TYPE MISMATCH" exprRegion [] $
709+ Report.toCodeSnippet source region maybeHighlight docPair
704710 in
705711 case context of
706712 ListEntry index ->
@@ -731,18 +737,16 @@ toExprReport source localizer exprRegion category tipe expected =
731737 )
732738
733739 OpLeft op ->
734− Report.Report "TYPE MISMATCH" exprRegion [] $
735− Report.toCodeSnippet source region (Just exprRegion) $
736− opLeftToDocs localizer category op tipe expectedType
740+ custom (Just exprRegion) $
741+ opLeftToDocs localizer category op tipe expectedType
737742
738743 OpRight op ->
739− Report.Report "TYPE MISMATCH" exprRegion [] $
740− case opRightToDocs localizer category op tipe expectedType of
741− EmphBoth details ->
742− Report.toCodeSnippet source region Nothing details
744+ case opRightToDocs localizer category op tipe expectedType of
745+ EmphBoth details ->
746+ custom Nothing details
743747
744− EmphRight details ->
745− Report.toCodeSnippet source region (Just exprRegion) details
748+ EmphRight details ->
749+ custom (Just exprRegion) details
746750
747751 IfCondition ->
748752 badType
@@ -862,34 +866,43 @@ toExprReport source localizer exprRegion category tipe expected =
862866 ]
863867 )
864868
865− RecordUpdate name updatedFields ->
866− badType $
869+ RecordUpdateKeys record expectedFields ->
867870 case T.getFields tipe of
868871 Nothing ->
872+ badType
869873 ( Just exprRegion
870− , "I cannot update the `" <> N.toString name <> "` value:"
874+ , "This is not a record, so it has no fields to update!"
871875 , "It is"
872− , [ D.reflow $ "It is not a record. It has no fields to update!"
876+ , [ D.reflow $ "But I need a record!"
873877 ]
874878 )
875879
876− Just _fields ->
877− case Map.keys updatedFields of
878− [field] ->
879− ( Nothing
880− , "The `" <> N.toString name <> "` record does not have a `" <> N.toString field <> "` field."
881− , "It is"
882− , [ -- TODO suggest what the typo is!
880+ Just actualFields ->
881+ case Map.foldrWithKey addLocatedField [] (Map.difference expectedFields actualFields) of
882+ [] ->
883+ error "TODO RecordUpdateKeys"
884+
885+ A.At fieldRegion field : _ ->
886+ badType
887+ ( Just fieldRegion
888+ , "The `" <> N.toString record <> "` record does not have a `" <> N.toString field <> "` field:"
889+ , "The `" <> N.toString record <> "` is"
890+ , [ D.reflow $ "So maybe you want one of these fields instead? TODO make suggestions!"
891+ -- TODO suggest what the typo is!
883892 ]
884893 )
885894
886− _ ->
887− ( Nothing
888− , "The `" <> N.toString name <> "` record does have all of these fields:"
889− , "It is"
890− , [ -- TODO suggest what the typo is!
891− ]
892− )
895+ RecordUpdateValue field ->
896+ mismatch
897+ ( Just exprRegion
898+ , "I cannot update the `" <> N.toString field <> "` field like this:"
899+ , "You are trying to update `" <> N.toString field <> "` to be"
900+ , singular "But it should be"
901+ , [ D.toSimpleNote
902+ "The record update syntax does not allow you to change the type of fields.\
903+ \ You can achieve that with record constructors or the record literal syntax."
904+ ]
905+ )
893906
894907 Destructure ->
895908 mismatch
@@ -902,7 +915,7 @@ toExprReport source localizer exprRegion category tipe expected =
902915
903916
904917
905−-- COUNT ARGS
918+-- HELPERS
906919
907920
908921countArgs :: T.Type -> Int
@@ -915,6 +928,11 @@ countArgs tipe =
915928 0
916929
917930
931+addLocatedField :: N.Name -> Can.FieldUpdate -> [A.Located N.Name] -> [A.Located N.Name]
932+addLocatedField name (Can.FieldUpdate region _) names =
933+ A.At region name : names
934+
935+
918936
919937-- OP LEFT
920938