@@ -34,6 +34,7 @@ import PureScript.TypeChecker.Kinds
34import PureScript.TypeChecker.Synonyms
34import PureScript.TypeChecker.Synonyms
35import PureScript.CodeGen.Pretty.Types
35import PureScript.CodeGen.Pretty.Types
36import PureScript.CodeGen.Pretty.Kinds
36import PureScript.CodeGen.Pretty.Kinds
37+import PureScript.CodeGen.Pretty.Values
38import Control.Monad.State
39import Control.Monad.State
39import Control.Monad.Error
40import Control.Monad.Error
@@ -44,9 +45,19 @@ import qualified Control.Category as C
45import qualified Data.Map as M
46import qualified Data.Map as M
48+data TypeConstraintOrigin
50+ | BinderOrigin Binder
51+ | AssignmentTargetOrigin AssignmentTarget deriving (Show, D.Data, D.Typeable)
53+prettyPrintOrigin :: TypeConstraintOrigin -> String
54+prettyPrintOrigin (ValueOrigin val) = prettyPrintValue val
55+prettyPrintOrigin (BinderOrigin binder) = prettyPrintBinder binder
56+prettyPrintOrigin (AssignmentTargetOrigin assign) = prettyPrintAssignmentTarget assign
47data TypeConstraint
58data TypeConstraint
48− = TypeConstraint Int Type
59+ = TypeConstraint Int Type TypeConstraintOrigin
49− | RowConstraint Int Row deriving (Show, D.Data, D.Typeable)
60+ | RowConstraint Int Row TypeConstraintOrigin deriving (Show, D.Data, D.Typeable)
51newtype TypeSolution = TypeSolution { runTypeSolution :: (Int -> Type, Int -> Row) }
62newtype TypeSolution = TypeSolution { runTypeSolution :: (Int -> Type, Int -> Row) }
@@ -59,7 +70,7 @@ typeOf name val = do
59 Abs _ _ -> do
70 Abs _ _ -> do
60 me <- fresh
71 me <- fresh
61 (cs, n) <- typeConstraints (M.singleton name me) val
72 (cs, n) <- typeConstraints (M.singleton name me) val
62− return (TypeConstraint me (TUnknown n) : cs, n)
73+ return (TypeConstraint me (TUnknown n) (ValueOrigin val): cs, n)
63 _ -> typeConstraints M.empty val
74 _ -> typeConstraints M.empty val
64 desugared <- replaceAllTypeSynonyms cs
75 desugared <- replaceAllTypeSynonyms cs
65 solution <- solveTypeConstraints desugared emptyTypeSolution
76 solution <- solveTypeConstraints desugared emptyTypeSolution
@@ -72,15 +83,15 @@ allUnknownsBecameQuantified cs solution ty = do
73 typesMentioned = findUnknownTypes ty
84 typesMentioned = findUnknownTypes ty
74 unknownTypes = nub $ flip concatMap cs $ \c -> case c of
85 unknownTypes = nub $ flip concatMap cs $ \c -> case c of
75− TypeConstraint u t -> u : findUnknownTypes t
86+ TypeConstraint u t _ -> u : findUnknownTypes t
76− RowConstraint _ r -> findUnknownTypes r
87+ RowConstraint _ r _ -> findUnknownTypes r
77 unsolvedTypes = filter (\n -> TUnknown n == fst (runTypeSolution solution) n) unknownTypes
88 unsolvedTypes = filter (\n -> TUnknown n == fst (runTypeSolution solution) n) unknownTypes
78 guardWith "Unsolved type variable" $ null $ unsolvedTypes \\ typesMentioned
89 guardWith "Unsolved type variable" $ null $ unsolvedTypes \\ typesMentioned
80 rowsMentioned = findUnknownRows ty
91 rowsMentioned = findUnknownRows ty
81 unknownRows = nub $ flip concatMap cs $ \c -> case c of
92 unknownRows = nub $ flip concatMap cs $ \c -> case c of
82− TypeConstraint _ t -> findUnknownRows t
93+ TypeConstraint _ t _ -> findUnknownRows t
83− RowConstraint u r -> u : findUnknownRows r
94+ RowConstraint u r _ -> u : findUnknownRows r
84 unsolvedRows = filter (\n -> RUnknown n == snd (runTypeSolution solution) n) unknownRows
95 unsolvedRows = filter (\n -> RUnknown n == snd (runTypeSolution solution) n) unknownRows
85 guardWith "Unsolved row variable" $ null $ unsolvedRows \\ rowsMentioned
96 guardWith "Unsolved row variable" $ null $ unsolvedRows \\ rowsMentioned
@@ -206,61 +217,61 @@ occursCheck u = everything (||) $ flip extQ g $ mkQ False f
206 g _ = False
217 g _ = False
208typeConstraints :: M.Map Ident Int -> Value -> Check ([TypeConstraint], Int)
219typeConstraints :: M.Map Ident Int -> Value -> Check ([TypeConstraint], Int)
209−typeConstraints _ (NumericLiteral _) = do
220+typeConstraints _ v@(NumericLiteral _) = do
210 me <- fresh
221 me <- fresh
211− return ([TypeConstraint me Number], me)
222+ return ([TypeConstraint me Number (ValueOrigin v)], me)
212−typeConstraints _ (StringLiteral _) = do
223+typeConstraints _ v@(StringLiteral _) = do
213 me <- fresh
224 me <- fresh
214− return ([TypeConstraint me String], me)
225+ return ([TypeConstraint me String (ValueOrigin v)], me)
215−typeConstraints _ (BooleanLiteral _) = do
226+typeConstraints _ v@(BooleanLiteral _) = do
216 me <- fresh
227 me <- fresh
217− return ([TypeConstraint me Boolean], me)
228+ return ([TypeConstraint me Boolean (ValueOrigin v)], me)
218−typeConstraints m (ArrayLiteral vals) = do
229+typeConstraints m v@(ArrayLiteral vals) = do
219 all <- mapM (typeConstraints m) vals
230 all <- mapM (typeConstraints m) vals
220 let (cs, ns) = (concat . map fst &&& map snd) all
231 let (cs, ns) = (concat . map fst &&& map snd) all
221 me <- fresh
232 me <- fresh
222− return (cs ++ map (TypeConstraint me . Array . TUnknown) ns, me)
233+ return (cs ++ zipWith (\n el -> TypeConstraint me (Array $ TUnknown n) (ValueOrigin el)) ns vals, me)
223−typeConstraints m (Unary op val) = do
234+typeConstraints m u@(Unary op val) = do
224 (cs, n1) <- typeConstraints m val
235 (cs, n1) <- typeConstraints m val
225 me <- fresh
236 me <- fresh
226− return (cs ++ unaryOperatorConstraints op n1 me, me)
237+ return (cs ++ unaryOperatorConstraints u op n1 me, me)
227−typeConstraints m (Binary op left right) = do
238+typeConstraints m b@(Binary op left right) = do
228 (cs1, n1) <- typeConstraints m left
239 (cs1, n1) <- typeConstraints m left
229 (cs2, n2) <- typeConstraints m right
240 (cs2, n2) <- typeConstraints m right
230 me <- fresh
241 me <- fresh
231− return (cs1 ++ cs2 ++ binaryOperatorConstraints op n1 n2 me, me)
242+ return (cs1 ++ cs2 ++ binaryOperatorConstraints b op n1 n2 me, me)
232−typeConstraints m (ObjectLiteral ps) = do
243+typeConstraints m v@(ObjectLiteral ps) = do
233 all <- mapM (typeConstraints m . snd) ps
244 all <- mapM (typeConstraints m . snd) ps
234 let (cs, ns) = (concat . map fst &&& map snd) all
245 let (cs, ns) = (concat . map fst &&& map snd) all
235 me <- fresh
246 me <- fresh
236 let tys = zipWith (\(name, _) u -> (name, TUnknown u)) ps ns
247 let tys = zipWith (\(name, _) u -> (name, TUnknown u)) ps ns
237− return ((TypeConstraint me (Object (typesToRow tys))) : cs, me)
248+ return ((TypeConstraint me (Object (typesToRow tys)) (ValueOrigin v)) : cs, me)
239 typesToRow [] = REmpty
250 typesToRow [] = REmpty
240 typesToRow ((name, ty):tys) = RCons name ty (typesToRow tys)
251 typesToRow ((name, ty):tys) = RCons name ty (typesToRow tys)
241−typeConstraints m (Indexer index val) = do
252+typeConstraints m v@(Indexer index val) = do
242 (cs1, n1) <- typeConstraints m index
253 (cs1, n1) <- typeConstraints m index
243 (cs2, n2) <- typeConstraints m val
254 (cs2, n2) <- typeConstraints m val
244 me <- fresh
255 me <- fresh
245− return ((TypeConstraint n1 Number) : (TypeConstraint n2 (Array (TUnknown me))) : cs1 ++ cs2, me)
256+ return ((TypeConstraint n1 Number (ValueOrigin index)) : (TypeConstraint n2 (Array (TUnknown me)) (ValueOrigin v)) : cs1 ++ cs2, me)
246−typeConstraints m (Accessor prop val) = do
257+typeConstraints m v@(Accessor prop val) = do
247 (cs, n1) <- typeConstraints m val
258 (cs, n1) <- typeConstraints m val
248 me <- fresh
259 me <- fresh
249 rest <- fresh
260 rest <- fresh
250− return ((TypeConstraint n1 (Object (RCons prop (TUnknown me) (RUnknown rest)))) : cs, me)
261+ return ((TypeConstraint n1 (Object (RCons prop (TUnknown me) (RUnknown rest))) (ValueOrigin v)) : cs, me)
251−typeConstraints m (Abs args ret) = do
262+typeConstraints m v@(Abs args ret) = do
252 ns <- replicateM (length args) fresh
263 ns <- replicateM (length args) fresh
253 let m' = m `M.union` M.fromList (zipWith (,) args ns)
264 let m' = m `M.union` M.fromList (zipWith (,) args ns)
254 (cs, n') <- typeConstraints m' ret
265 (cs, n') <- typeConstraints m' ret
255 me <- fresh
266 me <- fresh
256− return ((TypeConstraint me (Function (map TUnknown ns) (TUnknown n'))) : cs, me)
267+ return ((TypeConstraint me (Function (map TUnknown ns) (TUnknown n')) (ValueOrigin v)) : cs, me)
257−typeConstraints m (App f xs) = do
268+typeConstraints m v@(App f xs) = do
258 (cs1, n1) <- typeConstraints m f
269 (cs1, n1) <- typeConstraints m f
259 all <- mapM (typeConstraints m) xs
270 all <- mapM (typeConstraints m) xs
260 let (cs2, ns) = (concat . map fst &&& map snd) all
271 let (cs2, ns) = (concat . map fst &&& map snd) all
261 me <- fresh
272 me <- fresh
262− return ((TypeConstraint n1 (Function (map TUnknown ns) (TUnknown me))) : cs1 ++ cs2, me)
273+ return ((TypeConstraint n1 (Function (map TUnknown ns) (TUnknown me)) (ValueOrigin v)) : cs1 ++ cs2, me)
263−typeConstraints m (Var var) =
274+typeConstraints m v@(Var var) =
264 case M.lookup var m of
275 case M.lookup var m of
265 Nothing -> do
276 Nothing -> do
266 env <- getEnv
277 env <- getEnv
@@ -269,134 +280,134 @@ typeConstraints m (Var var) =
269 Just (PolyType idents ty, _) -> do
280 Just (PolyType idents ty, _) -> do
270 me <- fresh
281 me <- fresh
271 replaced <- replaceVarsWithUnknowns idents ty
282 replaced <- replaceVarsWithUnknowns idents ty
272− return ([TypeConstraint me replaced], me)
283+ return ([TypeConstraint me replaced (ValueOrigin v)], me)
273 Just u -> do
284 Just u -> do
274 me <- fresh
285 me <- fresh
275− return ([TypeConstraint u (TUnknown me)], me)
286+ return ([TypeConstraint u (TUnknown me) (ValueOrigin v)], me)
276typeConstraints m (Block ss) = do
287typeConstraints m (Block ss) = do
277 ret <- fresh
288 ret <- fresh
278 (cs, allCodePathsReturn, _) <- typeConstraintsForBlock m M.empty ret ss
289 (cs, allCodePathsReturn, _) <- typeConstraintsForBlock m M.empty ret ss
279 guardWith "Block is missing a return statement" allCodePathsReturn
290 guardWith "Block is missing a return statement" allCodePathsReturn
280 return (cs, ret)
291 return (cs, ret)
281−typeConstraints m (Constructor c) = do
292+typeConstraints m v@(Constructor c) = do
282 env <- getEnv
293 env <- getEnv
283 case M.lookup c (dataConstructors env) of
294 case M.lookup c (dataConstructors env) of
284 Nothing -> throwError $ "Constructor " ++ c ++ " is undefined"
295 Nothing -> throwError $ "Constructor " ++ c ++ " is undefined"
285 Just (PolyType idents ty) -> do
296 Just (PolyType idents ty) -> do
286 me <- fresh
297 me <- fresh
287 replaced <- replaceVarsWithUnknowns idents ty
298 replaced <- replaceVarsWithUnknowns idents ty
288− return ([TypeConstraint me replaced], me)
299+ return ([TypeConstraint me replaced (ValueOrigin v)], me)
289typeConstraints m (Case val binders) = do
300typeConstraints m (Case val binders) = do
290 (cs1, n1) <- typeConstraints m val
301 (cs1, n1) <- typeConstraints m val
291 ret <- fresh
302 ret <- fresh
292 cs2 <- typeConstraintsForBinders m n1 ret binders
303 cs2 <- typeConstraintsForBinders m n1 ret binders
293 return (cs1 ++ cs2, ret)
304 return (cs1 ++ cs2, ret)
294−typeConstraints m (IfThenElse cond th el) = do
305+typeConstraints m v@(IfThenElse cond th el) = do
295 (cs1, n1) <- typeConstraints m cond
306 (cs1, n1) <- typeConstraints m cond
296 (cs2, n2) <- typeConstraints m th
307 (cs2, n2) <- typeConstraints m th
297 (cs3, n3) <- typeConstraints m el
308 (cs3, n3) <- typeConstraints m el
298− return (TypeConstraint n1 Boolean : TypeConstraint n2 (TUnknown n3) : cs1 ++ cs2 ++ cs3, n2)
309+ return (TypeConstraint n1 Boolean (ValueOrigin cond) : TypeConstraint n2 (TUnknown n3) (ValueOrigin v) : cs1 ++ cs2 ++ cs3, n2)
299−typeConstraints m (TypedValue val poly@(PolyType idents ty)) = do
310+typeConstraints m v@(TypedValue val poly@(PolyType idents ty)) = do
300 kind <- kindOf poly
311 kind <- kindOf poly
301 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
312 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
302 (cs, n1) <- typeConstraints m val
313 (cs, n1) <- typeConstraints m val
303− return (TypeConstraint n1 ty : cs, n1)
314+ return (TypeConstraint n1 ty (ValueOrigin v) : cs, n1)
305−unaryOperatorConstraints :: UnaryOperator -> Int -> Int -> [TypeConstraint]
316+unaryOperatorConstraints :: Value -> UnaryOperator -> Int -> Int -> [TypeConstraint]
306−unaryOperatorConstraints Negate val result = [TypeConstraint val Number, TypeConstraint result Number]
317+unaryOperatorConstraints v Negate val result = [TypeConstraint val Number (ValueOrigin v), TypeConstraint result Number (ValueOrigin v)]
307−unaryOperatorConstraints Not val result = [TypeConstraint val Boolean, TypeConstraint result Boolean]
318+unaryOperatorConstraints v Not val result = [TypeConstraint val Boolean (ValueOrigin v), TypeConstraint result Boolean (ValueOrigin v)]
308−unaryOperatorConstraints BitwiseNot val result = [TypeConstraint val Number, TypeConstraint result Number]
319+unaryOperatorConstraints v BitwiseNot val result = [TypeConstraint val Number (ValueOrigin v), TypeConstraint result Number (ValueOrigin v)]
310−binaryOperatorConstraints :: BinaryOperator -> Int -> Int -> Int -> [TypeConstraint]
321+binaryOperatorConstraints :: Value -> BinaryOperator -> Int -> Int -> Int -> [TypeConstraint]
311−binaryOperatorConstraints Add = symBinOpConstraints Number
322+binaryOperatorConstraints v Add = symBinOpConstraints v Number
312−binaryOperatorConstraints Subtract = symBinOpConstraints Number
323+binaryOperatorConstraints v Subtract = symBinOpConstraints v Number
313−binaryOperatorConstraints Multiply = symBinOpConstraints Number
324+binaryOperatorConstraints v Multiply = symBinOpConstraints v Number
314−binaryOperatorConstraints Divide = symBinOpConstraints Number
325+binaryOperatorConstraints v Divide = symBinOpConstraints v Number
315−binaryOperatorConstraints Modulus = symBinOpConstraints Number
326+binaryOperatorConstraints v Modulus = symBinOpConstraints v Number
316−binaryOperatorConstraints LessThan = asymBinOpConstraints Number Boolean
327+binaryOperatorConstraints v LessThan = asymBinOpConstraints v Number Boolean
317−binaryOperatorConstraints LessThanOrEqualTo = asymBinOpConstraints Number Boolean
328+binaryOperatorConstraints v LessThanOrEqualTo = asymBinOpConstraints v Number Boolean
318−binaryOperatorConstraints GreaterThan = asymBinOpConstraints Number Boolean
329+binaryOperatorConstraints v GreaterThan = asymBinOpConstraints v Number Boolean
319−binaryOperatorConstraints GreaterThanOrEqualTo = asymBinOpConstraints Number Boolean
330+binaryOperatorConstraints v GreaterThanOrEqualTo = asymBinOpConstraints v Number Boolean
320−binaryOperatorConstraints BitwiseAnd = symBinOpConstraints Number
331+binaryOperatorConstraints v BitwiseAnd = symBinOpConstraints v Number
321−binaryOperatorConstraints BitwiseOr = symBinOpConstraints Number
332+binaryOperatorConstraints v BitwiseOr = symBinOpConstraints v Number
322−binaryOperatorConstraints BitwiseXor = symBinOpConstraints Number
333+binaryOperatorConstraints v BitwiseXor = symBinOpConstraints v Number
323−binaryOperatorConstraints ShiftLeft = symBinOpConstraints Number
334+binaryOperatorConstraints v ShiftLeft = symBinOpConstraints v Number
324−binaryOperatorConstraints ShiftRight = symBinOpConstraints Number
335+binaryOperatorConstraints v ShiftRight = symBinOpConstraints v Number
325−binaryOperatorConstraints ZeroFillShiftRight = symBinOpConstraints Number
336+binaryOperatorConstraints v ZeroFillShiftRight = symBinOpConstraints v Number
326−binaryOperatorConstraints EqualTo = equalityBinOpConstraints
337+binaryOperatorConstraints v EqualTo = equalityBinOpConstraints v
327−binaryOperatorConstraints NotEqualTo = equalityBinOpConstraints
338+binaryOperatorConstraints v NotEqualTo = equalityBinOpConstraints v
328−binaryOperatorConstraints And = symBinOpConstraints Boolean
339+binaryOperatorConstraints v And = symBinOpConstraints v Boolean
329−binaryOperatorConstraints Or = symBinOpConstraints Boolean
340+binaryOperatorConstraints v Or = symBinOpConstraints v Boolean
330−binaryOperatorConstraints Concat = symBinOpConstraints String
341+binaryOperatorConstraints v Concat = symBinOpConstraints v String
332−equalityBinOpConstraints :: Int -> Int -> Int -> [TypeConstraint]
343+equalityBinOpConstraints :: Value -> Int -> Int -> Int -> [TypeConstraint]
333−equalityBinOpConstraints left right result = [TypeConstraint left (TUnknown right), TypeConstraint result Boolean]
344+equalityBinOpConstraints v left right result = [TypeConstraint left (TUnknown right) (ValueOrigin v), TypeConstraint result Boolean (ValueOrigin v)]
335−symBinOpConstraints :: Type -> Int -> Int -> Int -> [TypeConstraint]
346+symBinOpConstraints :: Value -> Type -> Int -> Int -> Int -> [TypeConstraint]
336−symBinOpConstraints ty left right result = asymBinOpConstraints ty ty left right result
347+symBinOpConstraints v ty left right result = asymBinOpConstraints v ty ty left right result
338−asymBinOpConstraints :: Type -> Type -> Int -> Int -> Int -> [TypeConstraint]
349+asymBinOpConstraints :: Value -> Type -> Type -> Int -> Int -> Int -> [TypeConstraint]
339−asymBinOpConstraints ty res left right result = [TypeConstraint left ty, TypeConstraint right ty, TypeConstraint result res]
350+asymBinOpConstraints v ty res left right result = [TypeConstraint left ty (ValueOrigin v), TypeConstraint right ty (ValueOrigin v), TypeConstraint result res (ValueOrigin v)]
341typeConstraintsForBinder :: Int -> Binder -> Check ([TypeConstraint], M.Map Ident Int)
352typeConstraintsForBinder :: Int -> Binder -> Check ([TypeConstraint], M.Map Ident Int)
342typeConstraintsForBinder _ NullBinder = return ([], M.empty)
353typeConstraintsForBinder _ NullBinder = return ([], M.empty)
343−typeConstraintsForBinder val (StringBinder _) = constantBinder val String
354+typeConstraintsForBinder val b@(StringBinder _) = constantBinder b val String
344−typeConstraintsForBinder val (NumberBinder _) = constantBinder val Number
355+typeConstraintsForBinder val b@(NumberBinder _) = constantBinder b val Number
345−typeConstraintsForBinder val (BooleanBinder _) = constantBinder val Boolean
356+typeConstraintsForBinder val b@(BooleanBinder _) = constantBinder b val Boolean
346−typeConstraintsForBinder val (VarBinder name) = do
357+typeConstraintsForBinder val b@(VarBinder name) = do
347 me <- fresh
358 me <- fresh
348− return ([TypeConstraint me (TUnknown val)], M.singleton name me)
359+ return ([TypeConstraint me (TUnknown val) (BinderOrigin b)], M.singleton name me)
349−typeConstraintsForBinder val (NullaryBinder ctor) = do
360+typeConstraintsForBinder val b@(NullaryBinder ctor) = do
350 env <- getEnv
361 env <- getEnv
351 case M.lookup ctor (dataConstructors env) of
362 case M.lookup ctor (dataConstructors env) of
352 Just (PolyType args ret) -> do
363 Just (PolyType args ret) -> do
353 ret' <- replaceVarsWithUnknowns args ret
364 ret' <- replaceVarsWithUnknowns args ret
354− return ([TypeConstraint val ret'], M.empty)
365+ return ([TypeConstraint val ret' (BinderOrigin b)], M.empty)
355 _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
366 _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
356−typeConstraintsForBinder val (UnaryBinder ctor binder) = do
367+typeConstraintsForBinder val b@(UnaryBinder ctor binder) = do
357 env <- getEnv
368 env <- getEnv
358 case M.lookup ctor (dataConstructors env) of
369 case M.lookup ctor (dataConstructors env) of
359 Just (PolyType idents f@(Function [_] _)) -> do
370 Just (PolyType idents f@(Function [_] _)) -> do
360 obj <- fresh
371 obj <- fresh
361 (Function [ty] ret) <- replaceVarsWithUnknowns idents f
372 (Function [ty] ret) <- replaceVarsWithUnknowns idents f
362 (cs, m1) <- typeConstraintsForBinder obj binder
373 (cs, m1) <- typeConstraintsForBinder obj binder
363− return ((TypeConstraint val ret) : (TypeConstraint obj ty) : cs, m1)
374+ return ((TypeConstraint val ret (BinderOrigin b)) : (TypeConstraint obj ty (BinderOrigin b)) : cs, m1)
364 Just _ -> throwError $ ctor ++ " is not a unary constructor"
375 Just _ -> throwError $ ctor ++ " is not a unary constructor"
365 _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
376 _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
366−typeConstraintsForBinder val (ObjectBinder props) = do
377+typeConstraintsForBinder val b@(ObjectBinder props) = do
367 row <- fresh
378 row <- fresh
368 rest <- fresh
379 rest <- fresh
369 (cs, m1) <- typeConstraintsForProperties row (RUnknown rest) props
380 (cs, m1) <- typeConstraintsForProperties row (RUnknown rest) props
370− return ((TypeConstraint val (Object (RUnknown row))) : cs, m1)
381+ return ((TypeConstraint val (Object (RUnknown row)) (BinderOrigin b)) : cs, m1)
372 typeConstraintsForProperties :: Int -> Row -> [(String, Binder)] -> Check ([TypeConstraint], M.Map Ident Int)
383 typeConstraintsForProperties :: Int -> Row -> [(String, Binder)] -> Check ([TypeConstraint], M.Map Ident Int)
373− typeConstraintsForProperties nrow row [] = return ([RowConstraint nrow row], M.empty)
384+ typeConstraintsForProperties nrow row [] = return ([RowConstraint nrow row (BinderOrigin b)], M.empty)
374 typeConstraintsForProperties nrow row ((name, binder):binders) = do
385 typeConstraintsForProperties nrow row ((name, binder):binders) = do
375 propTy <- fresh
386 propTy <- fresh
376 (cs1, m1) <- typeConstraintsForBinder propTy binder
387 (cs1, m1) <- typeConstraintsForBinder propTy binder
377 (cs2, m2) <- typeConstraintsForProperties nrow (RCons name (TUnknown propTy) row) binders
388 (cs2, m2) <- typeConstraintsForProperties nrow (RCons name (TUnknown propTy) row) binders
378 return (cs1 ++ cs2, M.union m1 m2)
389 return (cs1 ++ cs2, M.union m1 m2)
379−typeConstraintsForBinder val (ArrayBinder binders rest) = do
390+typeConstraintsForBinder val b@(ArrayBinder binders rest) = do
380 el <- fresh
391 el <- fresh
381 all <- mapM (typeConstraintsForBinder el) binders
392 all <- mapM (typeConstraintsForBinder el) binders
382 let (cs1, m1) = (concat . map fst &&& M.unions . map snd) all
393 let (cs1, m1) = (concat . map fst &&& M.unions . map snd) all
383− let arrayConstraint = TypeConstraint val (Array (TUnknown el))
394+ let arrayConstraint = TypeConstraint val (Array (TUnknown el)) (BinderOrigin b)
384 case rest of
395 case rest of
385 Nothing -> return (arrayConstraint : cs1, m1)
396 Nothing -> return (arrayConstraint : cs1, m1)
386 Just binder -> do
397 Just binder -> do
387 (cs2, m2) <- typeConstraintsForBinder val binder
398 (cs2, m2) <- typeConstraintsForBinder val binder
388 return (arrayConstraint : cs1 ++ cs2, M.union m1 m2)
399 return (arrayConstraint : cs1 ++ cs2, M.union m1 m2)
389−typeConstraintsForBinder val (NamedBinder name binder) = do
400+typeConstraintsForBinder val b@(NamedBinder name binder) = do
390 me <- fresh
401 me <- fresh
391 (cs, m) <- typeConstraintsForBinder val binder
402 (cs, m) <- typeConstraintsForBinder val binder
392− return (TypeConstraint me (TUnknown val) : cs, M.insert name me m)
403+ return (TypeConstraint me (TUnknown val) (BinderOrigin b) : cs, M.insert name me m)
393−typeConstraintsForBinder val (GuardedBinder cond binder) = do
404+typeConstraintsForBinder val b@(GuardedBinder cond binder) = do
394 (cs1, m) <- typeConstraintsForBinder val binder
405 (cs1, m) <- typeConstraintsForBinder val binder
395 (cs2, n) <- typeConstraints m cond
406 (cs2, n) <- typeConstraints m cond
396− return (TypeConstraint n Boolean : cs1 ++ cs2, m)
407+ return (TypeConstraint n Boolean (ValueOrigin cond) : cs1 ++ cs2, m)
398−constantBinder :: Int -> Type -> Check ([TypeConstraint], M.Map Ident Int)
409+constantBinder :: Binder -> Int -> Type -> Check ([TypeConstraint], M.Map Ident Int)
399−constantBinder val ty = return ([TypeConstraint val ty], M.empty)
410+constantBinder b val ty = return ([TypeConstraint val ty (BinderOrigin b)], M.empty)
401typeConstraintsForBinders :: M.Map Ident Int -> Int -> Int -> [(Binder, Value)] -> Check [TypeConstraint]
412typeConstraintsForBinders :: M.Map Ident Int -> Int -> Int -> [(Binder, Value)] -> Check [TypeConstraint]
402typeConstraintsForBinders _ _ _ [] = return []
413typeConstraintsForBinders _ _ _ [] = return []
@@ -404,7 +415,7 @@ typeConstraintsForBinders m nval ret ((binder, val):bs) = do
404 (cs1, m1) <- typeConstraintsForBinder nval binder
415 (cs1, m1) <- typeConstraintsForBinder nval binder
405 (cs2, n2) <- typeConstraints (M.union m m1) val
416 (cs2, n2) <- typeConstraints (M.union m m1) val
406 cs3 <- typeConstraintsForBinders m nval ret bs
417 cs3 <- typeConstraintsForBinders m nval ret bs
407− return ((TypeConstraint n2 (TUnknown ret)) : cs1 ++ cs2 ++ cs3)
418+ return ((TypeConstraint n2 (TUnknown ret) (BinderOrigin binder)) : cs1 ++ cs2 ++ cs3)
409assignVariable :: Ident -> M.Map Ident Int -> Check ()
420assignVariable :: Ident -> M.Map Ident Int -> Check ()
410assignVariable name m =
421assignVariable name m =
@@ -424,7 +435,7 @@ typeConstraintsForStatement m mass ret (Assignment tgt val) = do
424typeConstraintsForStatement m mass ret (While val inner) = do
435typeConstraintsForStatement m mass ret (While val inner) = do
425 (cs1, n1) <- typeConstraints m val
436 (cs1, n1) <- typeConstraints m val
426 (cs2, allCodePathsReturn, _) <- typeConstraintsForBlock m mass ret inner
437 (cs2, allCodePathsReturn, _) <- typeConstraintsForBlock m mass ret inner
427− return $ ((TypeConstraint n1 Boolean) : cs1 ++ cs2, allCodePathsReturn, mass)
438+ return $ ((TypeConstraint n1 Boolean (ValueOrigin val)) : cs1 ++ cs2, allCodePathsReturn, mass)
428typeConstraintsForStatement m mass ret (If ifst) = do
439typeConstraintsForStatement m mass ret (If ifst) = do
429 (cs, allCodePathsReturn) <- typeConstraintsForIfStatement m mass ret ifst
440 (cs, allCodePathsReturn) <- typeConstraintsForIfStatement m mass ret ifst
430 return $ (cs, allCodePathsReturn, mass)
441 return $ (cs, allCodePathsReturn, mass)
@@ -434,7 +445,7 @@ typeConstraintsForStatement m mass ret (For ident start end inner) = do
434 (cs2, n2) <- typeConstraints (m `M.union` mass) end
445 (cs2, n2) <- typeConstraints (m `M.union` mass) end
435 let mass1 = M.insert ident n1 mass
446 let mass1 = M.insert ident n1 mass
436 (cs3, allCodePathsReturn, _) <- typeConstraintsForBlock (m `M.union` mass1) mass1 ret inner
447 (cs3, allCodePathsReturn, _) <- typeConstraintsForBlock (m `M.union` mass1) mass1 ret inner
437− return $ ((TypeConstraint n1 Number) : (TypeConstraint n2 Number) : cs1 ++ cs2 ++ cs3, allCodePathsReturn, mass)
448+ return $ ((TypeConstraint n1 Number (ValueOrigin start)) : (TypeConstraint n2 Number (ValueOrigin end)) : cs1 ++ cs2 ++ cs3, allCodePathsReturn, mass)
438typeConstraintsForStatement m mass ret (ForEach ident vals inner) = do
449typeConstraintsForStatement m mass ret (ForEach ident vals inner) = do
439 assignVariable ident (m `M.union` mass)
450 assignVariable ident (m `M.union` mass)
440 val <- fresh
451 val <- fresh
@@ -442,21 +453,21 @@ typeConstraintsForStatement m mass ret (ForEach ident vals inner) = do
442 let mass1 = M.insert ident val mass
453 let mass1 = M.insert ident val mass
443 (cs2, allCodePathsReturn, _) <- typeConstraintsForBlock (m `M.union` mass1) mass1 ret inner
454 (cs2, allCodePathsReturn, _) <- typeConstraintsForBlock (m `M.union` mass1) mass1 ret inner
444 guardWith "Cannot return from within a foreach block" $ not allCodePathsReturn
455 guardWith "Cannot return from within a foreach block" $ not allCodePathsReturn
445− return $ ((TypeConstraint n1 (Array (TUnknown val))) : cs1 ++ cs2, False, mass)
456+ return $ ((TypeConstraint n1 (Array (TUnknown val)) (ValueOrigin vals)) : cs1 ++ cs2, False, mass)
446typeConstraintsForStatement m mass ret (Return val) = do
457typeConstraintsForStatement m mass ret (Return val) = do
447 (cs1, n1) <- typeConstraints (m `M.union` mass) val
458 (cs1, n1) <- typeConstraints (m `M.union` mass) val
448− return ((TypeConstraint n1 (TUnknown ret)) : cs1, True, mass)
459+ return ((TypeConstraint n1 (TUnknown ret) (ValueOrigin val)) : cs1, True, mass)
450typeConstraintsForIfStatement :: M.Map Ident Int -> M.Map Ident Int -> Int -> IfStatement -> Check ([TypeConstraint], Bool)
461typeConstraintsForIfStatement :: M.Map Ident Int -> M.Map Ident Int -> Int -> IfStatement -> Check ([TypeConstraint], Bool)
451typeConstraintsForIfStatement m mass ret (IfStatement val thens Nothing) = do
462typeConstraintsForIfStatement m mass ret (IfStatement val thens Nothing) = do
452 (cs1, n1) <- typeConstraints m val
463 (cs1, n1) <- typeConstraints m val
453 (cs2, allCodePathsReturn, _) <- typeConstraintsForBlock m mass ret thens
464 (cs2, allCodePathsReturn, _) <- typeConstraintsForBlock m mass ret thens
454− return ((TypeConstraint n1 Boolean) : cs1 ++ cs2, allCodePathsReturn)
465+ return ((TypeConstraint n1 Boolean (ValueOrigin val)) : cs1 ++ cs2, allCodePathsReturn)
455typeConstraintsForIfStatement m mass ret (IfStatement val thens (Just elses)) = do
466typeConstraintsForIfStatement m mass ret (IfStatement val thens (Just elses)) = do
456 (cs1, n1) <- typeConstraints m val
467 (cs1, n1) <- typeConstraints m val
457 (cs2, allCodePathsReturn1, _) <- typeConstraintsForBlock m mass ret thens
468 (cs2, allCodePathsReturn1, _) <- typeConstraintsForBlock m mass ret thens
458 (cs3, allCodePathsReturn2) <- typeConstraintsForElseStatement m mass ret elses
469 (cs3, allCodePathsReturn2) <- typeConstraintsForElseStatement m mass ret elses
459− return ((TypeConstraint n1 Boolean) : cs1 ++ cs2 ++ cs3, allCodePathsReturn1 && allCodePathsReturn2)
470+ return ((TypeConstraint n1 Boolean (ValueOrigin val)) : cs1 ++ cs2 ++ cs3, allCodePathsReturn1 && allCodePathsReturn2)
461typeConstraintsForElseStatement :: M.Map Ident Int -> M.Map Ident Int -> Int -> ElseStatement -> Check ([TypeConstraint], Bool)
472typeConstraintsForElseStatement :: M.Map Ident Int -> M.Map Ident Int -> Int -> ElseStatement -> Check ([TypeConstraint], Bool)
462typeConstraintsForElseStatement m mass ret (Else elses) = do
473typeConstraintsForElseStatement m mass ret (Else elses) = do
@@ -467,21 +478,21 @@ typeConstraintsForElseStatement m mass ret (ElseIf ifst) = do
467 return (cs, allCodePathsReturn)
478 return (cs, allCodePathsReturn)
469typeConstraintsForAssignmentTarget :: M.Map Ident Int -> M.Map Ident Int -> Int -> AssignmentTarget -> Check [TypeConstraint]
480typeConstraintsForAssignmentTarget :: M.Map Ident Int -> M.Map Ident Int -> Int -> AssignmentTarget -> Check [TypeConstraint]
470−typeConstraintsForAssignmentTarget m mass nval (AssignVariable var) =
481+typeConstraintsForAssignmentTarget m mass nval a@(AssignVariable var) =
471 case M.lookup var mass of
482 case M.lookup var mass of
472 Nothing -> throwError $ "No local variable with name " ++ show var
483 Nothing -> throwError $ "No local variable with name " ++ show var
473 Just ty -> do
484 Just ty -> do
474− return [TypeConstraint nval (TUnknown ty)]
485+ return [TypeConstraint nval (TUnknown ty) (AssignmentTargetOrigin a)]
475−typeConstraintsForAssignmentTarget m mass nval (AssignArrayIndex index tgt) = do
486+typeConstraintsForAssignmentTarget m mass nval a@(AssignArrayIndex index tgt) = do
476 arr <- fresh
487 arr <- fresh
477 (cs1, n1) <- typeConstraints (m `M.union` mass) index
488 (cs1, n1) <- typeConstraints (m `M.union` mass) index
478 cs2 <- typeConstraintsForAssignmentTarget m mass arr tgt
489 cs2 <- typeConstraintsForAssignmentTarget m mass arr tgt
479− return $ (TypeConstraint arr (Array (TUnknown nval))) : (TypeConstraint n1 Number) : cs1 ++ cs2
490+ return $ (TypeConstraint arr (Array (TUnknown nval)) (AssignmentTargetOrigin a)) : (TypeConstraint n1 Number (ValueOrigin index)) : cs1 ++ cs2
480−typeConstraintsForAssignmentTarget m mass nval (AssignObjectProperty prop tgt) = do
491+typeConstraintsForAssignmentTarget m mass nval a@(AssignObjectProperty prop tgt) = do
481 obj <- fresh
492 obj <- fresh
482 row <- fresh
493 row <- fresh
483 cs <- typeConstraintsForAssignmentTarget m mass obj tgt
494 cs <- typeConstraintsForAssignmentTarget m mass obj tgt
484− return $ (TypeConstraint obj (Object (RCons prop (TUnknown nval) $ RUnknown row))) : cs
495+ return $ (TypeConstraint obj (Object (RCons prop (TUnknown nval) $ RUnknown row)) (AssignmentTargetOrigin a)) : cs
486typeConstraintsForBlock :: M.Map Ident Int -> M.Map Ident Int -> Int -> [Statement] -> Check ([TypeConstraint], Bool, M.Map Ident Int)
497typeConstraintsForBlock :: M.Map Ident Int -> M.Map Ident Int -> Int -> [Statement] -> Check ([TypeConstraint], Bool, M.Map Ident Int)
487typeConstraintsForBlock _ mass _ [] = return ([], False, mass)
498typeConstraintsForBlock _ mass _ [] = return ([], False, mass)
@@ -496,97 +507,100 @@ typeConstraintsForBlock m mass ret (s:ss) = do
497solveTypeConstraints :: [TypeConstraint] -> TypeSolution -> Check TypeSolution
508solveTypeConstraints :: [TypeConstraint] -> TypeSolution -> Check TypeSolution
498solveTypeConstraints [] s = return s
509solveTypeConstraints [] s = return s
499−solveTypeConstraints all@(TypeConstraint n t:cs) s = do
510+solveTypeConstraints all@(TypeConstraint n t o:cs) s = do
511+ (cs', s') <- rethrow (\err -> "Error in " ++ prettyPrintOrigin o ++ ": " ++ err) $ do
500− typeOccursCheck n t
512+ typeOccursCheck n t
501− let s' = let (f, g) = runTypeSolution s
513+ let s' = let (f, g) = runTypeSolution s
502− in TypeSolution (replaceType n t . f, replaceType n t . g)
514+ in TypeSolution (replaceType n t . f, replaceType n t . g)
503− cs' <- fmap concat $ mapM (substituteTypeInConstraint n t) cs
515+ cs' <- fmap concat $ mapM (substituteTypeInConstraint n t) cs
504 solveTypeConstraints cs' s'
517 solveTypeConstraints cs' s'
505−solveTypeConstraints (RowConstraint n r:cs) s = do
518+solveTypeConstraints (RowConstraint n r o:cs) s = do
519+ (cs', s') <- rethrow (\err -> "Error in " ++ prettyPrintOrigin o ++ ": " ++ err) $ do
506− rowOccursCheck n r
520+ rowOccursCheck n r
507− let s' = let (f, g) = runTypeSolution s
521+ let s' = let (f, g) = runTypeSolution s
508− in TypeSolution $ (replaceRow n r . f, replaceRow n r . g)
522+ in TypeSolution $ (replaceRow n r . f, replaceRow n r . g)
509− cs' <- fmap concat $ mapM (substituteRowInConstraint n r) cs
523+ cs' <- fmap concat $ mapM (substituteRowInConstraint n r) cs
510 solveTypeConstraints cs' s'
525 solveTypeConstraints cs' s'
512substituteTypeInConstraint :: Int -> Type -> TypeConstraint -> Check [TypeConstraint]
527substituteTypeInConstraint :: Int -> Type -> TypeConstraint -> Check [TypeConstraint]
513−substituteTypeInConstraint n s (TypeConstraint m t)
528+substituteTypeInConstraint n s (TypeConstraint m t v)
514− | n == m = unifyTypes s t
529+ | n == m = unifyTypes v s t
515− | otherwise = return [TypeConstraint m (replaceType n s t)]
530+ | otherwise = return [TypeConstraint m (replaceType n s t) v]
516−substituteTypeInConstraint n s (RowConstraint m r)
531+substituteTypeInConstraint n s (RowConstraint m r v)
517− = return [RowConstraint m (replaceType n s r)]
532+ = return [RowConstraint m (replaceType n s r) v]
519substituteRowInConstraint :: Int -> Row -> TypeConstraint -> Check [TypeConstraint]
534substituteRowInConstraint :: Int -> Row -> TypeConstraint -> Check [TypeConstraint]
520−substituteRowInConstraint n r (TypeConstraint m t)
535+substituteRowInConstraint n r (TypeConstraint m t v)
521− = return [TypeConstraint m (replaceRow n r t)]
536+ = return [TypeConstraint m (replaceRow n r t) v]
522−substituteRowInConstraint n r (RowConstraint m r1)
537+substituteRowInConstraint n r (RowConstraint m r1 v)
523− | m == n = unifyRows r r1
538+ | m == n = unifyRows v r r1
524− | otherwise = return [RowConstraint m (replaceRow n r r1)]
539+ | otherwise = return [RowConstraint m (replaceRow n r r1) v]
526−unifyTypes :: Type -> Type -> Check [TypeConstraint]
541+unifyTypes :: TypeConstraintOrigin -> Type -> Type -> Check [TypeConstraint]
527−unifyTypes (TUnknown u1) (TUnknown u2) | u1 == u2 = return []
542+unifyTypes _ (TUnknown u1) (TUnknown u2) | u1 == u2 = return []
528−unifyTypes (TUnknown u) t = do
543+unifyTypes o (TUnknown u) t = do
529 typeOccursCheck u t
544 typeOccursCheck u t
530− return [TypeConstraint u t]
545+ return [TypeConstraint u t o]
531−unifyTypes t (TUnknown u) = do
546+unifyTypes o t (TUnknown u) = do
532 typeOccursCheck u t
547 typeOccursCheck u t
533− return [TypeConstraint u t]
548+ return [TypeConstraint u t o]
534−unifyTypes (SaturatedTypeSynonym name1 args1) (SaturatedTypeSynonym name2 args2) | name1 == name2 =
549+unifyTypes o (SaturatedTypeSynonym name1 args1) (SaturatedTypeSynonym name2 args2) | name1 == name2 =
535− fmap concat $ zipWithM unifyTypes args1 args2
550+ fmap concat $ zipWithM (unifyTypes o) args1 args2
536−unifyTypes (SaturatedTypeSynonym name args) ty = do
551+unifyTypes o (SaturatedTypeSynonym name args) ty = do
537 env <- getEnv
552 env <- getEnv
538 case M.lookup name (typeSynonyms env) of
553 case M.lookup name (typeSynonyms env) of
539 Just (synArgs, body) -> do
554 Just (synArgs, body) -> do
540 let m = M.fromList $ zip synArgs args
555 let m = M.fromList $ zip synArgs args
541 let replaced = replaceTypeVars m body
556 let replaced = replaceTypeVars m body
542− unifyTypes replaced ty
557+ unifyTypes o replaced ty
543 Nothing -> error "Type synonym was not defined"
558 Nothing -> error "Type synonym was not defined"
544−unifyTypes ty s@(SaturatedTypeSynonym _ _) = unifyTypes s ty
559+unifyTypes o ty s@(SaturatedTypeSynonym _ _) = unifyTypes o s ty
545−unifyTypes Number Number = return []
560+unifyTypes _ Number Number = return []
546−unifyTypes String String = return []
561+unifyTypes _ String String = return []
547−unifyTypes Boolean Boolean = return []
562+unifyTypes _ Boolean Boolean = return []
548−unifyTypes (Array s) (Array t) = unifyTypes s t
563+unifyTypes o (Array s) (Array t) = unifyTypes o s t
549−unifyTypes (Object row1) (Object row2) = unifyRows row1 row2
564+unifyTypes o (Object row1) (Object row2) = unifyRows o row1 row2
550−unifyTypes (Function args1 ret1) (Function args2 ret2) = do
565+unifyTypes o (Function args1 ret1) (Function args2 ret2) = do
551 guardWith "Function applied to incorrect number of args" $ length args1 == length args2
566 guardWith "Function applied to incorrect number of args" $ length args1 == length args2
552− cs1 <- fmap concat $ zipWithM unifyTypes args1 args2
567+ cs1 <- fmap concat $ zipWithM (unifyTypes o) args1 args2
553− cs2 <- unifyTypes ret1 ret2
568+ cs2 <- unifyTypes o ret1 ret2
554 return $ cs1 ++ cs2
569 return $ cs1 ++ cs2
555−unifyTypes (TypeVar v1) (TypeVar v2) | v1 == v2 = return []
570+unifyTypes _ (TypeVar v1) (TypeVar v2) | v1 == v2 = return []
556−unifyTypes (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = return []
571+unifyTypes _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = return []
557−unifyTypes (TypeVar v1) (TypeVar v2) = return []
558−unifyTypes (TypeApp t1 t2) (TypeApp t3 t4) = do
572+unifyTypes o (TypeApp t1 t2) (TypeApp t3 t4) = do
559− cs1 <- unifyTypes t1 t3
573+ cs1 <- unifyTypes o t1 t3
560− cs2 <- unifyTypes t2 t4
574+ cs2 <- unifyTypes o t2 t4
561 return $ cs1 ++ cs2
575 return $ cs1 ++ cs2
562−unifyTypes t1 t2 = throwError $ "Cannot unify " ++ prettyPrintType t1 ++ " with " ++ prettyPrintType t2 ++ "."
576+unifyTypes _ t1 t2 = throwError $ "Cannot unify " ++ prettyPrintType t1 ++ " with " ++ prettyPrintType t2 ++ "."
564−unifyRows :: Row -> Row -> Check [TypeConstraint]
578+unifyRows :: TypeConstraintOrigin -> Row -> Row -> Check [TypeConstraint]
565−unifyRows r1 r2 =
579+unifyRows o r1 r2 =
567 (s1, r1') = toList r1
581 (s1, r1') = toList r1
568 (s2, r2') = toList r2
582 (s2, r2') = toList r2
569 int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
583 int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
570 sd1 = [ (name, t1) | (name, t1) <- s1, not (elem name (map fst s2)) ]
584 sd1 = [ (name, t1) | (name, t1) <- s1, not (elem name (map fst s2)) ]
571 sd2 = [ (name, t2) | (name, t2) <- s2, not (elem name (map fst s1)) ]
585 sd2 = [ (name, t2) | (name, t2) <- s2, not (elem name (map fst s1)) ]
572− in rethrow (\e -> "Cannot unify " ++ prettyPrintRow r1 ++ " with " ++ prettyPrintRow r2 ++ ": " ++ e) $ do
586+ in do
573− cs1 <- fmap concat $ mapM (uncurry unifyTypes) int
587+ cs1 <- fmap concat $ mapM (uncurry $ unifyTypes o) int
574− cs2 <- unifyRows' sd1 r1' sd2 r2'
588+ cs2 <- unifyRows' o sd1 r1' sd2 r2'
575 return $ cs1 ++ cs2
589 return $ cs1 ++ cs2
577− unifyRows' :: [(String, Type)] -> Row -> [(String, Type)] -> Row -> Check [TypeConstraint]
591+ unifyRows' :: TypeConstraintOrigin -> [(String, Type)] -> Row -> [(String, Type)] -> Row -> Check [TypeConstraint]
578− unifyRows' [] (RUnknown u) sd r = do
592+ unifyRows' o [] (RUnknown u) sd r = do
579 rowOccursCheck u r
593 rowOccursCheck u r
580− return [RowConstraint u (fromList (sd, r))]
594+ return [RowConstraint u (fromList (sd, r)) o]
581− unifyRows' sd r [] (RUnknown u) = do
595+ unifyRows' o sd r [] (RUnknown u) = do
582 rowOccursCheck u r
596 rowOccursCheck u r
583− return [RowConstraint u (fromList (sd, r))]
597+ return [RowConstraint u (fromList (sd, r)) o]
584− unifyRows' ((name, ty):row) r others (RUnknown u) = do
598+ unifyRows' o ((name, ty):row) r others (RUnknown u) = do
585 u' <- fresh
599 u' <- fresh
586− cs <- unifyRows' row r others (RUnknown u')
600+ cs <- unifyRows' o row r others (RUnknown u')
587− return (RowConstraint u (RCons name ty (RUnknown u')) : cs)
601+ return (RowConstraint u (RCons name ty (RUnknown u')) o : cs)
588− unifyRows' [] REmpty [] REmpty = return []
602+ unifyRows' _ [] REmpty [] REmpty = return []
589− unifyRows' sd1 r1 sd2 r2 = throwError $ "Cannot unify " ++ prettyPrintRow (fromList (sd1, r1)) ++ " with " ++ prettyPrintRow (fromList (sd2, r2)) ++ "."
603+ unifyRows' _ sd1 r1 sd2 r2 = throwError $ "Cannot unify " ++ prettyPrintRow (fromList (sd1, r1)) ++ " with " ++ prettyPrintRow (fromList (sd2, r2)) ++ "."
590 toList :: Row -> ([(String, Type)], Row)
604 toList :: Row -> ([(String, Type)], Row)
591 toList (RCons name ty row) = let (tys, rest) = toList row
605 toList (RCons name ty row) = let (tys, rest) = toList row
592 in ((name, ty):tys, rest)
606 in ((name, ty):tys, rest)