@@ -122,6 +122,27 @@ and paths_row ta ps = function
122122 ts1 @ ts2
123123
124124
125+ let rec_from_extyp typ label s =
126+ match s with
127+ | ExT ([] , t ) ->
128+ let rec find_rec = function
129+ | AppT (t , ts ) ->
130+ let rec_t, unroll_t, roll_t, ak = find_rec t in
131+ rec_t, AppT (unroll_t, ts), AppT (roll_t, ts), ak
132+ | RecT (ak , unroll_t ) as rec_t ->
133+ rec_t, unroll_t, rec_t, ak
134+ | DotT (t , lab ) ->
135+ let rec_t, unroll_t, roll_t, ak = find_rec t in
136+ rec_t, DotT (unroll_t, lab), DotT (roll_t, lab), ak
137+ | _ ->
138+ error typ.at (" non-recursive type for " ^ label ^ " :"
139+ ^ " " ^ Types. string_of_extyp s) in
140+ find_rec t
141+ | _ ->
142+ error typ.at (" non-recursive type for " ^ label ^ " :"
143+ ^ " " ^ Types. string_of_extyp s)
144+
145+
125146(* Instantiation *)
126147
127148let rec instantiate env t e =
@@ -386,15 +407,18 @@ Trace.debug (lazy ("[FunE] env =" ^ VarSet.fold (fun a s -> s ^ " " ^ a) (domain
386407
387408 | EL. RollE (var , typ ) ->
388409 let s, zs1 = elab_typ env typ l in
389- let t, ak, t' =
390- match s with
391- | ExT ([] , (RecT(ak , t' ) as t )) -> t, ak, t'
392- | _ -> error typ.at " non-recursive type for rolling" in
410+ let rec_t, unroll_t, roll_t, ak = rec_from_extyp typ " rolling" s in
411+ let var_t = lookup_var env var in
412+ let unroll_t = subst_typ (subst [ak] [rec_t]) unroll_t in
393413 let _, zs2, f =
394- try sub_typ env (lookup_var env var) (subst_typ (subst [ak] [t]) t') []
395- with Sub e -> error var.at (" rolled value does not match annotation" ) in
396- ExT ([] , t), Pure , zs1 @ zs2,
397- IL. RollE (IL. AppE (f, IL. VarE (var.it)), erase_typ t)
414+ try sub_typ env var_t unroll_t []
415+ with Sub e ->
416+ error var.at (" rolled value does not match annotation:"
417+ ^ " " ^ Types. string_of_typ var_t ^ " "
418+ ^ " <"
419+ ^ " " ^ Types. string_of_typ unroll_t) in
420+ ExT ([] , roll_t), Pure , zs1 @ zs2,
421+ IL. RollE (IL. AppE (f, IL. VarE (var.it)), erase_typ roll_t)
398422
399423 | EL. IfE (var , exp1 , exp2 , typ ) ->
400424 let t0, zs0, ex = elab_instvar env var in
@@ -488,13 +512,15 @@ Trace.debug (lazy ("[UnwrapE] s2 = " ^ string_of_norm_extyp s2));
488512
489513 | EL. UnrollE (var , typ ) ->
490514 let s, zs1 = elab_typ env typ l in
491- let t, ak, t' =
492- match s with
493- | ExT ([] , (RecT(ak , t' ) as t )) -> t, ak, t'
494- | _ -> error typ.at " non-recursive type for rolling" in
495- let _, zs2, f = try sub_typ env (lookup_var env var) t [] with Sub e ->
496- error var.at (" unrolled value does not match annotation" ) in
497- ExT ([] , subst_typ (subst [ak] [t]) t'), Pure , zs1 @ zs2,
515+ let rec_t, unroll_t, roll_t, ak = rec_from_extyp typ " unrolling" s in
516+ let var_t = lookup_var env var in
517+ let _, zs2, f = try sub_typ env var_t roll_t [] with Sub e ->
518+ error var.at (" unrolled value does not match annotation:"
519+ ^ " " ^ Types. string_of_typ var_t ^ " "
520+ ^ " <"
521+ ^ " " ^ Types. string_of_typ roll_t) in
522+ let unroll_t = subst_typ (subst [ak] [rec_t]) unroll_t in
523+ ExT ([] , unroll_t), Pure , zs1 @ zs2,
498524 IL. UnrollE (IL. AppE (f, IL. VarE (var.it)))
499525
500526 | EL. RecE (var , typ , exp1 ) ->
0 commit comments