Mercurial > urweb
changeset 987:6dd122f10c0c
Better location calculation for record unification error messages; infer kind arguments to module-projected variables
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Mon, 05 Oct 2009 16:36:38 -0400 |
parents | d1dbb9a3c804 |
children | d923b47e483d |
files | demo/more/orm.ur demo/more/orm.urp demo/more/orm.urs src/elaborate.sml |
diffstat | 4 files changed, 98 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/more/orm.ur Mon Oct 05 16:36:38 2009 -0400 @@ -0,0 +1,29 @@ +con link = fn t :: Type => unit + +con meta = fn col :: Type => { + Link : link col, + Inj : sql_injectable col + } + +functor Table(M : sig + con cols :: {Type} + val cols : $(map meta cols) + constraint [Id] ~ cols + val folder : folder cols + end) = struct + type id = int + val inj = _ + val id : meta id = {Link = (), + Inj = inj} + + sequence s + table t : ([Id = id] ++ M.cols) + + fun create (r : $M.cols) = + id <- nextval s; + dml (insert t ({Id = sql_inject id} + ++ map2 [meta] [Top.id] [sql_exp [] [] []] + (fn [t ::: Type] (meta : meta t) (v : t) => @sql_inject meta.Inj v) + [_] M.folder M.cols r)); + return id +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/more/orm.urp Mon Oct 05 16:36:38 2009 -0400 @@ -0,0 +1,2 @@ + +orm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demo/more/orm.urs Mon Oct 05 16:36:38 2009 -0400 @@ -0,0 +1,19 @@ +con link :: Type -> Type + +con meta = fn col :: Type => { + Link : link col, + Inj : sql_injectable col + } + +functor Table(M : sig + con cols :: {Type} + val cols : $(map meta cols) + constraint [Id] ~ cols + val folder : folder cols + end) : sig + type id + val inj : sql_injectable id + val id : meta id + + val create : $M.cols -> transaction id +end
--- a/src/elaborate.sml Mon Oct 05 12:51:17 2009 -0400 +++ b/src/elaborate.sml Mon Oct 05 16:36:38 2009 -0400 @@ -326,8 +326,9 @@ NONE => (conError env (UnboundCon (loc, s)); kerror) | SOME (k, _) => k + val (c, k) = elabConHead (L'.CModProj (n, ms, s), loc) k in - ((L'.CModProj (n, ms, s), loc), k, []) + (c, k, []) end) | L.CApp (c1, c2) => @@ -678,12 +679,12 @@ sum end - and consEq env (c1, c2) = + and consEq env loc (c1, c2) = let val mayDelay' = !mayDelay in (mayDelay := false; - unifyCons env c1 c2; + unifyCons env loc c1 c2; mayDelay := mayDelay'; true) handle CUnify _ => (mayDelay := mayDelay'; false) @@ -724,15 +725,15 @@ val (fs1, fs2) = eatMatching (fn ((x1, c1), (x2, c2)) => not (consNeq env (x1, x2)) - andalso consEq env (c1, c2) - andalso consEq env (x1, x2)) + andalso consEq env loc (c1, c2) + andalso consEq env loc (x1, x2)) (#fields s1, #fields s2) (*val () = eprefaces "Summaries2" [("#1", p_summary env {fields = fs1, unifs = #unifs s1, others = #others s1}), ("#2", p_summary env {fields = fs2, unifs = #unifs s2, others = #others s2})]*) val (unifs1, unifs2) = eatMatching (fn ((_, r1), (_, r2)) => r1 = r2) (#unifs s1, #unifs s2) - val (others1, others2) = eatMatching (consEq env) (#others s1, #others s2) + val (others1, others2) = eatMatching (consEq env loc) (#others s1, #others s2) (*val () = eprefaces "Summaries3" [("#1", p_summary env {fields = fs1, unifs = unifs1, others = others1}), ("#2", p_summary env {fields = fs2, unifs = unifs2, others = others2})]*) @@ -793,7 +794,7 @@ val c = (L'.CRecord (k, fs), loc) val c = foldl (fn ((c', _), c) => (L'.CConcat (c', c), loc)) c unifs in - (guessMap env (other, c, GuessFailure); + (guessMap env loc (other, c, GuessFailure); true) handle GuessFailure => false end @@ -833,23 +834,21 @@ ("#2", p_summary env (normalizeRecordSummary env s2))]*) end - and guessMap env (c1, c2, ex) = + and guessMap env loc (c1, c2, ex) = let - val loc = #2 c1 - fun unfold (dom, ran, f, r, c) = let fun unfold (r, c) = case #1 (hnormCon env c) of - L'.CRecord (_, []) => unifyCons env r (L'.CRecord (dom, []), loc) + L'.CRecord (_, []) => unifyCons env loc r (L'.CRecord (dom, []), loc) | L'.CRecord (_, [(x, v)]) => let val v' = case dom of (L'.KUnit, _) => (L'.CUnit, loc) | _ => cunif (loc, dom) in - unifyCons env v (L'.CApp (f, v'), loc); - unifyCons env r (L'.CRecord (dom, [(x, v')]), loc) + unifyCons env loc v (L'.CApp (f, v'), loc); + unifyCons env loc r (L'.CRecord (dom, [(x, v')]), loc) end | L'.CRecord (_, (x, v) :: rest) => let @@ -858,7 +857,7 @@ in unfold (r1, (L'.CRecord (ran, [(x, v)]), loc)); unfold (r2, (L'.CRecord (ran, rest), loc)); - unifyCons env r (L'.CConcat (r1, r2), loc) + unifyCons env loc r (L'.CConcat (r1, r2), loc) end | L'.CConcat (c1', c2') => let @@ -867,7 +866,7 @@ in unfold (r1, c1'); unfold (r2, c2'); - unifyCons env r (L'.CConcat (r1, r2), loc) + unifyCons env loc r (L'.CConcat (r1, r2), loc) end | L'.CUnif (_, _, _, ur) => ur := SOME (L'.CApp ((L'.CApp ((L'.CMap (dom, ran), loc), f), loc), r), loc) @@ -885,7 +884,7 @@ | _ => raise ex end - and unifyCons' env c1 c2 = + and unifyCons' env loc c1 c2 = if isUnitCon env c1 andalso isUnitCon env c2 then () else @@ -896,11 +895,11 @@ val c1 = hnormCon env c1 val c2 = hnormCon env c2 in - unifyCons'' env c1 c2 - handle ex => guessMap env (c1, c2, ex) + unifyCons'' env loc c1 c2 + handle ex => guessMap env loc (c1, c2, ex) end - and unifyCons'' env (c1All as (c1, loc)) (c2All as (c2, _)) = + and unifyCons'' env loc (c1All as (c1, _)) (c2All as (c2, _)) = let fun err f = raise CUnify' (f (c1All, c2All)) @@ -912,7 +911,7 @@ let fun tryNormal () = if n1 = n2 then - unifyCons' env c1 c2 + unifyCons' env loc c1 c2 else onFail () in @@ -925,7 +924,7 @@ val us = map (fn k => cunif (loc, k)) ks in r := SOME (L'.CTuple us, loc); - unifyCons' env c1All (List.nth (us, n2 - 1)) + unifyCons' env loc c1All (List.nth (us, n2 - 1)) end | _ => tryNormal ()) | _ => tryNormal () @@ -941,7 +940,7 @@ val us = map (fn k => cunif (loc, k)) ks in r := SOME (L'.CTuple us, loc); - unifyCons' env (List.nth (us, n1 - 1)) c2All + unifyCons' env loc (List.nth (us, n1 - 1)) c2All end | _ => trySnd ()) | _ => trySnd () @@ -957,7 +956,7 @@ val us = map (fn k => cunif (loc, k)) ks in r := SOME (L'.CTuple us, loc); - unifyCons' env c1All (List.nth (us, n2 - 1)) + unifyCons' env loc c1All (List.nth (us, n2 - 1)) end | _ => onFail ()) | _ => onFail () @@ -1003,8 +1002,8 @@ | (L'.CUnit, L'.CUnit) => () | (L'.TFun (d1, r1), L'.TFun (d2, r2)) => - (unifyCons' env d1 d2; - unifyCons' env r1 r2) + (unifyCons' env loc d1 d2; + unifyCons' env loc r1 r2) | (L'.TCFun (expl1, x1, d1, r1), L'.TCFun (expl2, _, d2, r2)) => if expl1 <> expl2 then err CExplicitness @@ -1017,13 +1016,13 @@ (*TextIO.print ("E.pushCRel: " ^ LargeReal.toString (Time.toReal (Time.- (Time.now (), befor))) ^ "\n");*) - unifyCons' env' r1 r2 + unifyCons' env' loc r1 r2 end) - | (L'.TRecord r1, L'.TRecord r2) => unifyCons' env r1 r2 + | (L'.TRecord r1, L'.TRecord r2) => unifyCons' env loc r1 r2 | (L'.TDisjoint (c1, d1, e1), L'.TDisjoint (c2, d2, e2)) => - (unifyCons' env c1 c2; - unifyCons' env d1 d2; - unifyCons' env e1 e2) + (unifyCons' env loc c1 c2; + unifyCons' env loc d1 d2; + unifyCons' env loc e1 e2) | (L'.CRel n1, L'.CRel n2) => if n1 = n2 then @@ -1037,11 +1036,11 @@ err CIncompatible | (L'.CApp (d1, r1), L'.CApp (d2, r2)) => - (unifyCons' env d1 d2; - unifyCons' env r1 r2) + (unifyCons' env loc d1 d2; + unifyCons' env loc r1 r2) | (L'.CAbs (x1, k1, c1), L'.CAbs (_, k2, c2)) => (unifyKinds env k1 k2; - unifyCons' (E.pushCRel env x1 k1) c1 c2) + unifyCons' (E.pushCRel env x1 k1) loc c1 c2) | (L'.CName n1, L'.CName n2) => if n1 = n2 then @@ -1056,7 +1055,7 @@ err CIncompatible | (L'.CTuple cs1, L'.CTuple cs2) => - ((ListPair.appEq (fn (c1, c2) => unifyCons' env c1 c2) (cs1, cs2)) + ((ListPair.appEq (fn (c1, c2) => unifyCons' env loc c1 c2) (cs1, cs2)) handle ListPair.UnequalLengths => err CIncompatible) | (L'.CProj (c1, n1), _) => projSpecial1 (c1, n1, fn () => err CIncompatible) @@ -1067,28 +1066,28 @@ unifyKinds env ran1 ran2) | (L'.CKAbs (x, c1), L'.CKAbs (_, c2)) => - unifyCons' (E.pushKRel env x) c1 c2 + unifyCons' (E.pushKRel env x) loc c1 c2 | (L'.CKApp (c1, k1), L'.CKApp (c2, k2)) => (unifyKinds env k1 k2; - unifyCons' env c1 c2) + unifyCons' env loc c1 c2) | (L'.TKFun (x, c1), L'.TKFun (_, c2)) => - unifyCons' (E.pushKRel env x) c1 c2 + unifyCons' (E.pushKRel env x) loc c1 c2 | _ => err CIncompatible end - and unifyCons env c1 c2 = - unifyCons' env c1 c2 + and unifyCons env loc c1 c2 = + unifyCons' env loc c1 c2 handle CUnify' err => raise CUnify (c1, c2, err) | KUnify args => raise CUnify (c1, c2, CKind args) fun checkCon env e c1 c2 = - unifyCons env c1 c2 + unifyCons env (#2 e) c1 c2 handle CUnify (c1, c2, err) => expError env (Unify (e, c1, c2, err)) fun checkPatCon env p c1 c2 = - unifyCons env c1 c2 + unifyCons env (#2 p) c1 c2 handle CUnify (c1, c2, err) => expError env (PatUnify (p, c1, c2, err)) @@ -2653,7 +2652,7 @@ SOME env end in - (unifyCons env c1 c2; + (unifyCons env loc c1 c2; good ()) handle CUnify (c1, c2, err) => (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); @@ -2707,7 +2706,7 @@ orelse case (t1, t2) of (NONE, NONE) => false | (SOME t1, SOME t2) => - (unifyCons env t1 (sub2 t2); false) + (unifyCons env loc t1 (sub2 t2); false) | _ => true in (if xs1 <> xs2 @@ -2778,7 +2777,7 @@ SOME env end in - (unifyCons env t1 t2; + (unifyCons env loc t1 t2; good ()) handle CUnify (c1, c2, err) => (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); @@ -2799,7 +2798,7 @@ ("c1", p_con env c1), ("c2", p_con env c2), ("c2'", p_con env (sub2 c2))];*) - unifyCons env c1 (sub2 c2); + unifyCons env loc c1 (sub2 c2); SOME env) handle CUnify (c1, c2, err) => (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); @@ -2855,7 +2854,8 @@ seek (fn (env, sgi1All as (sgi1, _)) => case sgi1 of L'.SgiConstraint (c1, d1) => - if consEq env (c1, c2) andalso consEq env (d1, d2) then + if consEq env loc (c1, c2) + andalso consEq env loc (d1, d2) then SOME env else NONE @@ -2911,7 +2911,7 @@ SOME env end in - (unifyCons env c1 c2; + (unifyCons env loc c1 c2; good ()) handle CUnify (c1, c2, err) => (sgnError env (SgiWrongCon (sgi1All, c1, sgi2All, c2, err)); @@ -3819,7 +3819,7 @@ (strerror, sgnerror, [])) end -fun resolveClass env = E.resolveClass (hnormCon env) (consEq env) env +fun resolveClass env = E.resolveClass (hnormCon env) (consEq env dummy) env fun elabFile basis topStr topSgn env file = let