Mercurial > urweb
comparison src/elab_env.sml @ 1742:fca4a6d05ac1
More diagnostic information about some type class resolution failures
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Fri, 04 May 2012 10:33:04 -0400 |
parents | 6c00d8af6239 |
children | d28adceef22a |
comparison
equal
deleted
inserted
replaced
1741:d6e233db97c8 | 1742:fca4a6d05ac1 |
---|---|
676 case firstArg (c, NONE) of | 676 case firstArg (c, NONE) of |
677 NONE => false | 677 NONE => false |
678 | SOME x => hasUnif x | 678 | SOME x => hasUnif x |
679 end | 679 end |
680 | 680 |
681 val cause = ref (NONE : con option) | |
682 fun resolveFailureCause () = !cause | |
683 | |
681 fun resolveClass (hnorm : con -> con) (consEq : con * con -> bool) (env : env) = | 684 fun resolveClass (hnorm : con -> con) (consEq : con * con -> bool) (env : env) = |
682 let | 685 let |
683 fun resolve c = | 686 fun resolve firstLevel c = |
684 let | 687 let |
688 fun notFound () = (if firstLevel then () else cause := SOME c; NONE) | |
689 | |
685 fun doHead f = | 690 fun doHead f = |
686 case CM.find (#classes env, f) of | 691 case CM.find (#classes env, f) of |
687 NONE => NONE | 692 NONE => notFound () |
688 | SOME class => | 693 | SOME class => |
689 let | 694 let |
690 val loc = #2 c | 695 val loc = #2 c |
691 | 696 |
692 fun generalize (c as (_, loc)) = | 697 fun generalize (c as (_, loc)) = |
720 | 725 |
721 val (c, equate) = generalize c | 726 val (c, equate) = generalize c |
722 | 727 |
723 fun tryRules rules = | 728 fun tryRules rules = |
724 case rules of | 729 case rules of |
725 [] => NONE | 730 [] => notFound () |
726 | (nRs, cs, c', e) :: rules' => | 731 | (nRs, cs, c', e) :: rules' => |
727 case tryUnify hnorm nRs (c, c') of | 732 case tryUnify hnorm nRs (c, c') of |
728 NONE => tryRules rules' | 733 NONE => tryRules rules' |
729 | SOME rs => | 734 | SOME rs => |
730 let | 735 let |
731 val eos = map (resolve o unifySubst rs) cs | 736 val eos = map (resolve false o unifySubst rs) cs |
732 in | 737 in |
733 if List.exists (not o Option.isSome) eos | 738 if List.exists (not o Option.isSome) eos |
734 orelse not (equate ()) | 739 orelse not (equate ()) |
735 orelse not (consEq (c, unifySubst rs c')) then | 740 orelse not (consEq (c, unifySubst rs c')) then |
736 tryRules rules' | 741 tryRules rules' |
757 in | 762 in |
758 tryGrounds (#ground class) | 763 tryGrounds (#ground class) |
759 end | 764 end |
760 in | 765 in |
761 if startsWithUnif c then | 766 if startsWithUnif c then |
762 NONE | 767 notFound () |
763 else | 768 else |
764 case #1 c of | 769 case #1 c of |
765 TRecord c => | 770 TRecord c => |
766 (case #1 (hnorm c) of | 771 (case #1 (hnorm c) of |
767 CRecord (_, xts) => | 772 CRecord (_, xts) => |
775 | 780 |
776 val t = case t of | 781 val t = case t of |
777 (CApp (f, x), loc) => (CApp (hnorm f, hnorm x), loc) | 782 (CApp (f, x), loc) => (CApp (hnorm f, hnorm x), loc) |
778 | _ => t | 783 | _ => t |
779 in | 784 in |
780 case resolve t of | 785 case resolve false t of |
781 NONE => NONE | 786 NONE => notFound () |
782 | SOME e => resolver (xts, (x, e, t) :: acc) | 787 | SOME e => resolver (xts, (x, e, t) :: acc) |
783 end | 788 end |
784 in | 789 in |
785 resolver (xts, []) | 790 resolver (xts, []) |
786 end | 791 end |
787 | _ => NONE) | 792 | _ => notFound ()) |
788 | _ => | 793 | _ => |
789 case class_head_in c of | 794 case class_head_in c of |
790 SOME f => doHead f | 795 SOME f => doHead f |
791 | _ => NONE | 796 | _ => notFound () |
792 end | 797 end |
793 in | 798 in |
794 resolve | 799 cause := NONE; |
800 resolve true | |
795 end | 801 end |
796 | 802 |
797 fun pushERel (env : env) x t = | 803 fun pushERel (env : env) x t = |
798 let | 804 let |
799 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) | 805 val renameE = SM.map (fn Rel' (n, t) => Rel' (n+1, t) |