@@ -5,10 +5,10 @@ import Control.Monad.Except (ExceptT, throwError, runExceptT)
5import Control.Monad.State as State
5import Control.Monad.State as State
6import qualified Data.List as List
6import qualified Data.List as List
7import qualified Data.Map as Map
7import qualified Data.Map as Map
8−import qualified Data.Maybe as Maybe
9import qualified Data.UnionFind.IO as UF
8import qualified Data.UnionFind.IO as UF
10import Text.PrettyPrint (render)
9import Text.PrettyPrint (render)
11+import qualified AST.Type as AstType
12import qualified AST.Variable as Var
12import qualified AST.Variable as Var
13import qualified Reporting.Region as R
13import qualified Reporting.Region as R
14import qualified Reporting.Error.Type as Error
14import qualified Reporting.Error.Type as Error
@@ -30,29 +30,30 @@ unify hint region variable1 variable2 =
30 Right state ->
30 Right state ->
31 return state
31 return state
33− Left (Error.MismatchInfo maybeMessage leftType rightType) ->
33+ Left (RawMismatch (leftType, rightType, note)) ->
35− trueHint = Error.mergeHint hint maybeMessage
37− TS.addError region $ Error.Mismatch $
34+ TS.addError region $ Error.Mismatch $
38− Error.MismatchInfo trueHint leftType rightType
35+ Error.MismatchInfo hint leftType rightType note
41-- ACTUALLY UNIFY STUFF
38-- ACTUALLY UNIFY STUFF
43type Unify =
40type Unify =
44− ExceptT (Error.Mismatch (Maybe String)) (StateT TS.SolverState IO)
41+ ExceptT RawMismatch (StateT TS.SolverState IO)
45+ RawMismatch (AstType.Canonical, AstType.Canonical, Error.Note)
49− -> UF.Point Descriptor
49+ :: UF.Point Descriptor
50 -> UF.Point Descriptor
50 -> UF.Point Descriptor
51 -> Unify a
52 -> Unify a
52−typeError hint leftType rightType =
53+typeError leftType rightType note =
53 do leftSrcType <- liftIO (toSrcType leftType)
54 do leftSrcType <- liftIO (toSrcType leftType)
54 rightSrcType <- liftIO (toSrcType rightType)
55 rightSrcType <- liftIO (toSrcType rightType)
55− throwError (Error.MismatchInfo hint leftSrcType rightSrcType)
56+ throwError (RawMismatch (leftSrcType, rightSrcType, note))
58unifyHelp :: Variable -> Variable -> Unify ()
59unifyHelp :: Variable -> Variable -> Unify ()
@@ -120,23 +121,16 @@ actuallyUnify variable1 variable2 = do
120 Var.BuiltIn | name `elem` ["Int","Float"] -> flexAndUnify svar
121 Var.BuiltIn | name `elem` ["Int","Float"] -> flexAndUnify svar
121 Var.Local | List.isPrefixOf "number" name -> flexAndUnify svar
122 Var.Local | List.isPrefixOf "number" name -> flexAndUnify svar
123− let hint = "Looks like something besides an Int or Float is being used as a number."
125− typeError (Just hint) variable1 variable2
124+ typeError variable1 variable2 Error.NoNote
127− comparableError maybe =
126+ comparableError maybeHint =
128− typeError (Just $ Maybe.fromMaybe msg maybe) variable1 variable2
127+ typeError variable1 variable2 $ Error.PostNote $
131− "Looks like you want something comparable, but the only valid comparable\n\
132− \types are Int, Float, Char, String, lists, and tuples."
128+ "Note: comparable types include Int, Float, Char, String, lists, and tuples."
133−
129+ ++ maybe "" ("\n"++) maybeHint
134− appendableError maybe =
131+ appendableError =
135− typeError (Just $ Maybe.fromMaybe msg maybe) variable1 variable2
132+ typeError variable1 variable2 $ Error.PostNote $
138− "Looks like you want something appendable, but the only Strings, Lists,\n\
133+ "Note: appendable types include only Strings, Lists, and Text."
139− \and Text can be appended with the (++) operator."
141 unifyComparable v (Var.Canonical home name) =
135 unifyComparable v (Var.Canonical home name) =
142 case home of
136 case home of
@@ -156,7 +150,8 @@ actuallyUnify variable1 variable2 = do
158 | length vs > 6 ->
152 | length vs > 6 ->
153+ comparableError $ Just $
159− comparableError $ Just "Cannot compare a tuple with more than 6 elements."
154+ "Furthermore, it cannot be a tuple with more than 6 elements."
160 | otherwise ->
155 | otherwise ->
161 do flexAndUnify varSuper
156 do flexAndUnify varSuper
162 cmpVars <- liftIO $ forM [1..length vs] $ \_ -> variable (Is Comparable)
157 cmpVars <- liftIO $ forM [1..length vs] $ \_ -> variable (Is Comparable)
@@ -166,15 +161,15 @@ actuallyUnify variable1 variable2 = do
166 do struct <- liftIO $ collectApps varFlex
161 do struct <- liftIO $ collectApps varFlex
167 case struct of
162 case struct of
168 List _ -> flexAndUnify varSuper
163 List _ -> flexAndUnify varSuper
169− _ -> appendableError Nothing
164+ _ -> appendableError
171 rigidError var =
166 rigidError var =
167+ let v = render (pretty Never var)
172− typeError (Just hint) variable1 variable2
169+ typeError variable1 variable2 $ Error.PreNote $
175− "Could not unify rigid type variable '" ++ render (pretty Never var) ++ "'.\n" ++
170+ "Could not unify rigid type variable '" ++ v ++ "'. The problem probably\n"
176− "The problem probably relates to the type variable being shared between a\n\
171+ ++ "relates to the type variable being shared between two type annotations.\n"
177− \top-level type annotation and a related let-bound type annotation."
172+ ++ "Try commenting out some type annotations and see what happens."
179 superUnify =
174 superUnify =
180 case (flex desc1, flex desc2, name desc1, name desc2) of
175 case (flex desc1, flex desc2, name desc1, name desc2) of
@@ -200,7 +195,7 @@ actuallyUnify variable1 variable2 = do
201 (Rigid, _, _, _) -> rigidError variable1
196 (Rigid, _, _, _) -> rigidError variable1
202 (_, Rigid, _, _) -> rigidError variable2
197 (_, Rigid, _, _) -> rigidError variable2
203− _ -> typeError Nothing variable1 variable2
198+ _ -> typeError variable1 variable2 Error.NoNote
205 case (structure desc1, structure desc2) of
200 case (structure desc1, structure desc2) of
206 (Nothing, Nothing) | flex desc1 == Flexible && flex desc1 == Flexible ->
201 (Nothing, Nothing) | flex desc1 == Flexible && flex desc1 == Flexible ->
@@ -244,7 +239,7 @@ actuallyUnify variable1 variable2 = do
244 (Record1 _ _, Record1 _ _) ->
239 (Record1 _ _, Record1 _ _) ->
245 recordUnify fresh variable1 variable2
240 recordUnify fresh variable1 variable2
247− _ -> typeError Nothing variable1 variable2
242+ _ -> typeError variable1 variable2 Error.NoNote
250-- RECORD UNIFICATION
245-- RECORD UNIFICATION
@@ -267,15 +262,14 @@ recordUnify fresh variable1 variable2 =
267 let uniqueFields2 = diffFields fields2 fields1
262 let uniqueFields2 = diffFields fields2 fields1
269 let addFieldMismatchError missingFields =
264 let addFieldMismatchError missingFields =
270− let msg = fieldMismatchError missingFields
272− typeError (Just msg) variable1 variable2
265+ typeError variable1 variable2 $ Error.PreNote $
266+ fieldMismatchError missingFields
274 case (ext1, ext2) of
268 case (ext1, ext2) of
275 (Empty _, Empty _) ->
269 (Empty _, Empty _) ->
276 case Map.null uniqueFields1 && Map.null uniqueFields2 of
270 case Map.null uniqueFields1 && Map.null uniqueFields2 of
277 True -> return ()
271 True -> return ()
278− False -> typeError Nothing variable1 variable2
272+ False -> typeError variable1 variable2 Error.NoNote
280 (Empty var1, Extension var2) ->
274 (Empty var1, Extension var2) ->
281 case (Map.null uniqueFields1, Map.null uniqueFields2) of
275 case (Map.null uniqueFields1, Map.null uniqueFields2) of