on master help sign in
Avoid cascading errors
19f39f8Evan Czaplicki
src/Type/Type.hs+16−9
@@ -92,6 +92,7 @@ data Flex
92 | Flexible
92 | Flexible
93 | Constant
93 | Constant
94 | Is SuperType
94 | Is SuperType
95+ | Error
95 deriving (Eq)
96 deriving (Eq)
96
97
97data SuperType
98data SuperType
@@ -152,15 +153,21 @@ namedVar flex name = UF.fresh $ Descriptor
152
153
153
154
154variable :: Flex -> IO Variable
155variable :: Flex -> IO Variable
155−variable flex = UF.fresh $ Descriptor
156+variable flex =
157+ UF.fresh (descriptor flex)
158+
159+
160+descriptor :: Flex -> Descriptor
161+descriptor flex =
162+ Descriptor
156− { structure = Nothing
163+ { structure = Nothing
157− , rank = noRank
164+ , rank = noRank
158− , flex = flex
165+ , flex = flex
159− , name = Nothing
166+ , name = Nothing
160− , copy = Nothing
167+ , copy = Nothing
161− , mark = noMark
168+ , mark = noMark
162− , alias = Nothing
169+ , alias = Nothing
163− }
170+ }
164
171
165
172
166-- CONSTRAINT HELPERS
173-- CONSTRAINT HELPERS
src/Type/Unify.hs+26−14
@@ -53,6 +53,9 @@ typeError
53typeError leftType rightType note =
53typeError leftType rightType note =
54 do leftSrcType <- liftIO (toSrcType leftType)
54 do leftSrcType <- liftIO (toSrcType leftType)
55 rightSrcType <- liftIO (toSrcType rightType)
55 rightSrcType <- liftIO (toSrcType rightType)
56+ liftIO $ do
57+ UF.setDescriptor leftType (Type.descriptor Error)
58+ UF.setDescriptor rightType (Type.descriptor Error)
56 throwError (RawMismatch (leftSrcType, rightSrcType, note))
59 throwError (RawMismatch (leftSrcType, rightSrcType, note))
57
60
58
61
@@ -118,8 +121,11 @@ actuallyUnify variable1 variable2 = do
118
121
119 unifyNumber svar (Var.Canonical home name) =
122 unifyNumber svar (Var.Canonical home name) =
120 case home of
123 case home of
121− Var.BuiltIn | name `elem` ["Int","Float"] -> flexAndUnify svar
124+ Var.BuiltIn | name `elem` ["Int","Float"] ->
125+ flexAndUnify svar
126+
122− Var.Local | List.isPrefixOf "number" name -> flexAndUnify svar
127+ Var.Local | List.isPrefixOf "number" name ->
128+ flexAndUnify svar
123 _ ->
129 _ ->
124 typeError variable1 variable2 Nothing
130 typeError variable1 variable2 Nothing
125
131
@@ -134,9 +140,12 @@ actuallyUnify variable1 variable2 = do
134
140
135 unifyComparable v (Var.Canonical home name) =
141 unifyComparable v (Var.Canonical home name) =
136 case home of
142 case home of
137− Var.BuiltIn | name `elem` ["Int","Float","Char","String"] -> flexAndUnify v
143+ Var.BuiltIn | name `elem` ["Int","Float","Char","String"] ->
144+ flexAndUnify v
138− Var.Local | List.isPrefixOf "comparable" name -> flexAndUnify v
145+ Var.Local | List.isPrefixOf "comparable" name ->
146+ flexAndUnify v
147+ _ ->
139− _ -> comparableError Nothing
148+ comparableError Nothing
140
149
141 unifyComparableStructure varSuper varFlex =
150 unifyComparableStructure varSuper varFlex =
142 do struct <- liftIO $ collectApps varFlex
151 do struct <- liftIO $ collectApps varFlex
@@ -148,11 +157,11 @@ actuallyUnify variable1 variable2 = do
148 do flexAndUnify varSuper
157 do flexAndUnify varSuper
149 unifyHelp v =<< liftIO (variable $ Is Comparable)
158 unifyHelp v =<< liftIO (variable $ Is Comparable)
150
159
151− Tuple vs
160+ Tuple vs ->
152− | length vs > 6 ->
161+ if length vs > 6 then
153 comparableError $ Just $
162 comparableError $ Just $
154 "Furthermore, it cannot be a tuple with more than 6 elements."
163 "Furthermore, it cannot be a tuple with more than 6 elements."
155− | otherwise ->
164+ else
156 do flexAndUnify varSuper
165 do flexAndUnify varSuper
157 cmpVars <- liftIO $ forM [1..length vs] $ \_ -> variable (Is Comparable)
166 cmpVars <- liftIO $ forM [1..length vs] $ \_ -> variable (Is Comparable)
158 zipWithM_ unifyHelp vs cmpVars
167 zipWithM_ unifyHelp vs cmpVars
@@ -194,14 +203,17 @@ actuallyUnify variable1 variable2 = do
194 _ -> typeError variable1 variable2 Nothing
203 _ -> typeError variable1 variable2 Nothing
195
204
196 case (structure desc1, structure desc2) of
205 case (structure desc1, structure desc2) of
206+ (Nothing, Nothing)
197− (Nothing, Nothing) | flex desc1 == Flexible && flex desc1 == Flexible ->
207+ | flex desc1 == Flexible && flex desc1 == Flexible ->
198− merge
208+ merge
199
209
210+ (Nothing, _)
200− (Nothing, _) | flex desc1 == Flexible ->
211+ | flex desc1 == Flexible -> merge2
201− merge2
212+ | flex desc1 == Error -> return ()
202
213
214+ (_, Nothing)
203− (_, Nothing) | flex desc2 == Flexible ->
215+ | flex desc2 == Flexible -> merge1
204− merge1
216+ | flex desc2 == Error -> return ()
205
217
206 (Just (Var1 v), _) ->
218 (Just (Var1 v), _) ->
207 unifyHelp v variable2
219 unifyHelp v variable2