comparison src/elaborate.sml @ 1719:0bafdfae2ac7

Saving proper environments, to use in displaying nested error messages
author Adam Chlipala <adam@chlipala.net>
date Sat, 21 Apr 2012 14:57:00 -0400
parents 16ee7ff7f119
children 5ecf67553da8
comparison
equal deleted inserted replaced
1718:dd12d6d9e9a7 1719:0bafdfae2ac7
84 true) 84 true)
85 handle _ => false 85 handle _ => false
86 86
87 and validateKind env k = validateCon env (L'.CRecord (k, []), ErrorMsg.dummySpan) 87 and validateKind env k = validateCon env (L'.CRecord (k, []), ErrorMsg.dummySpan)
88 88
89 exception KUnify' of kunify_error 89 exception KUnify' of E.env * kunify_error
90 90
91 fun unifyKinds' env (k1All as (k1, _)) (k2All as (k2, _)) = 91 fun unifyKinds' env (k1All as (k1, _)) (k2All as (k2, _)) =
92 let 92 let
93 fun err f = raise KUnify' (f (k1All, k2All)) 93 fun err f = raise KUnify' (env, f (k1All, k2All))
94 in 94 in
95 case (k1, k2) of 95 case (k1, k2) of
96 (L'.KType, L'.KType) => () 96 (L'.KType, L'.KType) => ()
97 | (L'.KUnit, L'.KUnit) => () 97 | (L'.KUnit, L'.KUnit) => ()
98 98
177 end 177 end
178 178
179 | _ => err KIncompatible 179 | _ => err KIncompatible
180 end 180 end
181 181
182 exception KUnify of L'.kind * L'.kind * kunify_error 182 exception KUnify of L'.kind * L'.kind * E.env * kunify_error
183 183
184 fun unifyKinds env k1 k2 = 184 fun unifyKinds env k1 k2 =
185 unifyKinds' env k1 k2 185 unifyKinds' env k1 k2
186 handle KUnify' err => raise KUnify (k1, k2, err) 186 handle KUnify' (env', err) => raise KUnify (k1, k2, env', err)
187 187
188 fun checkKind env c k1 k2 = 188 fun checkKind env c k1 k2 =
189 unifyKinds env k1 k2 189 unifyKinds env k1 k2
190 handle KUnify (k1, k2, err) => 190 handle KUnify (k1, k2, env', err) =>
191 conError env (WrongKind (c, k1, k2, err)) 191 conError env (WrongKind (c, k1, k2, env', err))
192 192
193 val dummy = ErrorMsg.dummySpan 193 val dummy = ErrorMsg.dummySpan
194 194
195 val ktype = (L'.KType, dummy) 195 val ktype = (L'.KType, dummy)
196 val kname = (L'.KName, dummy) 196 val kname = (L'.KName, dummy)
561 fun occursCon r = 561 fun occursCon r =
562 U.Con.exists {kind = fn _ => false, 562 U.Con.exists {kind = fn _ => false,
563 con = fn L'.CUnif (_, _, _, _, r') => r = r' 563 con = fn L'.CUnif (_, _, _, _, r') => r = r'
564 | _ => false} 564 | _ => false}
565 565
566 exception CUnify' of cunify_error 566 exception CUnify' of E.env * cunify_error
567 567
568 type record_summary = { 568 type record_summary = {
569 fields : (L'.con * L'.con) list, 569 fields : (L'.con * L'.con) list,
570 unifs : (L'.con * L'.cunif ref) list, 570 unifs : (L'.con * L'.cunif ref) list,
571 others : L'.con list 571 others : L'.con list
587 concat ((L'.CRecord (ktype, fields), dummy), c) 587 concat ((L'.CRecord (ktype, fields), dummy), c)
588 end 588 end
589 589
590 fun p_summary env s = p_con env (summaryToCon s) 590 fun p_summary env s = p_con env (summaryToCon s)
591 591
592 exception CUnify of L'.con * L'.con * cunify_error 592 exception CUnify of L'.con * L'.con * E.env * cunify_error
593 593
594 fun kindof env (c, loc) = 594 fun kindof env (c, loc) =
595 case c of 595 case c of
596 L'.TFun _ => ktype 596 L'.TFun _ => ktype
597 | L'.TCFun _ => ktype 597 | L'.TCFun _ => ktype
616 616
617 | L'.CApp (c, _) => 617 | L'.CApp (c, _) =>
618 (case hnormKind (kindof env c) of 618 (case hnormKind (kindof env c) of
619 (L'.KArrow (_, k), _) => k 619 (L'.KArrow (_, k), _) => k
620 | (L'.KError, _) => kerror 620 | (L'.KError, _) => kerror
621 | k => raise CUnify' (CKindof (k, c, "arrow"))) 621 | k => raise CUnify' (env, CKindof (k, c, "arrow")))
622 | L'.CAbs (x, k, c) => (L'.KArrow (k, kindof (E.pushCRel env x k) c), loc) 622 | L'.CAbs (x, k, c) => (L'.KArrow (k, kindof (E.pushCRel env x k) c), loc)
623 623
624 624
625 | L'.CName _ => kname 625 | L'.CName _ => kname
626 626
651 val k = (L'.KTupleUnif (loc, ((n, ku) :: nks), r), loc) 651 val k = (L'.KTupleUnif (loc, ((n, ku) :: nks), r), loc)
652 in 652 in
653 r := L'.KKnown k; 653 r := L'.KKnown k;
654 k 654 k
655 end) 655 end)
656 | k => raise CUnify' (CKindof (k, c, "tuple"))) 656 | k => raise CUnify' (env, CKindof (k, c, "tuple")))
657 657
658 | L'.CError => kerror 658 | L'.CError => kerror
659 | L'.CUnif (_, _, k, _, _) => k 659 | L'.CUnif (_, _, k, _, _) => k
660 660
661 | L'.CKAbs (x, c) => (L'.KFun (x, kindof (E.pushKRel env x) c), loc) 661 | L'.CKAbs (x, c) => (L'.KFun (x, kindof (E.pushKRel env x) c), loc)
662 | L'.CKApp (c, k) => 662 | L'.CKApp (c, k) =>
663 (case hnormKind (kindof env c) of 663 (case hnormKind (kindof env c) of
664 (L'.KFun (_, k'), _) => subKindInKind (0, k) k' 664 (L'.KFun (_, k'), _) => subKindInKind (0, k) k'
665 | k => raise CUnify' (CKindof (k, c, "kapp"))) 665 | k => raise CUnify' (env, CKindof (k, c, "kapp")))
666 | L'.TKFun _ => ktype 666 | L'.TKFun _ => ktype
667 667
668 exception GuessFailure 668 exception GuessFailure
669 669
670 fun isUnitCon env (c, loc) = 670 fun isUnitCon env (c, loc) =
756 val k = kunif' f (#2 c) 756 val k = kunif' f (#2 c)
757 in 757 in
758 r := L'.KKnown (L'.KRecord k, #2 c); 758 r := L'.KKnown (L'.KRecord k, #2 c);
759 k 759 k
760 end 760 end
761 | k => raise CUnify' (CKindof (k, c, "record")) 761 | k => raise CUnify' (env, CKindof (k, c, "record"))
762 762
763 val k1 = rkindof c1 763 val k1 = rkindof c1
764 val k2 = rkindof c2 764 val k2 = rkindof c2
765 765
766 val r1 = recordSummary env c1 766 val r1 = recordSummary env c1
985 | SOME (_, c2) => 985 | SOME (_, c2) =>
986 if consEq env loc (c1, c2) then 986 if consEq env loc (c1, c2) then
987 findPointwise fs1 987 findPointwise fs1
988 else 988 else
989 SOME (nm1, c1, c2, (unifyCons env loc c1 c2; NONE) 989 SOME (nm1, c1, c2, (unifyCons env loc c1 c2; NONE)
990 handle CUnify (_, _, err) => (reducedSummaries := NONE; 990 handle CUnify (_, _, env', err) => (reducedSummaries := NONE;
991 SOME err)) 991 SOME (env', err)))
992 in 992 in
993 raise CUnify' (CRecordFailure (unsummarize s1, unsummarize s2, findPointwise (#fields s1))) 993 raise CUnify' (env, CRecordFailure (unsummarize s1, unsummarize s2, findPointwise (#fields s1)))
994 end 994 end
995 995
996 fun default () = if !mayDelay then 996 fun default () = if !mayDelay then
997 delayedUnifs := (loc, env, k, s1, s2) :: !delayedUnifs 997 delayedUnifs := (loc, env, k, s1, s2) :: !delayedUnifs
998 else 998 else
1007 let 1007 let
1008 val c = summaryToCon {fields = fs1, unifs = unifs1, others = others1} 1008 val c = summaryToCon {fields = fs1, unifs = unifs1, others = others1}
1009 in 1009 in
1010 if occursCon r c then 1010 if occursCon r c then
1011 (reducedSummaries := NONE; 1011 (reducedSummaries := NONE;
1012 raise CUnify' (COccursCheckFailed (cr, c))) 1012 raise CUnify' (env, COccursCheckFailed (cr, c)))
1013 else 1013 else
1014 let 1014 let
1015 val sq = squish nl c 1015 val sq = squish nl c
1016 in 1016 in
1017 if not (f sq) then 1017 if not (f sq) then
1025 let 1025 let
1026 val c = summaryToCon {fields = fs2, unifs = unifs2, others = others2} 1026 val c = summaryToCon {fields = fs2, unifs = unifs2, others = others2}
1027 in 1027 in
1028 if occursCon r c then 1028 if occursCon r c then
1029 (reducedSummaries := NONE; 1029 (reducedSummaries := NONE;
1030 raise CUnify' (COccursCheckFailed (cr, c))) 1030 raise CUnify' (env, COccursCheckFailed (cr, c)))
1031 else 1031 else
1032 let 1032 let
1033 val sq = squish nl c 1033 val sq = squish nl c
1034 in 1034 in
1035 if not (f sq) then 1035 if not (f sq) then
1117 handle ex => guessMap env loc (c1, c2, ex) 1117 handle ex => guessMap env loc (c1, c2, ex)
1118 end 1118 end
1119 1119
1120 and unifyCons'' env loc (c1All as (c1, _)) (c2All as (c2, _)) = 1120 and unifyCons'' env loc (c1All as (c1, _)) (c2All as (c2, _)) =
1121 let 1121 let
1122 fun err f = raise CUnify' (f (c1All, c2All)) 1122 fun err f = raise CUnify' (env, f (c1All, c2All))
1123 1123
1124 fun projSpecial1 (c1, n1, onFail) = 1124 fun projSpecial1 (c1, n1, onFail) =
1125 let 1125 let
1126 fun trySnd () = 1126 fun trySnd () =
1127 case #1 (hnormCon env c2All) of 1127 case #1 (hnormCon env c2All) of
1342 ("c2", p_con env c2All)]*) 1342 ("c2", p_con env c2All)]*)
1343 end 1343 end
1344 1344
1345 and unifyCons env loc c1 c2 = 1345 and unifyCons env loc c1 c2 =
1346 unifyCons' env loc c1 c2 1346 unifyCons' env loc c1 c2
1347 handle CUnify' err => raise CUnify (c1, c2, err) 1347 handle CUnify' (env', err) => raise CUnify (c1, c2, env', err)
1348 | KUnify args => raise CUnify (c1, c2, CKind args) 1348 | KUnify (arg as {3 = env', ...}) => raise CUnify (c1, c2, env', CKind arg)
1349 1349
1350 fun checkCon env e c1 c2 = 1350 fun checkCon env e c1 c2 =
1351 unifyCons env (#2 e) c1 c2 1351 unifyCons env (#2 e) c1 c2
1352 handle CUnify (c1, c2, err) => 1352 handle CUnify (c1, c2, env', err) =>
1353 expError env (Unify (e, c1, c2, err)) 1353 expError env (Unify (e, c1, c2, env', err))
1354 1354
1355 fun checkPatCon env p c1 c2 = 1355 fun checkPatCon env p c1 c2 =
1356 unifyCons env (#2 p) c1 c2 1356 unifyCons env (#2 p) c1 c2
1357 handle CUnify (c1, c2, err) => 1357 handle CUnify (c1, c2, env', err) =>
1358 expError env (PatUnify (p, c1, c2, err)) 1358 expError env (PatUnify (p, c1, c2, env', err))
1359 1359
1360 fun primType env p = 1360 fun primType env p =
1361 case p of 1361 case p of
1362 P.Int _ => !int 1362 P.Int _ => !int
1363 | P.Float _ => !float 1363 | P.Float _ => !float
2577 val old = c' 2577 val old = c'
2578 val c' = normClassConstraint env c' 2578 val c' = normClassConstraint env c'
2579 val (env', n) = E.pushENamed env x c' 2579 val (env', n) = E.pushENamed env x c'
2580 in 2580 in
2581 (unifyKinds env ck ktype 2581 (unifyKinds env ck ktype
2582 handle KUnify ue => strError env (NotType (loc, ck, ue))); 2582 handle KUnify arg => strError env (NotType (loc, ck, arg)));
2583 2583
2584 ([(L'.SgiVal (x, n, c'), loc)], (env', denv, gs' @ gs)) 2584 ([(L'.SgiVal (x, n, c'), loc)], (env', denv, gs' @ gs))
2585 end 2585 end
2586 2586
2587 | L.SgiTable (x, c, pe, ce) => 2587 | L.SgiTable (x, c, pe, ce) =>
3054 let 3054 let
3055 fun found (x', n1, k1, co1) = 3055 fun found (x', n1, k1, co1) =
3056 if x = x' then 3056 if x = x' then
3057 let 3057 let
3058 val () = unifyKinds env k1 k2 3058 val () = unifyKinds env k1 k2
3059 handle KUnify (k1, k2, err) => 3059 handle KUnify (k1, k2, env', err) =>
3060 sgnError env (SgiWrongKind (loc, sgi1All, k1, 3060 sgnError env (SgiWrongKind (loc, sgi1All, k1,
3061 sgi2All, k2, err)) 3061 sgi2All, k2, env', err))
3062 val env = E.pushCNamedAs env x n1 k1 co1 3062 val env = E.pushCNamedAs env x n1 k1 co1
3063 in 3063 in
3064 SOME (if n1 = n2 then 3064 SOME (if n1 = n2 then
3065 env 3065 env
3066 else 3066 else
3123 SOME env 3123 SOME env
3124 end 3124 end
3125 in 3125 in
3126 (unifyCons env loc c1 c2; 3126 (unifyCons env loc c1 c2;
3127 good ()) 3127 good ())
3128 handle CUnify (c1, c2, err) => 3128 handle CUnify (c1, c2, env', err) =>
3129 (sgnError env (SgiWrongCon (loc, sgi1All, c1, 3129 (sgnError env (SgiWrongCon (loc, sgi1All, c1,
3130 sgi2All, c2, err)); 3130 sgi2All, c2, env', err));
3131 good ()) 3131 good ())
3132 end 3132 end
3133 else 3133 else
3134 NONE 3134 NONE
3135 in 3135 in
3249 SOME env 3249 SOME env
3250 end 3250 end
3251 in 3251 in
3252 (unifyCons env loc t1 t2; 3252 (unifyCons env loc t1 t2;
3253 good ()) 3253 good ())
3254 handle CUnify (c1, c2, err) => 3254 handle CUnify (c1, c2, env', err) =>
3255 (sgnError env (SgiWrongCon (loc, sgi1All, c1, sgi2All, c2, err)); 3255 (sgnError env (SgiWrongCon (loc, sgi1All, c1, sgi2All, c2, env', err));
3256 good ()) 3256 good ())
3257 end 3257 end
3258 else 3258 else
3259 NONE 3259 NONE
3260 3260
3270 ("c1", p_con env c1), 3270 ("c1", p_con env c1),
3271 ("c2", p_con env c2), 3271 ("c2", p_con env c2),
3272 ("c2'", p_con env (sub2 c2))];*) 3272 ("c2'", p_con env (sub2 c2))];*)
3273 unifyCons env loc c1 (sub2 c2); 3273 unifyCons env loc c1 (sub2 c2);
3274 SOME env) 3274 SOME env)
3275 handle CUnify (c1, c2, err) => 3275 handle CUnify (c1, c2, env', err) =>
3276 (sgnError env (SgiWrongCon (loc, sgi1All, c1, sgi2All, c2, err)); 3276 (sgnError env (SgiWrongCon (loc, sgi1All, c1, sgi2All, c2, env', err));
3277 SOME env) 3277 SOME env)
3278 else 3278 else
3279 NONE 3279 NONE
3280 | _ => NONE) 3280 | _ => NONE)
3281 3281
3338 let 3338 let
3339 fun found (x', n1, k1, co) = 3339 fun found (x', n1, k1, co) =
3340 if x = x' then 3340 if x = x' then
3341 let 3341 let
3342 val () = unifyKinds env k1 k2 3342 val () = unifyKinds env k1 k2
3343 handle KUnify (k1, k2, err) => 3343 handle KUnify (k1, k2, env', err) =>
3344 sgnError env (SgiWrongKind (loc, sgi1All, k1, 3344 sgnError env (SgiWrongKind (loc, sgi1All, k1,
3345 sgi2All, k2, err)) 3345 sgi2All, k2, env', err))
3346 3346
3347 val env = E.pushCNamedAs env x n1 k1 co 3347 val env = E.pushCNamedAs env x n1 k1 co
3348 in 3348 in
3349 SOME (if n1 = n2 then 3349 SOME (if n1 = n2 then
3350 env 3350 env
3365 let 3365 let
3366 fun found (x', n1, k1, c1) = 3366 fun found (x', n1, k1, c1) =
3367 if x = x' then 3367 if x = x' then
3368 let 3368 let
3369 val () = unifyKinds env k1 k2 3369 val () = unifyKinds env k1 k2
3370 handle KUnify (k1, k2, err) => 3370 handle KUnify (k1, k2, env', err) =>
3371 sgnError env (SgiWrongKind (loc, sgi1All, k1, 3371 sgnError env (SgiWrongKind (loc, sgi1All, k1,
3372 sgi2All, k2, err)) 3372 sgi2All, k2, env', err))
3373 3373
3374 val c2 = sub2 c2 3374 val c2 = sub2 c2
3375 3375
3376 fun good () = 3376 fun good () =
3377 let 3377 let
3385 SOME env 3385 SOME env
3386 end 3386 end
3387 in 3387 in
3388 (unifyCons env loc c1 c2; 3388 (unifyCons env loc c1 c2;
3389 good ()) 3389 good ())
3390 handle CUnify (c1, c2, err) => 3390 handle CUnify (c1, c2, env', err) =>
3391 (sgnError env (SgiWrongCon (loc, sgi1All, c1, 3391 (sgnError env (SgiWrongCon (loc, sgi1All, c1,
3392 sgi2All, c2, err)); 3392 sgi2All, c2, env', err));
3393 good ()) 3393 good ())
3394 end 3394 end
3395 else 3395 else
3396 NONE 3396 NONE
3397 in 3397 in
4628 if ErrorMsg.anyErrors () then 4628 if ErrorMsg.anyErrors () then
4629 () 4629 ()
4630 else 4630 else
4631 (app (fn (loc, env, k, s1, s2) => 4631 (app (fn (loc, env, k, s1, s2) =>
4632 unifySummaries env (loc, k, normalizeRecordSummary env s1, normalizeRecordSummary env s2) 4632 unifySummaries env (loc, k, normalizeRecordSummary env s1, normalizeRecordSummary env s2)
4633 handle CUnify' err => (ErrorMsg.errorAt loc "Error in final record unification"; 4633 handle CUnify' (env', err) => (ErrorMsg.errorAt loc "Error in final record unification";
4634 cunifyError env err; 4634 cunifyError env' err;
4635 case !reducedSummaries of 4635 case !reducedSummaries of
4636 NONE => () 4636 NONE => ()
4637 | SOME (s1, s2) => 4637 | SOME (s1, s2) =>
4638 (ErrorMsg.errorAt loc "Stuck unifying these records after canceling matching pieces:"; 4638 (ErrorMsg.errorAt loc "Stuck unifying these records after canceling matching pieces:";
4639 eprefaces' [("Have", s1), 4639 eprefaces' [("Have", s1),
4640 ("Need", s2)]))) 4640 ("Need", s2)])))
4641 (!delayedUnifs); 4641 (!delayedUnifs);
4642 delayedUnifs := []); 4642 delayedUnifs := []);
4643 4643
4644 if ErrorMsg.anyErrors () then 4644 if ErrorMsg.anyErrors () then
4645 () 4645 ()