on master help sign in
Work on TODO for bad type variables in type aliases
commit07712e911d0214a5457b590c86c7760f56da6d6e authorEvan Czaplicki <evancz@users.noreply.github.com> dateMon 19 Feb 2018, 15:26 (9 years ago) parent3116898
2 files changed+124−107
src/Canonicalize/Environment/Local.hs+2−3 src/Reporting/Error/Canonicalize.hs+122−104
src/Canonicalize/Environment/Local.hs+2−3
@@ -219,12 +219,11 @@ checkAliasFreeVars (Valid.Alias aliasRegion (A.At _ name) args tipe) =
219219 if Map.size boundVars == overlap && Map.size freeVars == overlap
220220 then Result.ok (map A.toValue args)
221221 else
222− let toLoc (arg, region) = A.At region arg in
223222 Result.throw $
224223 Error.TypeVarsMessedUpInAlias aliasRegion name
225224 (map A.toValue args)
226− (map toLoc (Map.toList (Map.difference boundVars freeVars)))
227− (map toLoc (Map.toList (Map.difference freeVars boundVars)))
225+ (Map.toList (Map.difference boundVars freeVars))
226+ (Map.toList (Map.difference freeVars boundVars))
228227
229228
230229addFreeVars :: Map.Map N.Name R.Region -> Src.Type -> Map.Map N.Name R.Region
src/Reporting/Error/Canonicalize.hs+122−104
@@ -73,7 +73,7 @@ data Error
7373 | Shadowing N.Name R.Region R.Region
7474 | TupleLargerThanThree R.Region
7575 | TypeVarsUnboundInUnion R.Region N.Name [N.Name] (N.Name, R.Region) [(N.Name, R.Region)]
76− | TypeVarsMessedUpInAlias R.Region N.Name [N.Name] [A.Located N.Name] [A.Located N.Name]
76+ | TypeVarsMessedUpInAlias R.Region N.Name [N.Name] [(N.Name, R.Region)] [(N.Name, R.Region)]
7777
7878
7979data BadArityContext
@@ -735,114 +735,133 @@ toReport source err =
735735 ]
736736 )
737737
738− TypeVarsUnboundInUnion unionRegion tipe allVars (unboundVar, varRegion) unboundVars ->
739− let
740− backQuote name =
741− "`" <> H.nameToDoc name <> "`"
738+ TypeVarsUnboundInUnion unionRegion typeName allVars unbound unbounds ->
739+ unboundTypeVars source unionRegion ["type"] typeName allVars unbound unbounds
742740
743− (title, subRegion, overview) =
744− case map fst unboundVars of
745− [] ->
746− ( "UNBOUND TYPE VARIABLE"
747− , Just varRegion
748− , ["The",backQuote tipe,"type","uses","an","unbound","type","variable"
749− ,H.dullyellow (backQuote unboundVar),"in","its","definition:"
750− ]
741+ TypeVarsMessedUpInAlias aliasRegion typeName allVars unusedVars unboundVars ->
742+ case (unusedVars, unboundVars) of
743+ (unused:unuseds, []) ->
744+ let
745+ backQuote name =
746+ "`" <> H.nameToDoc name <> "`"
747+
748+ allUnusedNames =
749+ map fst unusedVars
750+
751+ (title, subRegion, overview, stuff) =
752+ case unuseds of
753+ [] ->
754+ ("UNUSED TYPE VARIABLE"
755+ , Just (snd unused)
756+ , ["Type","alias",backQuote typeName,"does","not","use","the"
757+ ,backQuote (fst unused),"type","variable."
758+ ]
759+ , [H.dullyellow (backQuote (fst unused))]
760+ )
761+
762+ _:_ ->
763+ ( "UNUSED TYPE VARIABLES"
764+ , Nothing
765+ , ["Type","variables"]
766+ ++ H.commaSep "and" id (map H.nameToDoc allUnusedNames)
767+ ++ ["are","unused","in","the",backQuote typeName,"definition."]
768+ , H.commaSep "and" H.dullyellow (map H.nameToDoc allUnusedNames)
769+ )
770+ in
771+ Report.Report title aliasRegion [] $
772+ Report.toCodeSnippet source aliasRegion subRegion
773+ (
774+ H.fillSep overview
775+ ,
776+ H.stack
777+ [ H.fillSep $
778+ ["I","recommend","removing"] ++ stuff ++ ["from","the","declaration,","like","this:"]
779+ , H.indent 4 $ H.hsep $
780+ ["type","alias",H.nameToDoc typeName]
781+ ++ map H.nameToDoc (filter (\v -> notElem v allUnusedNames) allVars)
782+ ++ ["=", "..."]
783+ , H.reflow $
784+ "Why? Well, if I allowed `type alias Height a = Float` I would need to answer\
785+ \ some weird questions. Is `Height Bool` the same as `Float`? Is `Height Bool`\
786+ \ the same as `Height Int`? My solution is to not need to ask them!"
787+ ]
751788 )
752789
753− vars ->
754− ( "UNBOUND TYPE VARIABLES"
755− , Nothing
756− , ["Type","variables"]
757− ++ H.commaSep "and" H.dullyellow (H.nameToDoc unboundVar : map H.nameToDoc vars)
758− ++ ["are","unbound","in","the",backQuote tipe,"type","definition:"]
790+ ([], unbound:unbounds) ->
791+ unboundTypeVars source aliasRegion ["type","alias"] typeName allVars unbound unbounds
792+
793+ (_, _) ->
794+ error "TODO TypeVarsMessedUpInAlias"
795+ {-
796+ Report.Report "TYPE VARIABLE PROBLEMS" aliasRegion [] $
797+ Report.toCodeSnippet source region Nothing
798+ (
799+ H.reflow $
800+ "Type alias `" <> typeName <> "` has some type variable problems."
801+ ,
802+ H.stack
803+ [ H.reflow $
804+ "The definition uses certain type variables ("
805+ <> H.commaSep unused <> ") but they do not appear in the aliased type. "
806+ <> "Furthermore, the aliased type says it uses type variables ("
807+ <> H.commaSep unbound
808+ <> ") that do not appear in the declaration."
809+ , text "You probably need to change the declaration like this:"
810+ , H.dullyellow $ hsep $
811+ map text ("type" : "alias" : typeName : filter (`notElem` unused) givenVars ++ unbound ++ ["=", "..."])
812+ ]
759813 )
760− in
761− Report.Report title unionRegion [] $
762− Report.toCodeSnippet source unionRegion subRegion
763− (
764− H.fillSep overview
765− ,
766− H.stack
767− [ H.reflow $
768− "You probably need to change the type declaration to something like this:"
769− , H.indent 4 $ H.hsep $
770− ["type", H.nameToDoc tipe]
771− ++ map H.nameToDoc allVars
772− ++ map (H.green . H.nameToDoc) (unboundVar : map fst unboundVars)
773− ++ ["=", "..."]
774− , H.reflow $
775− "Why? Well, imagine one `" ++ N.toString tipe ++ "` where `" ++ N.toString unboundVar ++
776− "` is an Int and another where it is a Bool. When we explicitly list the type\
777− \ variables, the type checker can see that they are actually different types."
778− ]
814+ -}
815+
816+
817+
818+-- BAD TYPE VARIABLES
819+
820+
821+unboundTypeVars :: Code.Source -> R.Region -> [H.Doc] -> N.Name -> [N.Name] -> (N.Name, R.Region) -> [(N.Name, R.Region)] -> Report.Report
822+unboundTypeVars source declRegion tipe typeName allVars (unboundVar, varRegion) unboundVars =
823+ let
824+ backQuote name =
825+ "`" <> H.nameToDoc name <> "`"
826+
827+ (title, subRegion, overview) =
828+ case map fst unboundVars of
829+ [] ->
830+ ( "UNBOUND TYPE VARIABLE"
831+ , Just varRegion
832+ , ["The",backQuote typeName]
833+ ++ tipe
834+ ++ ["uses","an","unbound","type","variable",H.dullyellow (backQuote unboundVar),"in","its","definition:"]
779835 )
780836
781− TypeVarsMessedUpInAlias _ _ _ _ _ ->
782− error "TODO TypeVarsMessedUpInAlias"
783−
784−
785−
786−-- UnboundTypeVarsInUnion typeName givenVars unbound ->
787−-- unboundTypeVars "type" typeName givenVars unbound
788−
789−-- UnboundTypeVarsInAlias typeName givenVars unbound ->
790−-- unboundTypeVars "type alias" typeName givenVars unbound
791−
792−-- UnusedTypeVarsInAlias typeName givenVars unused ->
793−-- Report.report
794−-- "UNUSED TYPE VARIABLES"
795−-- Nothing
796−-- ( "Type alias `" <> typeName <> "` cannot have unused type variables: "
797−-- <> H.commaSep unused
798−-- )
799−-- ( H.stack
800−-- [ text "You probably need to change the declaration like this:"
801−-- , H.dullyellow $ hsep $
802−-- map text ("type" : "alias" : typeName : filter (`notElem` unused) givenVars ++ ["=", "..."])
803−-- ]
804−-- )
805−
806−-- MessyTypeVarsInAlias typeName givenVars unused unbound ->
807−-- Report.report
808−-- "TYPE VARIABLE PROBLEMS"
809−-- Nothing
810−-- ( "Type alias `" <> typeName <> "` has some problems with type variables."
811−-- )
812−-- ( H.stack
813−-- [ H.reflow $
814−-- "The declaration says it uses certain type variables ("
815−-- <> H.commaSep unused <> ") but they do not appear in the aliased type. "
816−-- <> "Furthermore, the aliased type says it uses type variables ("
817−-- <> H.commaSep unbound
818−-- <> ") that do not appear in the declaration."
819−-- , text "You probably need to change the declaration like this:"
820−-- , H.dullyellow $ hsep $
821−-- map text ("type" : "alias" : typeName : filter (`notElem` unused) givenVars ++ unbound ++ ["=", "..."])
822−-- ]
823−-- )
824−
825−
826−--unboundTypeVars :: Text -> Text -> [Text] -> [Text] -> Report.Report
827−--unboundTypeVars declKind typeName givenVars unboundVars =
828−-- Report.report
829−-- "UNBOUND TYPE VARIABLES"
830−-- Nothing
831−-- ( H.capitalize declKind <> " `" <> typeName <> "` must declare its use of type variable"
832−-- <> H.commaSep unboundVars
833−-- )
834−-- ( H.stack
835−-- [ text "You probably need to change the declaration like this:"
836−-- , hsep $
837−-- map text (declKind : typeName : givenVars)
838−-- ++ map (H.dullyellow . text) unboundVars
839−-- ++ map text ["=", "..."]
840−-- , reflow $
841−-- "Here's why. Imagine one `" <> typeName <> "` where `" <> head unboundVars <>
842−-- "` is an Int and another where it is a Bool. When we explicitly list the type\
843−-- \ variables, the type checker can see that they are actually different types."
844−-- ]
845−-- )
837+ vars ->
838+ ( "UNBOUND TYPE VARIABLES"
839+ , Nothing
840+ , ["Type","variables"]
841+ ++ H.commaSep "and" H.dullyellow (H.nameToDoc unboundVar : map H.nameToDoc vars)
842+ ++ ["are","unbound","in","the",backQuote typeName] ++ tipe ++ ["definition:"]
843+ )
844+ in
845+ Report.Report title declRegion [] $
846+ Report.toCodeSnippet source declRegion subRegion
847+ (
848+ H.fillSep overview
849+ ,
850+ H.stack
851+ [ H.reflow $
852+ "You probably need to change the declaration to something like this:"
853+ , H.indent 4 $ H.hsep $
854+ tipe
855+ ++ [H.nameToDoc typeName]
856+ ++ map H.nameToDoc allVars
857+ ++ map (H.green . H.nameToDoc) (unboundVar : map fst unboundVars)
858+ ++ ["=", "..."]
859+ , H.reflow $
860+ "Why? Well, imagine one `" ++ N.toString typeName ++ "` where `" ++ N.toString unboundVar ++
861+ "` is an Int and another where it is a Bool. When we explicitly list the type\
862+ \ variables, the type checker can see that they are actually different types."
863+ ]
864+ )
846865
847866
848867
@@ -921,7 +940,6 @@ ambiguousName source region maybePrefix name possibleHomes thing =
921940
922941
923942
924−
925943-- NOT FOUND
926944
927945