on master help sign in
Make type error messages more specific for lists
37a5687Evan Czaplicki
src/Reporting/Error/Type.hs+16
@@ -30,6 +30,8 @@ data Hint
30 | IfBranches
30 | IfBranches
31 | MultiIfBranch Int Region.Region
31 | MultiIfBranch Int Region.Region
32 | If
32 | If
33+ | List
34+ | ListElement Int Region.Region
33
35
34
36
35data Note
37data Note
@@ -121,3 +123,17 @@ hintToString hint =
121 , "All the branches of this if-expression are consistent, but the overall\n"
123 , "All the branches of this if-expression are consistent, but the overall\n"
122 ++ "type does not match how it is used elsewhere."
124 ++ "type does not match how it is used elsewhere."
123 )
125 )
126+
127+ ListElement elementNumber region ->
128+ ( Just region
129+ , "Not all elements of this list are the same type of value.\n\n"
130+ ++ "I noticed the mismatch in element #" ++ show elementNumber ++ ", but go through and make sure every\n"
131+ ++ "element is the same type of value."
132+ )
133+
134+ List ->
135+ ( Nothing
136+ , "All the elements in this list are the same type, but the overall\n"
137+ ++ "type does not match how it is used elsewhere."
138+ )
139+
src/Type/Constrain/Expression.hs+43−3
@@ -71,9 +71,7 @@ constrain env (A.A region expression) tipe =
71 return $ CAnd [lowCon, highCon, list n === tipe]
71 return $ CAnd [lowCon, highCon, list n === tipe]
72
72
73 E.ExplicitList exprs ->
73 E.ExplicitList exprs ->
74− exists $ \x ->
74+ constrainList env region exprs tipe
75− do constraints <- mapM (\e -> constrain env e x) exprs
76− return $ CAnd (list x === tipe : constraints)
77
75
78 E.Binop op leftExpr rightExpr ->
76 E.Binop op leftExpr rightExpr ->
79 exists $ \leftType ->
77 exists $ \leftType ->
@@ -190,6 +188,48 @@ constrain env (A.A region expression) tipe =
190 constrain env expr tipe
188 constrain env expr tipe
191
189
192
190
191+-- CONSTRAIN LISTS
192+
193+constrainList
194+ :: Env.Environment
195+ -> R.Region
196+ -> [Canonical.Expr]
197+ -> Type
198+ -> IO TypeConstraint
199+constrainList env region exprs tipe =
200+ do (exprInfo, exprCons) <-
201+ unzip <$> mapM elementConstraint exprs
202+
203+ let pairwiseCons = pairwiseConstraints 2 exprInfo
204+
205+ return $
206+ ex (map fst exprInfo)
207+ (CAnd (exprCons ++ pairwiseCons))
208+ where
209+ list t =
210+ Env.get env Env.types "List" <| t
211+
212+ elementConstraint expr@(A.A region' _) =
213+ do var <- variable Flexible
214+ con <- constrain env expr (varN var)
215+ return ( (var, region'), con )
216+
217+ pairwiseConstraints n exprInfo =
218+ case exprInfo of
219+ [] ->
220+ []
221+
222+ (var,_) : [] ->
223+ [ CEqual Error.List region tipe (list (varN var)) ]
224+
225+ (var,_) : (var',region') : rest ->
226+ let
227+ hint = Error.ListElement n region'
228+ con = CEqual hint region (varN var) (varN var')
229+ in
230+ con : pairwiseConstraints (n+1) ((var', region') : rest)
231+
232+
193-- CONSTRAIN IF EXPRESSIONS
233-- CONSTRAIN IF EXPRESSIONS
194
234
195constrainIf
235constrainIf