on master help sign in
Fix bugs when unifying rigid constraints

The new combineRigidSupers function makes sure that the rigid variable always wins and that the rigid variable is a subset of the flex variable. There was also a bug in unifyRigid where the rigid variable would not win! The flex one would win. This accounted for some fraction of the bugs as well. I also try to avoid allocating new rigid content in unifyRigid to maybe make things a bit faster. Fixes #1268 Fixes #1270 Fixes #1281 Fixes #1316 Fixes #1422 Fixes #1581

commit5fe9bb9602163927295a6b37a64fd47f982d502a authorEvan Czaplicki <evancz@users.noreply.github.com> dateThu 11 May 2017, 14:29 (9 years ago) parent669fa90
1 file changed+24−21
src/Type/Unify.hs+24−21
src/Type/Unify.hs+24−21
@@ -193,9 +193,10 @@ subUnify context var1 var2 =
193193actuallyUnify :: Context -> Unify ()
194194actuallyUnify context@(Context _ _ firstDesc _ secondDesc) =
195195 let
196+ firstContent = _content firstDesc
196197 secondContent = _content secondDesc
197198 in
198− case _content firstDesc of
199+ case firstContent of
199200 Error ->
200201 -- If there was an error, just pretend it is okay. This lets us avoid
201202 -- "cascading" errors where one problem manifests as multiple message.
@@ -208,7 +209,7 @@ actuallyUnify context@(Context _ _ firstDesc _ secondDesc) =
208209 unifySuper context super secondContent
209210
210211 Var Rigid maybeSuper maybeName ->
211− unifyRigid context maybeSuper maybeName secondContent
212+ unifyRigid context maybeSuper maybeName firstContent secondContent
212213
213214 Atom name ->
214215 unifyAtom context name secondContent
@@ -250,8 +251,8 @@ unifyFlex context otherContent =
250251-- UNIFY RIGID VARIABLES
251252
252253
253−unifyRigid :: Context -> Maybe Super -> Maybe Text -> Content -> Unify ()
254−unifyRigid context maybeSuper maybeName otherContent =
254+unifyRigid :: Context -> Maybe Super -> Maybe Text -> Content -> Content -> Unify ()
255+unifyRigid context maybeSuper maybeName content otherContent =
255256 case otherContent of
256257 Error ->
257258 return ()
@@ -259,18 +260,16 @@ unifyRigid context maybeSuper maybeName otherContent =
259260 Var Flex otherMaybeSuper _ ->
260261 case (maybeSuper, otherMaybeSuper) of
261262 (_, Nothing) ->
262− merge context (Var Rigid maybeSuper maybeName)
263+ merge context content
263264
264265 (Nothing, Just _) ->
265266 mismatch context (Just (badRigid maybeName))
266267
267268 (Just super, Just otherSuper) ->
268− case combineSupers super otherSuper of
269− Right newSuper | newSuper == otherSuper ->
270− merge context otherContent
271−
272− _ ->
273− mismatch context (Just (badRigid maybeName))
269+ if combineRigidSupers super otherSuper then
270+ merge context content
271+ else
272+ mismatch context (Just (badRigid maybeName))
274273
275274 Var Rigid _ otherMaybeName ->
276275 mismatch context $ Just $
@@ -306,19 +305,16 @@ unifySuper context super otherContent =
306305 mismatch context (Just (doubleBad (errorSuper super) (Error.Rigid maybeName)))
307306
308307 Var Rigid (Just otherSuper) maybeName ->
309− case combineSupers super otherSuper of
310− Right newSuper | newSuper == super ->
311− merge context otherContent
312−
313− _ ->
314− mismatch context $ Just $
315− doubleBad (errorSuper super) (Error.Rigid maybeName)
308+ if combineRigidSupers otherSuper super then
309+ merge context otherContent
310+ else
311+ mismatch context $ Just $ badRigid maybeName
316312
317313 Var Flex Nothing _ ->
318314 merge context (Var Flex (Just super) Nothing)
319315
320316 Var Flex (Just otherSuper) _ ->
321− case combineSupers super otherSuper of
317+ case combineFlexSupers super otherSuper of
322318 Left reason ->
323319 mismatch context (Just reason)
324320
@@ -332,8 +328,8 @@ unifySuper context super otherContent =
332328 return ()
333329
334330
335−combineSupers :: Super -> Super -> Either Error.Reason Super
336−combineSupers firstSuper secondSuper =
331+combineFlexSupers :: Super -> Super -> Either Error.Reason Super
332+combineFlexSupers firstSuper secondSuper =
337333 case (firstSuper, secondSuper) of
338334 (Number , Number ) -> Right Number
339335 (Comparable, Number ) -> Right Number
@@ -355,6 +351,13 @@ combineSupers firstSuper secondSuper =
355351 Left $ doubleBad (errorSuper firstSuper) (errorSuper secondSuper)
356352
357353
354+combineRigidSupers :: Super -> Super -> Bool
355+combineRigidSupers rigid flex =
356+ rigid == flex
357+ || (rigid == Number && flex == Comparable)
358+ || (rigid == CompAppend && (flex == Comparable || flex == Appendable))
359+
360+
358361isPrimitiveFrom :: [Text] -> Var.Canonical -> Bool
359362isPrimitiveFrom prims var =
360363 any (\p -> Var.isPrim p var) prims