on master help sign in
Make type error messages more specific for lists
commit37a568714d68617bc9022117c71f43e1c113d116 authorEvan Czaplicki <info@elm-lang.org> dateThu 7 May 2015, 14:02 (11 years ago) parent60a112a
2 files changed+59−3
src/Reporting/Error/Type.hs+16 src/Type/Constrain/Expression.hs+43−3
src/Reporting/Error/Type.hs+16
@@ -30,6 +30,8 @@ data Hint
3030 | IfBranches
3131 | MultiIfBranch Int Region.Region
3232 | If
33+ | List
34+ | ListElement Int Region.Region
3335
3436
3537data Note
@@ -121,3 +123,17 @@ hintToString hint =
121123 , "All the branches of this if-expression are consistent, but the overall\n"
122124 ++ "type does not match how it is used elsewhere."
123125 )
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 =
7171 return $ CAnd [lowCon, highCon, list n === tipe]
7272
7373 E.ExplicitList exprs ->
74− exists $ \x ->
75− do constraints <- mapM (\e -> constrain env e x) exprs
76− return $ CAnd (list x === tipe : constraints)
74+ constrainList env region exprs tipe
7775
7876 E.Binop op leftExpr rightExpr ->
7977 exists $ \leftType ->
@@ -190,6 +188,48 @@ constrain env (A.A region expression) tipe =
190188 constrain env expr tipe
191189
192190
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+
193233-- CONSTRAIN IF EXPRESSIONS
194234
195235constrainIf