on master help sign in
Improve type error messages for case-expressions
0769e58Evan Czaplicki
src/Reporting/Error/Type.hs+8−1
@@ -26,6 +26,7 @@ data Hint
26 = None
26 = None
27 | Custom String
27 | Custom String
28 | CaseBranch Int Region.Region
28 | CaseBranch Int Region.Region
29+ | Case
29 | IfBranches
30 | IfBranches
30 | MultiIfBranch Int Region.Region
31 | MultiIfBranch Int Region.Region
31 | If
32 | If
@@ -93,6 +94,12 @@ hintToString hint =
93 ++ "branch returns the same type of value."
94 ++ "branch returns the same type of value."
94 )
95 )
95
96
97+ Case ->
98+ ( Nothing
99+ , "All the branches of this case-expression are consistent, but the overall\n"
100+ ++ "type does not match how it is used elsewhere."
101+ )
102+
96 IfBranches ->
103 IfBranches ->
97 ( Nothing
104 ( Nothing
98 , "The branches of this if-expression return different types of values.\n"
105 , "The branches of this if-expression return different types of values.\n"
@@ -108,6 +115,6 @@ hintToString hint =
108
115
109 If ->
116 If ->
110 ( Nothing
117 ( Nothing
111− , "All the branches of this if-expression are consistent, but the overall return\n"
118+ , "All the branches of this if-expression are consistent, but the overall\n"
112 ++ "type does not match how it is used elsewhere."
119 ++ "type does not match how it is used elsewhere."
113 )
120 )
src/Type/Constrain/Expression.hs+19−11
@@ -254,28 +254,36 @@ constrainCase env region expr branches tipe =
254
254
255 exprCon <- constrain env expr (varN exprVar)
255 exprCon <- constrain env expr (varN exprVar)
256
256
257− (branchVars, regions, branchExprCons) <-
257+ (branchInfo, branchExprCons) <-
258− unzip3 <$> mapM (branch (varN exprVar)) branches
258+ unzip <$> mapM (branch (varN exprVar)) branches
259−
260− let branchCons =
261− zipWith3 branchEqual [1..] branchVars regions
262
259
263 return $
260 return $
264− ex (exprVar:branchVars)
261+ ex (exprVar : map fst branchInfo)
265− (CAnd (exprCon : branchExprCons ++ branchCons))
262+ (CAnd (exprCon : branchExprCons ++ branchCons 2 branchInfo))
266 where
263 where
267 branch patternType (pattern, branchExpr@(A.A branchRegion _)) =
264 branch patternType (pattern, branchExpr@(A.A branchRegion _)) =
268 do branchVar <- variable Flexible
265 do branchVar <- variable Flexible
269 fragment <- Pattern.constrain env pattern patternType
266 fragment <- Pattern.constrain env pattern patternType
270 branchCon <- constrain env branchExpr (varN branchVar)
267 branchCon <- constrain env branchExpr (varN branchVar)
271 return
268 return
272− ( branchVar
273− , branchRegion
269+ ( (branchVar, branchRegion)
274 , CLet [Fragment.toScheme fragment] branchCon
270 , CLet [Fragment.toScheme fragment] branchCon
275 )
271 )
276
272
277− branchEqual n var branchRegion =
273+ branchCons n branchInfo =
274+ case branchInfo of
275+ [] ->
276+ []
277+
278+ (var,_) : [] ->
278− CEqual (Error.CaseBranch n branchRegion) region tipe (varN var)
279+ [ CEqual Error.Case region tipe (varN var) ]
280+
281+ (var,_) : (var',region') : rest ->
282+ let
283+ hint = Error.CaseBranch n region'
284+ con = CEqual hint region (varN var) (varN var')
285+ in
286+ con : branchCons (n+1) ((var', region') : rest)
279
287
280
288
281-- EXPAND PATTERNS
289-- EXPAND PATTERNS