diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/finite_map.ml | 17 | ||||
| -rw-r--r-- | src/pretty_print.ml | 2 | ||||
| -rw-r--r-- | src/type_check.ml | 179 | ||||
| -rw-r--r-- | src/type_internal.ml | 188 | ||||
| -rw-r--r-- | src/type_internal.mli | 6 |
5 files changed, 241 insertions, 151 deletions
diff --git a/src/finite_map.ml b/src/finite_map.ml index 6220e027..c7e427fd 100644 --- a/src/finite_map.ml +++ b/src/finite_map.ml @@ -58,8 +58,13 @@ module type Fmap = sig val insert : 'a t -> (k * 'a) -> 'a t (* Keys from the right argument replace those from the left *) val union : 'a t -> 'a t -> 'a t + (* Function merges the stored value when a key is in the right and the left map *) + val union_merge : ('a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t val intersect : 'a t -> 'a t -> 'a t + (* Function merges the stored values for shared keys *) + val intersect_merge : ('a -> 'a -> 'a) -> 'a t -> 'a t -> 'a t val big_union : 'a t list -> 'a t + val big_union_merge : ('a -> 'a -> 'a) -> 'a t list -> 'a t val merge : (k -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t val apply : 'a t -> k -> 'a option val in_dom : k -> 'a t -> bool @@ -94,6 +99,12 @@ module Fmap_map(Key : Set.OrderedType) : Fmap let insert m (k,v) = M.add k v m let union m1 m2 = M.merge (fun k v1 v2 -> match v2 with | None -> v1 | Some _ -> v2) m1 m2 + let union_merge f m1 m2 = + M.merge (fun k v1 v2 -> + match v1,v2 with + | None,None -> None + | None,Some v | Some v,None -> Some v + | Some v1, Some v2 -> Some (f v1 v2)) m1 m2 let merge f m1 m2 = M.merge f m1 m2 let apply m k = try @@ -118,6 +129,11 @@ module Fmap_map(Key : Set.OrderedType) : Fmap if (M.mem k m2) then M.add k v res else res) m1 M.empty + let intersect_merge f m1 m2 = + M.fold (fun k v res -> + match (apply m2 k) with + | None -> res + | Some v2 -> M.add k (f v v2) res) m1 M.empty let to_list m = M.fold (fun k v res -> (k,v)::res) m [] let remove m k = M.remove k m let pp_map pp_key pp_val ppf m = @@ -130,6 +146,7 @@ module Fmap_map(Key : Set.OrderedType) : Fmap pp_val v)) l let big_union l = List.fold_left union empty l + let big_union_merge f l = List.fold_left (union_merge f) empty l let domains_disjoint maps = match D.duplicates (List.concat (List.map (fun m -> List.map fst (M.bindings m)) maps)) with | D.No_dups _ -> true diff --git a/src/pretty_print.ml b/src/pretty_print.ml index 5d6e45e7..ab6e0539 100644 --- a/src/pretty_print.ml +++ b/src/pretty_print.ml @@ -565,7 +565,7 @@ and pp_format_o o = ^ " Unknown)" let pp_format_tag = function - | Emp -> "Tag_empty" + | Emp_local | Emp_global -> "Tag_empty" | External (Some s) -> "(Tag_extern (Just \""^s^"\"))" | External None -> "(Tag_extern Nothing)" | Default -> "Tag_default" diff --git a/src/type_check.ml b/src/type_check.ml index 044b17c6..dbf55a1a 100644 --- a/src/type_check.ml +++ b/src/type_check.ml @@ -155,7 +155,7 @@ let into_register d_env (t : tannot) : tannot = | _ -> Some((ids, {t= Tapp("register",[TA_typ ty'])}),tag,constraints,eft)) | None -> None -let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tannot emap) * nexp_range list * t) = +let rec check_pattern envs emp_tag expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tannot emap) * nexp_range list * t) = let (Env(d_env,t_env)) = envs in match p with | P_lit (L_aux(lit,l')) -> @@ -184,20 +184,20 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann | L_string s -> {t = Tid "string"},lit | L_undef -> typ_error l' "Cannot pattern match on undefined") in let t',cs = type_consistent l d_env t expect_t in - (P_aux(P_lit(L_aux(lit,l')),(l,Some(([],t),Emp,cs,pure_e))),Envmap.empty,[],t) + (P_aux(P_lit(L_aux(lit,l')),(l,Some(([],t),Emp_local,cs,pure_e))),Envmap.empty,[],t) | P_wild -> - (P_aux(p,(l,Some(([],expect_t),Emp,[],pure_e))),Envmap.empty,[],expect_t) + (P_aux(p,(l,Some(([],expect_t),Emp_local,[],pure_e))),Envmap.empty,[],expect_t) | P_as(pat,id) -> - let (pat',env,constraints,t) = check_pattern envs expect_t pat in - let tannot = Some(([],t),Emp,[],pure_e) in + let (pat',env,constraints,t) = check_pattern envs emp_tag expect_t pat in + let tannot = Some(([],t),emp_tag,[],pure_e) in (P_aux(P_as(pat',id),(l,tannot)),Envmap.insert env (id_to_string id,tannot),constraints,t) | P_typ(typ,pat) -> let t = typ_to_t typ in - let (pat',env,constraints,u) = check_pattern envs t pat in + let (pat',env,constraints,u) = check_pattern envs emp_tag t pat in let (t',constraint') = type_consistent l d_env u t in (*TODO: This should be a no-op now, should check*) - (P_aux(P_typ(typ,pat'),(l,Some(([],t'),Emp,[],pure_e))),env,constraints@constraint',t) + (P_aux(P_typ(typ,pat'),(l,Some(([],t'),Emp_local,[],pure_e))),env,constraints@constraint',t) | P_id id -> - let tannot = Some(([],expect_t),Emp,[],pure_e) in + let tannot = Some(([],expect_t),emp_tag,[],pure_e) in (P_aux(p,(l,tannot)),Envmap.from_list [(id_to_string id,tannot)],[],expect_t) | P_app(id,pats) -> let i = id_to_string id in @@ -215,12 +215,12 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann | [] -> let _ = type_consistent l d_env unit_t t1 in let t',constraints' = type_consistent l d_env t2 expect_t in (P_aux(P_app(id,[]),(l,Some(([],t'),Constructor,constraints,pure_e))),Envmap.empty,constraints@constraints',t') - | [p] -> let (p',env,constraints,u) = check_pattern envs t1 p in + | [p] -> let (p',env,constraints,u) = check_pattern envs emp_tag t1 p in let (t1',constraint') = type_consistent l d_env u t1 in (*TODO This should be a no-op now, should check *) let t',constraints' = type_consistent l d_env t2 expect_t in (P_aux(P_app(id,[p']),(l,Some(([],t'),Constructor,constraints,pure_e))),env,constraints@constraint'@constraints',t') | pats -> let ((P_aux(P_tup(pats'),_)),env,constraints,u) = - check_pattern envs t1 (P_aux(P_tup(pats),(l,annot))) in + check_pattern envs emp_tag t1 (P_aux(P_tup(pats),(l,annot))) in let (t1',constraint') = type_consistent l d_env u t1 in (*TODO This should be a no-op now, should check *) let t',constraints' = type_consistent l d_env t2 expect_t in (P_aux(P_app(id,pats'),(l,Some(([],t'),Constructor,constraints,pure_e))),env,constraint'@constraints@constraints',t')) @@ -234,7 +234,7 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann List.map (fun (tan,id,l,pat) -> let (Some((vs,t),tag,cs,eft)) = tan in let t,cs,_ = subst vs t cs eft in - let (pat,env,constraints,u) = check_pattern envs t pat in + let (pat,env,constraints,u) = check_pattern envs emp_tag t pat in let (t',cs') = type_consistent l d_env u t in let pat = FP_aux(FP_Fpat(id,pat),(l,Some(([],t'),tag,cs@cs',pure_e))) in (pat,env,cs@cs'@constraints)) typ_pats in @@ -244,7 +244,7 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann let constraints = List.fold_right (fun (_,_,cs) cons -> cs@cons) pat_checks [] in let t = {t=Tid id} in let t',cs' = type_consistent l d_env t expect_t in - (P_aux((P_record(pats',false)),(l,Some(([],t'),Emp,constraints@cs',pure_e))),env,constraints@cs',t')) + (P_aux((P_record(pats',false)),(l,Some(([],t'),Emp_local,constraints@cs',pure_e))),env,constraints@cs',t')) | P_vector pats -> let item_t = match expect_t.t with (*TODO check for abbrev, throw error if not a vector or tuvar*) | Tapp("vector",[b;r;o;TA_typ i]) -> i @@ -252,13 +252,13 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann let (pats',ts,t_envs,constraints) = List.fold_right (fun pat (pats,ts,t_envs,constraints) -> - let (pat',t_env,cons,t) = check_pattern envs item_t pat in + let (pat',t_env,cons,t) = check_pattern envs emp_tag item_t pat in ((pat'::pats),(t::ts),(t_env::t_envs),(cons@constraints))) pats ([],[],[],[]) in let env = List.fold_right (fun e env -> Envmap.union e env) t_envs Envmap.empty in (*Need to check for non-duplication of variables*) let (u,cs) = List.fold_right (fun u (t,cs) -> let t',cs = type_consistent l d_env u t in t',cs) ts (item_t,[]) in let t = {t = Tapp("vector",[(TA_nexp {nexp= Nconst 0});(TA_nexp {nexp= Nconst (List.length ts)});(TA_ord{order=Oinc});(TA_typ u)])} in - (P_aux(P_vector(pats'),(l,Some(([],t),Emp,cs,pure_e))), env,cs@constraints,t) + (P_aux(P_vector(pats'),(l,Some(([],t),Emp_local,cs,pure_e))), env,cs@constraints,t) | P_vector_indexed(ipats) -> let item_t = match expect_t.t with | Tapp("vector",[b;r;o;TA_typ i]) -> i @@ -281,7 +281,7 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann let (pats',ts,t_envs,constraints) = List.fold_right (fun (i,pat) (pats,ts,t_envs,constraints) -> - let (pat',env,cons,t) = check_pattern envs item_t pat in + let (pat',env,cons,t) = check_pattern envs emp_tag item_t pat in (((i,pat')::pats),(t::ts),(env::t_envs),(cons@constraints))) ipats ([],[],[],[]) in let env = List.fold_right (fun e env -> Envmap.union e env) t_envs Envmap.empty in (*Need to check for non-duplication of variables*) @@ -293,7 +293,7 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann GtEq(l,rise, {nexp = Nconst (lst-fst)});]@cs else [GtEq(l,base, {nexp = Nconst fst}); LtEq(l,rise, { nexp = Nconst (fst -lst)});]@cs in - (P_aux(P_vector_indexed(pats'),(l,Some(([],t),Emp,cs,pure_e))), env,constraints@cs,t) + (P_aux(P_vector_indexed(pats'),(l,Some(([],t),Emp_local,cs,pure_e))), env,constraints@cs,t) | P_tup(pats) -> let item_ts = match expect_t.t with | Ttup ts -> @@ -304,17 +304,17 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann let (pats',ts,t_envs,constraints) = List.fold_right (fun (pat,t) (pats,ts,t_envs,constraints) -> - let (pat',env,cons,t) = check_pattern envs t pat in + let (pat',env,cons,t) = check_pattern envs emp_tag t pat in ((pat'::pats),(t::ts),(env::t_envs),cons@constraints)) (List.combine pats item_ts) ([],[],[],[]) in let env = List.fold_right (fun e env -> Envmap.union e env) t_envs Envmap.empty in (*Need to check for non-duplication of variables*) let t = {t = Ttup ts} in - (P_aux(P_tup(pats'),(l,Some(([],t),Emp,[],pure_e))), env,constraints,t) + (P_aux(P_tup(pats'),(l,Some(([],t),Emp_local,[],pure_e))), env,constraints,t) | P_vector_concat pats -> let (pats',ts,envs,constraints) = List.fold_right (fun pat (pats,ts,t_envs,constraints) -> - let (pat',env,cons,t) = check_pattern envs expect_t pat in + let (pat',env,cons,t) = check_pattern envs emp_tag expect_t pat in (pat'::pats,t::ts,env::t_envs,cons@constraints)) pats ([],[],[],[]) in let env = List.fold_right (fun e env -> Envmap.union e env) envs Envmap.empty in (*Need to check for non-duplication of variables*) @@ -335,7 +335,7 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann | Tapp("vector",[(TA_nexp b);(TA_nexp r);(TA_ord o);(TA_typ u)]) -> {nexp = Nadd(r,rn)} | _ -> raise (Reporting_basic.err_unreachable l "vector concat pattern impossibility") ) (List.tl ts) r1 in let cs = [Eq(l,base,base_c);Eq(l,rise,range_c)]@(List.flatten cs) in - (P_aux(P_vector_concat(pats'),(l,Some(([],t),Emp,cs,pure_e))), env,constraints@cs,t) + (P_aux(P_vector_concat(pats'),(l,Some(([],t),Emp_local,cs,pure_e))), env,constraints@cs,t) | P_list(pats) -> let item_t = match expect_t.t with | Tapp("list",[TA_typ i]) -> i @@ -343,13 +343,13 @@ let rec check_pattern envs expect_t (P_aux(p,(l,annot))) : ((tannot pat) * (tann let (pats',ts,envs,constraints) = List.fold_right (fun pat (pats,ts,t_envs,constraints) -> - let (pat',env,cons,t) = check_pattern envs item_t pat in + let (pat',env,cons,t) = check_pattern envs emp_tag item_t pat in (pat'::pats,t::ts,env::t_envs,cons@constraints)) pats ([],[],[],[]) in let env = List.fold_right (fun e env -> Envmap.union e env) envs Envmap.empty in (*Need to check for non-duplication of variables*) let u,cs = List.fold_right (fun u (t,cs) -> let t',cs' = type_consistent l d_env u t in t',cs@cs') ts (item_t,[]) in let t = {t = Tapp("list",[TA_typ u])} in - (P_aux(P_list(pats'),(l,Some(([],t),Emp,cs,pure_e))), env,constraints@cs,t) + (P_aux(P_list(pats'),(l,Some(([],t),Emp_local,cs,pure_e))), env,constraints@cs,t) let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp * t * tannot emap * nexp_range list * effect) = let Env(d_env,t_env) = envs in @@ -377,7 +377,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp | Some(Some(tp,Default,cs,ef)) | Some(Some(tp,Spec,cs,ef)) -> typ_error l ("Identifier " ^ i ^ " must be defined, not just specified, before use") | Some(Some((params,t),tag,cs,ef)) -> - let t,cs,ef = subst params t cs ef in + let t,cs,ef = match tag with | Emp_global | External _ -> subst params t cs ef | _ -> t,cs,ef in let t,cs',ef' = get_abbrev d_env t in let cs,ef = cs@cs',union_effects ef ef' in let t_actual,expect_actual = match t.t,expect_t.t with @@ -388,7 +388,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp (match t_actual.t,expect_actual.t with | Tfn _,_ -> typ_error l ("Identifier " ^ (id_to_string id) ^ " is bound to a function and cannot be used as a value") | Tapp("register",[TA_typ(t')]),Tapp("register",[TA_typ(expect_t')]) -> - let tannot = Some(([],t),Emp,cs,ef) in + let tannot = Some(([],t),Emp_local,cs,ef) in let t',cs',e' = type_coerce l d_env t' (rebuild tannot) expect_t' in (e',t,t_env,cs@cs',ef) | Tapp("register",[TA_typ(t')]),_ -> @@ -397,7 +397,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp let t',cs',e' = type_coerce l d_env t' (rebuild tannot) expect_actual in (e',t,t_env,cs@cs',ef) | Tapp("reg",[TA_typ(t')]),_ -> - let tannot = Some(([],t),Emp,cs,pure_e) in + let tannot = Some(([],t),Emp_local,cs,pure_e) in let t',cs',e' = type_coerce l d_env t' (rebuild tannot) expect_actual in (e',t',t_env,cs@cs',pure_e) | _ -> @@ -443,7 +443,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp | L_string s -> {t = Tid "string"},lit,pure_e | L_undef -> new_t (),lit,{effect=Eset[BE_aux(BE_undef,l)]}) in let t',cs',e' = - type_coerce l d_env t (E_aux(E_lit(L_aux(lit',l')),(l,(Some(([],t),Emp,[],effect))))) expect_t in + type_coerce l d_env t (E_aux(E_lit(L_aux(lit',l')),(l,(Some(([],t),Emp_local,[],effect))))) expect_t in (e',t',t_env,cs',effect) | E_cast(typ,e) -> let t = typ_to_t typ in @@ -504,7 +504,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp let (e',t',_,c,ef) = check_exp envs t e in ((e'::exps),(t'::typs),c@consts,union_effects ef effect)) exps ts ([],[],[],pure_e) in let t = {t = Ttup typs} in - (E_aux(E_tuple(exps),(l,Some(([],t),Emp,[],pure_e))),t,t_env,consts,effect) + (E_aux(E_tuple(exps),(l,Some(([],t),Emp_local,[],pure_e))),t,t_env,consts,effect) else typ_error l ("Expected a tuple with length " ^ (string_of_int tl) ^ " found one of length " ^ (string_of_int el)) | _ -> let exps,typs,consts,effect = @@ -513,14 +513,14 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp let (e',t,_,c,ef) = check_exp envs (new_t ()) e in ((e'::exps),(t::typs),c@consts,union_effects ef effect)) exps ([],[],[],pure_e) in let t = { t=Ttup typs } in - let t',cs',e' = type_coerce l d_env t (E_aux(E_tuple(exps),(l,Some(([],t),Emp,[],pure_e)))) expect_t in + let t',cs',e' = type_coerce l d_env t (E_aux(E_tuple(exps),(l,Some(([],t),Emp_local,[],pure_e)))) expect_t in (e',t',t_env,consts@cs',effect)) | E_if(cond,then_,else_) -> let (cond',_,_,c1,ef1) = check_exp envs bool_t cond in let then',then_t,then_env,then_c,then_ef = check_exp envs expect_t then_ in let else',else_t,else_env,else_c,else_ef = check_exp envs expect_t else_ in - (E_aux(E_if(cond',then',else'),(l,Some(([],expect_t),Emp,[],pure_e))), - expect_t,Envmap.intersect then_env else_env,then_c@else_c@c1, + (E_aux(E_if(cond',then',else'),(l,Some(([],expect_t),Emp_local,[],pure_e))), + expect_t,Envmap.intersect_merge (tannot_merge l d_env) then_env else_env,then_c@else_c@c1, union_effects ef1 (union_effects then_ef else_ef)) | E_for(id,from,to_,step,order,block) -> let fb,fr,tb,tr,sb,sr = new_n(),new_n(),new_n(),new_n(),new_n(),new_n() in @@ -532,15 +532,15 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp let new_annot,local_cs = match (aorder_to_ord order).order with | Oinc -> - (Some(([],{t=Tapp("enum",[TA_nexp fb;TA_nexp {nexp=Nadd(tb,tr)}])}),Emp,[],pure_e), + (Some(([],{t=Tapp("enum",[TA_nexp fb;TA_nexp {nexp=Nadd(tb,tr)}])}),Emp_local,[],pure_e), [LtEq(l,{nexp=Nadd(fb,fr)},{nexp=Nadd(tb,tr)});LtEq(l,fb,tb)]) | Odec -> - (Some(([],{t=Tapp("enum",[TA_nexp tb; TA_nexp {nexp=Nadd(fb,fr)}])}),Emp,[],pure_e), + (Some(([],{t=Tapp("enum",[TA_nexp tb; TA_nexp {nexp=Nadd(fb,fr)}])}),Emp_local,[],pure_e), [GtEq(l,{nexp=Nadd(fb,fr)},{nexp=Nadd(tb,tr)});GtEq(l,fb,tb)]) | _ -> (typ_error l "Order specification in a foreach loop must be either inc or dec, not polymorphic") in let (block',b_t,_,b_c,b_ef) = check_exp (Env(d_env,Envmap.insert t_env (id_to_string id,new_annot))) expect_t block in - (E_aux(E_for(id,from',to_',step',order,block'),(l,Some(([],b_t),Emp,local_cs,pure_e))),expect_t,Envmap.empty, + (E_aux(E_for(id,from',to_',step',order,block'),(l,Some(([],b_t),Emp_local,local_cs,pure_e))),expect_t,Envmap.empty, b_c@from_c@to_c@step_c@local_cs,(union_effects b_ef (union_effects step_ef (union_effects to_ef from_ef)))) | E_vector(es) -> let item_t = match expect_t.t with @@ -551,7 +551,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp (fun (e,_,_,c,ef) (es,cs,effect) -> (e::es),(c@cs),union_effects ef effect) (List.map (check_exp envs item_t) es) ([],[],pure_e)) in let t = {t = Tapp("vector",[TA_nexp({nexp=Nconst 0});TA_nexp({nexp=Nconst (List.length es)});TA_ord({order=Oinc});TA_typ item_t])} in - let t',cs',e' = type_coerce l d_env t (E_aux(E_vector es,(l,Some(([],t),Emp,[],pure_e)))) expect_t in + let t',cs',e' = type_coerce l d_env t (E_aux(E_vector es,(l,Some(([],t),Emp_local,[],pure_e)))) expect_t in (e',t',t_env,cs@cs',effect) | E_vector_indexed eis -> let item_t = match expect_t.t with @@ -571,7 +571,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp eis) ([],[],pure_e,first)) in let t = {t = Tapp("vector",[TA_nexp({nexp=Nconst first});TA_nexp({nexp=Nconst (List.length eis)}); TA_ord({order= if is_increasing then Oinc else Odec});TA_typ item_t])} in - let t',cs',e' = type_coerce l d_env t (E_aux(E_vector_indexed es,(l,Some(([],t),Emp,[],pure_e)))) expect_t in + let t',cs',e' = type_coerce l d_env t (E_aux(E_vector_indexed es,(l,Some(([],t),Emp_local,[],pure_e)))) expect_t in (e',t',t_env,cs@cs',effect) | E_vector_access(vec,i) -> let base,rise,ord = new_n(),new_n(),new_o() in @@ -589,7 +589,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp [GtEq(l,base,min); LtEq(l,{nexp=Nadd(min,m_rise)},{nexp=Nadd(base,{nexp=Nneg rise})})] | _ -> typ_error l "A vector must be either increasing or decreasing to access a single element" in - let t',cs',e' = type_coerce l d_env item_t (E_aux(E_vector_access(vec',i'),(l,Some(([],item_t),Emp,[],pure_e)))) expect_t in + let t',cs',e'=type_coerce l d_env item_t (E_aux(E_vector_access(vec',i'),(l,Some(([],item_t),Emp_local,[],pure_e)))) expect_t in (e',t',t_env,cs_loc@cs_i@cs@cs',union_effects ef ef_i) | E_vector_subrange(vec,i1,i2) -> let base,rise,ord = new_n(),new_n(),new_o() in @@ -619,7 +619,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp | _ -> typ_error l "A vector must be either increasing or decreasing to access a slice" in let nt = {t=Tapp("vector",[TA_nexp base_n;TA_nexp rise_n; TA_ord ord;TA_typ item_t])} in let (t,cs3,e') = - type_coerce l d_env nt (E_aux(E_vector_subrange(vec',i1',i2'),(l,Some(([],nt),Emp,cs_loc,pure_e)))) expect_t in + type_coerce l d_env nt (E_aux(E_vector_subrange(vec',i1',i2'),(l,Some(([],nt),Emp_local,cs_loc,pure_e)))) expect_t in (e',t,t_env,cs3@cs@cs_i1@cs_i2@cs_loc,(union_effects ef (union_effects ef_i1 ef_i2))) | E_vector_update(vec,i,e) -> let base,rise,ord = new_n(),new_n(),new_o() in @@ -642,7 +642,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp in let nt = {t=Tapp("vector",[TA_nexp base;TA_nexp rise; TA_ord ord;TA_typ item_t])} in let (t,cs3,e') = - type_coerce l d_env nt (E_aux(E_vector_update(vec',i',e'),(l,Some(([],nt),Emp,cs_loc,pure_e)))) expect_t in + type_coerce l d_env nt (E_aux(E_vector_update(vec',i',e'),(l,Some(([],nt),Emp_local,cs_loc,pure_e)))) expect_t in (e',t,t_env,cs3@cs@cs_i@cs_e@cs_loc,(union_effects ef (union_effects ef_i ef_e))) | E_vector_update_subrange(vec,i1,i2,e) -> let base,rise,ord = new_n(),new_n(),new_o() in @@ -676,7 +676,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp | _ -> typ_error l "A vector must be either increasing or decreasing to modify a slice" in let nt = {t=Tapp("vector",[TA_nexp base;TA_nexp rise; TA_ord ord;TA_typ item_t])} in let (t,cs3,e') = - type_coerce l d_env nt (E_aux(E_vector_update_subrange(vec',i1',i2',e'),(l,Some(([],nt),Emp,cs_loc,pure_e)))) expect_t in + type_coerce l d_env nt (E_aux(E_vector_update_subrange(vec',i1',i2',e'),(l,Some(([],nt),Emp_local,cs_loc,pure_e)))) expect_t in (e',t,t_env,cs3@cs@cs_i1@cs_i2@cs_loc@cs_e,(union_effects ef (union_effects ef_i1 (union_effects ef_i2 ef_e)))) | E_list(es) -> let item_t = match expect_t.t with @@ -686,7 +686,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp (List.fold_right (fun (e,_,_,c,ef) (es,cs,effect) -> (e::es),(c@cs),union_effects ef effect) (List.map (check_exp envs item_t) es) ([],[],pure_e)) in let t = {t = Tapp("list",[TA_typ item_t])} in - let t',cs',e' = type_coerce l d_env t (E_aux(E_list es,(l,Some(([],t),Emp,[],pure_e)))) expect_t in + let t',cs',e' = type_coerce l d_env t (E_aux(E_list es,(l,Some(([],t),Emp_local,[],pure_e)))) expect_t in (e',t',t_env,cs@cs',effect) | E_cons(ls,i) -> let item_t = match expect_t.t with @@ -695,7 +695,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp let lt = {t=Tapp("list",[TA_typ item_t])} in let (ls',t',_,cs,ef) = check_exp envs lt ls in let (i', ti, _,cs_i,ef_i) = check_exp envs item_t i in - let (t',cs',e') = type_coerce l d_env lt (E_aux(E_cons(ls',i'),(l,Some(([],lt),Emp,[],pure_e)))) expect_t in + let (t',cs',e') = type_coerce l d_env lt (E_aux(E_cons(ls',i'),(l,Some(([],lt),Emp_local,[],pure_e)))) expect_t in (e',t',t_env,cs@cs'@cs_i,(union_effects ef ef_i)) | E_record(FES_aux(FES_Fexps(fexps,_),l')) -> let u,_,_ = get_abbrev d_env expect_t in @@ -718,7 +718,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp let (e,t',_,c,ef) = check_exp envs et exp in (FE_aux(FE_Fexp(id,e),(l,Some(([],t'),tag,cs@c,ef)))::fexps,cons@cs@c,union_effects ef ef')) fexps ([],[],pure_e) in - E_aux(E_record(FES_aux(FES_Fexps(fexps,false),l')),(l,Some(([],u),Emp,[],pure_e))),expect_t,t_env,cons,ef + E_aux(E_record(FES_aux(FES_Fexps(fexps,false),l')),(l,Some(([],u),Emp_local,[],pure_e))),expect_t,t_env,cons,ef else typ_error l ("Expected a struct of type " ^ n ^ ", which should have " ^ string_of_int (List.length fields) ^ " fields") | Some(i,Register,fields) -> typ_error l ("Expected a value with register type, found a struct")) | Tuvar _ -> @@ -738,7 +738,7 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp (FE_aux(FE_Fexp(id,e),(l,Some(([],t'),tag,cs@c,ef)))::fexps,cons@cs@c,union_effects ef ef')) fexps ([],[],pure_e) in expect_t.t <- Tid i; - E_aux(E_record(FES_aux(FES_Fexps(fexps,false),l')),(l,Some(([],expect_t),Emp,[],pure_e))),expect_t,t_env,cons,ef + E_aux(E_record(FES_aux(FES_Fexps(fexps,false),l')),(l,Some(([],expect_t),Emp_local,[],pure_e))),expect_t,t_env,cons,ef | Some(i,Register,fields) -> typ_error l "Expected a value with register type, found a struct") | _ -> typ_error l ("Expected an expression of type " ^ t_to_string expect_t ^ " but found a struct")) | E_record_update(exp,FES_aux(FES_Fexps(fexps,_),l')) -> @@ -763,7 +763,8 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp let (e,t',_,c,ef) = check_exp envs et exp in (FE_aux(FE_Fexp(id,e),(l,Some(([],t'),tag,cs@c,ef)))::fexps,cons@cs@c,union_effects ef ef')) fexps ([],[],pure_e) in - E_aux(E_record_update(e',FES_aux(FES_Fexps(fexps,false),l')),(l,Some(([],expect_t),Emp,[],pure_e))),expect_t,t_env,cons,ef + E_aux(E_record_update(e',FES_aux(FES_Fexps(fexps,false),l')), + (l,Some(([],expect_t),Emp_local,[],pure_e))),expect_t,t_env,cons,ef else typ_error l ("Expected fields from struct " ^ i ^ ", given more fields than struct includes")) | Tuvar _ -> let field_names = List.map (fun (FE_aux(FE_Fexp(id,exp),(l,annot))) -> id_to_string id) fexps in @@ -782,7 +783,8 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp (FE_aux(FE_Fexp(id,e),(l,Some(([],t'),tag,cs@c,ef)))::fexps,cons@cs@c,union_effects ef ef')) fexps ([],[],pure_e) in expect_t.t <- Tid i; - E_aux(E_record_update(e',FES_aux(FES_Fexps(fexps,false),l')),(l,Some(([],expect_t),Emp,[],pure_e))),expect_t,t_env,cons,ef + E_aux(E_record_update(e',FES_aux(FES_Fexps(fexps,false),l')), + (l,Some(([],expect_t),Emp_local,[],pure_e))),expect_t,t_env,cons,ef | [(i,Register,fields)] -> typ_error l "Expected a value with register type, found a struct" | records -> typ_error l "Multiple structs contain this set of fields, try adding a cast to disambiguate") | _ -> typ_error l ("Expected a struct to update but found an expression of type " ^ t_to_string expect_t)) @@ -833,11 +835,11 @@ let rec check_exp envs expect_t (E_aux(e,(l,annot)) : tannot exp) : (tannot exp let check_t = new_t() in let (e',t',_,cs,ef) = check_exp envs check_t exp in let (pexps',t,cs',ef') = check_cases envs check_t expect_t pexps in - (E_aux(E_case(e',pexps'),(l,Some(([],t),Emp,[],pure_e))),t,t_env,cs@cs',union_effects ef ef') + (E_aux(E_case(e',pexps'),(l,Some(([],t),Emp_local,[],pure_e))),t,t_env,cs@cs',union_effects ef ef') | E_let(lbind,body) -> - let (lb',t_env',cs,ef) = (check_lbind envs lbind) in - let (e,t,_,cs',ef') = check_exp (Env(d_env,Envmap.union t_env t_env')) expect_t body in - (E_aux(E_let(lb',e),(l,Some(([],t),Emp,[],pure_e))),t,t_env,cs@cs',union_effects ef ef') + let (lb',t_env',cs,ef) = (check_lbind envs Emp_local lbind) in + let (e,t,_,cs',ef') = check_exp (Env(d_env,Envmap.union_merge (tannot_merge l d_env) t_env t_env')) expect_t body in + (E_aux(E_let(lb',e),(l,Some(([],t),Emp_local,[],pure_e))),t,t_env,cs@cs',union_effects ef ef') | E_assign(lexp,exp) -> let (lexp',t',t_env',tag,cs,ef) = check_lexp envs true lexp in let (exp',t'',_,cs',ef') = check_exp envs t' exp in @@ -851,7 +853,7 @@ and check_block orig_envs envs expect_t exps : ((tannot exp) list * tannot * tan | [e] -> let (E_aux(e',(l,annot)),t,envs,sc,ef) = check_exp envs expect_t e in ([E_aux(e',(l,annot))],annot,orig_envs,sc,t,ef) | e::exps -> let (e',t',t_env',sc,ef') = check_exp envs unit_t e in - let (exps',annot',orig_envs,sc',t,ef) = check_block orig_envs (Env(d_env,Envmap.union t_env t_env')) expect_t exps in + let (exps',annot',orig_envs,sc',t,ef) = check_block orig_envs (Env(d_env,Envmap.union_merge (tannot_merge Parse_ast.Unknown d_env) t_env t_env')) expect_t exps in ((e'::exps'),annot',orig_envs,sc@sc',t,union_effects ef ef') and check_cases envs check_t expect_t pexps : ((tannot pexp) list * typ * nexp_range list * effect) = @@ -859,16 +861,16 @@ and check_cases envs check_t expect_t pexps : ((tannot pexp) list * typ * nexp_r match pexps with | [] -> raise (Reporting_basic.err_unreachable Parse_ast.Unknown "switch with no cases found") | [(Pat_aux(Pat_exp(pat,exp),(l,annot)))] -> - let pat',env,cs_p,u = check_pattern envs (new_t ()) pat in + let pat',env,cs_p,u = check_pattern envs Emp_local (new_t ()) pat in let t',cs_p' = type_consistent l d_env u check_t in - let (e,t,_,cs2,ef2) = check_exp (Env(d_env,Envmap.union t_env env)) expect_t exp in - [Pat_aux(Pat_exp(pat',e),(l,Some(([],t),Emp,cs_p@cs_p'@cs2,ef2)))],t,cs_p@cs_p'@cs2,ef2 + let (e,t,_,cs2,ef2) = check_exp (Env(d_env,Envmap.union_merge (tannot_merge l d_env) t_env env)) expect_t exp in + [Pat_aux(Pat_exp(pat',e),(l,Some(([],t),Emp_local,cs_p@cs_p'@cs2,ef2)))],t,cs_p@cs_p'@cs2,ef2 | ((Pat_aux(Pat_exp(pat,exp),(l,annot)))::pexps) -> - let pat',env,cs_p,u = check_pattern envs (new_t ()) pat in + let pat',env,cs_p,u = check_pattern envs Emp_local (new_t ()) pat in let t',cs_p' = type_consistent l d_env u check_t in - let (e,t,_,cs2,ef2) = check_exp (Env(d_env,Envmap.union t_env env)) expect_t exp in + let (e,t,_,cs2,ef2) = check_exp (Env(d_env,Envmap.union_merge (tannot_merge l d_env) t_env env)) expect_t exp in let (pes,t'',csl,efl) = check_cases envs check_t expect_t pexps in - ((Pat_aux(Pat_exp(pat',e),(l,(Some(([],t''),Emp,(csl@cs_p@cs_p'@cs2),(union_effects efl ef2))))))::pes, + ((Pat_aux(Pat_exp(pat',e),(l,(Some(([],t''),Emp_local,(csl@cs_p@cs_p'@cs2),(union_effects efl ef2))))))::pes, t'', csl@cs_p@cs_p'@cs2,union_effects efl ef2) @@ -881,7 +883,7 @@ and check_lexp envs is_top (LEXP_aux(lexp,(l,annot))) : (tannot lexp * typ * tan | Some(Some((parms,t),Default,_,_)) -> typ_error l ("Identifier " ^ i ^ " cannot be assigned when only a default specification exists") | Some(Some((parms,t),tag,cs,_)) -> - let t,cs,_ = subst parms t cs pure_e in + let t,cs,_ = match tag with | External _ | Emp_global -> subst parms t cs pure_e | _ -> t,cs,pure_e in let t,cs',_ = get_abbrev d_env t in let t_actual = match t.t with | Tabbrev(i,t) -> t @@ -891,20 +893,20 @@ and check_lexp envs is_top (LEXP_aux(lexp,(l,annot))) : (tannot lexp * typ * tan let ef = {effect=Eset[BE_aux(BE_wreg,l)]} in (LEXP_aux(lexp,(l,(Some(([],t),External (Some i),cs@cs',ef)))),u,Envmap.empty,External (Some i),[],ef) | Tapp("reg",[TA_typ u]),_ -> - (LEXP_aux(lexp,(l,(Some(([],t),Emp,cs@cs',pure_e)))),u,Envmap.empty,Emp,[],pure_e) + (LEXP_aux(lexp,(l,(Some(([],t),Emp_local,cs@cs',pure_e)))),u,Envmap.empty,Emp_local,[],pure_e) | Tapp("vector",_),false -> - (LEXP_aux(lexp,(l,(Some(([],t),Emp,cs@cs',pure_e)))),t,Envmap.empty,Emp,[],pure_e) + (LEXP_aux(lexp,(l,(Some(([],t),Emp_local,cs@cs',pure_e)))),t,Envmap.empty,Emp_local,[],pure_e) | _,_ -> if is_top then typ_error l ("Can only assign to identifiers with type register or reg, found identifier " ^ i ^ " with type " ^ t_to_string t) else - (LEXP_aux(lexp,(l,(Some(([],t),Emp,cs@cs',pure_e)))),t,Envmap.empty,Emp,[],pure_e) (* TODO, make sure this is a record *)) + (LEXP_aux(lexp,(l,(Some(([],t),Emp_local,cs@cs',pure_e)))),t,Envmap.empty,Emp_local,[],pure_e) (* TODO, make sure this is a record *)) | _ -> let u = new_t() in let t = {t=Tapp("reg",[TA_typ u])} in - let tannot = (Some(([],t),Emp,[],pure_e)) in - (LEXP_aux(lexp,(l,tannot)),u,Envmap.from_list [i,tannot],Emp,[],pure_e)) + let tannot = (Some(([],t),Emp_local,[],pure_e)) in + (LEXP_aux(lexp,(l,tannot)),u,Envmap.from_list [i,tannot],Emp_local,[],pure_e)) | LEXP_memory(id,exps) -> let i = id_to_string id in (match Envmap.apply t_env i with @@ -949,7 +951,7 @@ and check_lexp envs is_top (LEXP_aux(lexp,(l,annot))) : (tannot lexp * typ * tan | Some(Some((parms,t),Default,_,_)) -> typ_error l ("Identifier " ^ i ^ " cannot be assigned when only a default specification exists") | Some(Some((parms,t),tag,cs,_)) -> - let t,cs,_ = subst parms t cs pure_e in + let t,cs,_ = match tag with | External _ | Emp_global -> subst parms t cs pure_e | _ -> t,cs,pure_e in let t,cs',_ = get_abbrev d_env t in let t_actual = match t.t with | Tabbrev(_,t) -> t | _ -> t in (match t_actual.t,is_top with @@ -959,23 +961,23 @@ and check_lexp envs is_top (LEXP_aux(lexp,(l,annot))) : (tannot lexp * typ * tan (LEXP_aux(lexp,(l,(Some(([],t),External (Some i),cs,ef)))),ty,Envmap.empty,External (Some i),[],ef) | Tapp("reg",[TA_typ u]),_ -> let t',cs = type_consistent l d_env ty u in - (LEXP_aux(lexp,(l,(Some(([],t),Emp,cs,pure_e)))),ty,Envmap.empty,Emp,[],pure_e) + (LEXP_aux(lexp,(l,(Some(([],t),Emp_local,cs,pure_e)))),ty,Envmap.empty,Emp_local,[],pure_e) | Tapp("vector",_),false -> - (LEXP_aux(lexp,(l,(Some(([],t),Emp,cs,pure_e)))),ty,Envmap.empty,Emp,[],pure_e) + (LEXP_aux(lexp,(l,(Some(([],t),Emp_local,cs,pure_e)))),ty,Envmap.empty,Emp_local,[],pure_e) | Tuvar _,_ -> let u' = {t=Tapp("reg",[TA_typ ty])} in t.t <- u'.t; - (LEXP_aux(lexp,(l,(Some((([],u'),Emp,cs,pure_e))))),ty,Envmap.empty,Emp,[],pure_e) + (LEXP_aux(lexp,(l,(Some((([],u'),Emp_local,cs,pure_e))))),ty,Envmap.empty,Emp_local,[],pure_e) | _,_ -> if is_top then typ_error l ("Can only assign to identifiers with type register or reg, found identifier " ^ i ^ " with type " ^ t_to_string t) else - (LEXP_aux(lexp,(l,(Some(([],t),Emp,cs,pure_e)))),ty,Envmap.empty,Emp,[],pure_e)) (* TODO, make sure this is a record *) + (LEXP_aux(lexp,(l,(Some(([],t),Emp_local,cs,pure_e)))),ty,Envmap.empty,Emp_local,[],pure_e)) (* TODO, make sure this is a record *) | _ -> let t = {t=Tapp("reg",[TA_typ ty])} in - let tannot = (Some(([],t),Emp,[],pure_e)) in - (LEXP_aux(lexp,(l,tannot)),ty,Envmap.from_list [i,tannot],Emp,[],pure_e)) + let tannot = (Some(([],t),Emp_local,[],pure_e)) in + (LEXP_aux(lexp,(l,tannot)),ty,Envmap.from_list [i,tannot],Emp_local,[],pure_e)) | LEXP_vector(vec,acc) -> let (vec',item_t,env,tag,csi,ef) = check_lexp envs false vec in let item_t,cs',_ = get_abbrev d_env item_t in @@ -1050,15 +1052,15 @@ and check_lexp envs is_top (LEXP_aux(lexp,(l,annot))) : (tannot lexp * typ * tan (LEXP_aux(LEXP_field(vec',id),(l,(Some(([],vec_t),tag,csi@cs,ef)))),et,env,tag,csi@cs,ef))) | _ -> typ_error l ("Expected a register binding here, found " ^ (t_to_string item_t))) -and check_lbind envs (LB_aux(lbind,(l,annot))) : tannot letbind * tannot emap * nexp_range list * effect = +and check_lbind envs emp_tag (LB_aux(lbind,(l,annot))) : tannot letbind * tannot emap * nexp_range list * effect = let Env(d_env,t_env) = envs in match lbind with | LB_val_explicit(typ,pat,e) -> - let tan = typschm_to_tannot envs typ Emp in + let tan = typschm_to_tannot envs typ emp_tag in (match tan with | Some((params,t),tag,cs,ef) -> let t,cs,ef = subst params t cs ef in - let (pat',env,cs1,u) = check_pattern envs t pat in + let (pat',env,cs1,u) = check_pattern envs emp_tag t pat in let t',cs' = type_consistent l d_env u t in let (e,t,_,cs2,ef2) = check_exp envs t' e in let cs = resolve_constraints cs@cs1@cs'@cs2 in @@ -1067,10 +1069,10 @@ and check_lbind envs (LB_aux(lbind,(l,annot))) : tannot letbind * tannot emap * | None -> raise (Reporting_basic.err_unreachable l "typschm_to_tannot failed to produce a Some")) | LB_val_implicit(pat,e) -> let t = new_t () in - let (pat',env,cs1,u) = check_pattern envs (new_t ()) pat in + let (pat',env,cs1,u) = check_pattern envs emp_tag (new_t ()) pat in let (e,t',_,cs2,ef) = check_exp envs u e in let cs = resolve_constraints cs1@cs2 in - let tannot = check_tannot l (Some(([],t'),Emp,cs,ef)) cs ef (* see above *) in + let tannot = check_tannot l (Some(([],t'),emp_tag,cs,ef)) cs ef (* see above *) in (LB_aux (LB_val_implicit(pat',e),(l,tannot)), env,cs,ef) (*val check_type_def : envs -> (tannot type_def) -> (tannot type_def) envs_out*) @@ -1078,15 +1080,15 @@ let check_type_def envs (TD_aux(td,(l,annot))) = let (Env(d_env,t_env)) = envs in match td with | TD_abbrev(id,nmscm,typschm) -> - let tan = typschm_to_tannot envs typschm Emp in + let tan = typschm_to_tannot envs typschm Emp_global in (TD_aux(td,(l,tan)), Env( { d_env with abbrevs = Envmap.insert d_env.abbrevs ((id_to_string id),tan)},t_env)) | TD_record(id,nmscm,typq,fields,_) -> let id' = id_to_string id in let (params,constraints) = typq_to_params envs typq in - let tyannot = Some((params,{t=Tid id'}),Emp,constraints,pure_e) in + let tyannot = Some((params,{t=Tid id'}),Emp_global,constraints,pure_e) in let fields' = List.map - (fun (ty,i)->(id_to_string i),Some((params,(typ_to_t ty)),Emp,constraints,pure_e)) fields in + (fun (ty,i)->(id_to_string i),Some((params,(typ_to_t ty)),Emp_global,constraints,pure_e)) fields in (TD_aux(td,(l,tyannot)),Env({d_env with rec_env = (id',Record,fields')::d_env.rec_env},t_env)) | TD_variant(id,nmscm,typq,arms,_) -> let id' = id_to_string id in @@ -1134,10 +1136,10 @@ let check_type_def envs (TD_aux(td,(l,annot))) = then {t=Tapp("vector",[TA_nexp {nexp=Nconst i1}; TA_nexp {nexp=Nconst (i2 - i1)}; TA_ord({order=Oinc}); TA_typ {t=Tid "bit"}])} else typ_error l ("register type declaration " ^ id' ^ " contains a field specification outside of the declared register size") else typ_error l ("register type declaration " ^ id' ^ " is not consistently increasing") - | BF_concat _ -> assert false (* What is this supposed to imply again?*)),Emp,[],pure_e))) + | BF_concat _ -> assert false (* What is this supposed to imply again?*)),Emp_global,[],pure_e))) ranges in - let tannot = into_register d_env (Some(([],ty),Emp,[],pure_e)) in + let tannot = into_register d_env (Some(([],ty),Emp_global,[],pure_e)) in (TD_aux(td,(l,tannot)), Env({d_env with rec_env = ((id',Register,franges)::d_env.rec_env); abbrevs = Envmap.insert d_env.abbrevs (id',tannot)},t_env))) @@ -1161,10 +1163,10 @@ let check_type_def envs (TD_aux(td,(l,annot))) = else typ_error l ("register type declaration " ^ id' ^ " is not consistently decreasing") | BF_concat _ -> assert false (* What is this supposed to imply again?*) in ((id_to_string id), - Some(([],{t=Tapp("vector",[TA_nexp base;TA_nexp climb;TA_ord({order=Odec});TA_typ({t= Tid "bit"})])}),Emp,[],pure_e))) + Some(([],{t=Tapp("vector",[TA_nexp base;TA_nexp climb;TA_ord({order=Odec});TA_typ({t= Tid "bit"})])}),Emp_global,[],pure_e))) ranges in - let tannot = into_register d_env (Some(([],ty),Emp,[],pure_e)) in + let tannot = into_register d_env (Some(([],ty),Emp_global,[],pure_e)) in (TD_aux(td,(l,tannot)), Env({d_env with rec_env = (id',Register,franges)::d_env.rec_env; abbrevs = Envmap.insert d_env.abbrevs (id',tannot)},t_env))) @@ -1212,23 +1214,24 @@ let check_fundef envs (FD_aux(FD_function(recopt,tannotopt,effectopt,funcls),(l, | Typ_annot_opt_aux(Typ_annot_opt_some(typq,typ),l') -> let (ids,constraints) = typq_to_params envs typq in let t = typ_to_t typ in + let t,constraints,_ = subst ids t constraints pure_e in let p_t = new_t () in let ef = new_e () in - t,p_t,Some((ids,{t=Tfn(p_t,t,ef)}),Emp,constraints,ef) in + t,p_t,Some((ids,{t=Tfn(p_t,t,ef)}),Emp_global,constraints,ef) in let check t_env = List.split (List.map (fun (FCL_aux((FCL_Funcl(id,pat,exp)),(l,annot))) -> - let (pat',t_env',constraints',t') = check_pattern (Env(d_env,t_env)) param_t pat in + let (pat',t_env',constraints',t') = check_pattern (Env(d_env,t_env)) Emp_local param_t pat in (*let _ = Printf.printf "about to check that %s and %s are consistent\n" (t_to_string t') (t_to_string param_t) in*) let u,cs = type_consistent l d_env t' param_t in - let exp',_,_,constraints,ef = check_exp (Env(d_env,Envmap.union t_env t_env')) ret_t exp in - (*let _ = Printf.printf "checked function %s : %s,%s -> %s\n" (id_to_string id) (t_to_string t') (t_to_string param_t) (t_to_string ret_t) in *) + let exp',_,_,constraints,ef = check_exp (Env(d_env,Envmap.union_merge (tannot_merge l d_env) t_env t_env')) ret_t exp in + (*let _ = Printf.printf "checked function %s : %s -> %s\n" (id_to_string id) (t_to_string param_t) (t_to_string ret_t) in*) (*let _ = (Pretty_print.pp_exp Format.std_formatter) exp' in*) (FCL_aux((FCL_Funcl(id,pat',exp')),(l,tannot)),((constraints'@cs@constraints),ef))) funcls) in match (in_env,tannot) with - | Some(Some( (params,u),Spec,constraints,eft)), Some( (p',t),Emp,c',eft') -> + | Some(Some( (params,u),Spec,constraints,eft)), Some( (p',t),_,c',eft') -> + (*let _ = Printf.printf "Function %s is in env\n" id in*) let u,constraints,eft = subst params u constraints eft in - let t,c',eft' = subst p' t c' eft' in let t',cs = type_consistent l d_env t u in let t_env = if is_rec then t_env else Envmap.remove t_env id in let funcls,cs_ef = check t_env in @@ -1254,7 +1257,7 @@ let check_def envs (DEF_aux(def,(l,annot))) = (DEF_aux((DEF_type td),(l,annot)),envs) | DEF_fundef fdef -> let fd,envs = check_fundef envs fdef in (DEF_aux(DEF_fundef(fd),(l,annot)),envs) - | DEF_val letdef -> let (letbind,t_env_let,_,eft) = check_lbind envs letdef in + | DEF_val letdef -> let (letbind,t_env_let,_,eft) = check_lbind envs Emp_global letdef in (DEF_aux(DEF_val letbind,(l,annot)),Env(d_env,Envmap.union t_env t_env_let)) | DEF_spec spec -> let vs,envs = check_val_spec envs spec in (DEF_aux(DEF_spec(vs),(l,annot)),envs) diff --git a/src/type_internal.ml b/src/type_internal.ml index 7d613f3b..e2af4970 100644 --- a/src/type_internal.ml +++ b/src/type_internal.ml @@ -59,7 +59,8 @@ and t_arg = | TA_ord of order type tag = - | Emp + | Emp_local + | Emp_global | External of string option | Default | Constructor @@ -131,7 +132,8 @@ and o_to_string o = | Ouvar({oindex=i;osubst=a}) -> string_of_int i ^ "()" let tag_to_string = function - | Emp -> "Emp" + | Emp_local -> "Emp_local" + | Emp_global -> "Emp_global" | External None -> "External" | External (Some s) -> "External " ^ s | Default -> "Default" @@ -260,7 +262,9 @@ let new_e _ = { effect = Euvar { eindex = i; esubst = None }} exception Occurs_exn of t_arg -let rec resolve_tsubst (t : t) : t = match t.t with +let rec resolve_tsubst (t : t) : t = + (*let _ = Printf.printf "resolve_tsubst on %s\n" (t_to_string t) in*) + match t.t with | Tuvar({ subst=Some(t') } as u) -> let t'' = resolve_tsubst t' in (match t''.t with @@ -340,7 +344,8 @@ let equate_t (t_box : t) (t : t) : unit = | Tuvar(_) -> (match t_box.t with | Tuvar(u) -> - u.subst <- Some(t)) + u.subst <- Some(t) + | _ -> assert false) | _ -> t_box.t <- t.t) let equate_n (n_box : nexp) (n : nexp) : unit = @@ -352,7 +357,8 @@ let equate_n (n_box : nexp) (n : nexp) : unit = | Nuvar(_) -> (match n_box.nexp with | Nuvar(u) -> - u.nsubst <- Some(n)) + u.nsubst <- Some(n) + | _ -> assert false) | _ -> n_box.nexp <- n.nexp) let equate_o (o_box : order) (o : order) : unit = @@ -364,7 +370,8 @@ let equate_o (o_box : order) (o : order) : unit = | Ouvar(_) -> (match o_box.order with | Ouvar(u) -> - u.osubst <- Some(o)) + u.osubst <- Some(o) + | _ -> assert false) | _ -> o_box.order <- o.order) let equate_e (e_box : effect) (e : effect) : unit = @@ -376,7 +383,8 @@ let equate_e (e_box : effect) (e : effect) : unit = | Euvar(_) -> (match e_box.effect with | Euvar(u) -> - u.esubst <- Some(e)) + u.esubst <- Some(e) + | _ -> assert false) | _ -> e_box.effect <- e.effect) @@ -386,19 +394,54 @@ let rec fresh_var i mkr bindings = | Some _ -> fresh_var (i+1) mkr bindings | None -> mkr v -let fresh_tvar bindings t = +let rec fresh_tvar bindings t = match t.t with - | Tuvar { index = i } -> fresh_var i (fun v -> equate_t t {t = (Tvar v)}; (v,{k=K_Typ})) bindings -let fresh_nvar bindings n = + | Tuvar { index = i;subst = None } -> + fresh_var i (fun v -> equate_t t {t=Tvar v};Some (v,{k=K_Typ})) bindings + | Tuvar { index = i; subst = Some ({t = Tuvar _} as t') } -> + let kv = fresh_tvar bindings t' in + equate_t t t'; + kv + | Tuvar { index = i; subst = Some t' } -> + t.t <- t'.t; + None + | _ -> None +let rec fresh_nvar bindings n = match n.nexp with - | Nuvar { nindex = i } -> fresh_var i (fun v -> equate_n n {nexp = (Nvar v)}; (v,{k=K_Nat})) bindings -let fresh_ovar bindings o = + | Nuvar { nindex = i;nsubst = None } -> + fresh_var i (fun v -> equate_n n {nexp = (Nvar v)}; Some(v,{k=K_Nat})) bindings + | Nuvar { nindex = i; nsubst = Some({nexp=Nuvar _} as n')} -> + let kv = fresh_nvar bindings n' in + equate_n n n'; + kv + | Nuvar { nindex = i; nsubst = Some n' } -> + n.nexp <- n'.nexp; + None + | _ -> None +let rec fresh_ovar bindings o = match o.order with - | Ouvar { oindex = i } -> fresh_var i (fun v -> equate_o o {order = (Ovar v)}; (v,{k=K_Ord})) bindings -let fresh_evar bindings e = + | Ouvar { oindex = i;osubst = None } -> + fresh_var i (fun v -> equate_o o {order = (Ovar v)}; Some(v,{k=K_Nat})) bindings + | Ouvar { oindex = i; osubst = Some({order=Ouvar _} as o')} -> + let kv = fresh_ovar bindings o' in + equate_o o o'; + kv + | Ouvar { oindex = i; osubst = Some o' } -> + o.order <- o'.order; + None + | _ -> None +let rec fresh_evar bindings e = match e.effect with - | Euvar { eindex = i } -> fresh_var i (fun v -> equate_e e {effect = (Evar v)}; (v,{k=K_Efct})) bindings - + | Euvar { eindex = i;esubst = None } -> + fresh_var i (fun v -> equate_e e {effect = (Evar v)}; Some(v,{k=K_Nat})) bindings + | Euvar { eindex = i; esubst = Some({effect=Euvar _} as e')} -> + let kv = fresh_evar bindings e' in + equate_e e e'; + kv + | Euvar { eindex = i; esubst = Some e' } -> + e.effect <- e'.effect; + None + | _ -> None let nat_t = {t = Tapp("enum",[TA_nexp{nexp= Nconst 0};TA_nexp{nexp = Nconst max_int};])} let unit_t = { t = Tid "unit" } @@ -452,15 +495,17 @@ let initial_typ_env = let initial_abbrev_env = Envmap.from_list [ - ("nat",Some(([],nat_t),Emp,[],pure_e)); + ("nat",Some(([],nat_t),Emp_global,[],pure_e)); ] let rec t_subst s_env t = + (*let _ = Printf.printf "Calling t_subst on %s\n" (t_to_string t) in*) match t.t with | Tvar i -> (match Envmap.apply s_env i with | Some(TA_typ t1) -> t1 | _ -> t) - | Tuvar _ | Tid _ -> t + | Tuvar _ -> new_t() + | Tid _ -> t | Tfn(t1,t2,e) -> {t =Tfn((t_subst s_env t1),(t_subst s_env t2),(e_subst s_env e)) } | Ttup(ts) -> { t= Ttup(List.map (t_subst s_env) ts) } | Tapp(i,args) -> {t= Tapp(i,List.map (ta_subst s_env) args)} @@ -476,7 +521,8 @@ and n_subst s_env n = | Nvar i -> (match Envmap.apply s_env i with | Some(TA_nexp n1) -> n1 | _ -> n) - | Nuvar _ | Nconst _ -> n + | Nuvar _ -> new_n() + | Nconst _ -> n | N2n n1 -> { nexp = N2n (n_subst s_env n1) } | Nneg n1 -> { nexp = Nneg (n_subst s_env n1) } | Nadd(n1,n2) -> { nexp = Nadd(n_subst s_env n1,n_subst s_env n2) } @@ -486,12 +532,14 @@ and o_subst s_env o = | Ovar i -> (match Envmap.apply s_env i with | Some(TA_ord o1) -> o1 | _ -> o) + | Ouvar _ -> new_o () | _ -> o and e_subst s_env e = match e.effect with | Evar i -> (match Envmap.apply s_env i with | Some(TA_eft e1) -> e1 | _ -> e) + | Euvar _ -> new_e () | _ -> e let rec cs_subst t_env cs = @@ -518,7 +566,9 @@ let subst k_env t cs e = let rec t_remove_unifications s_env t = match t.t with | Tvar _ | Tid _-> s_env - | Tuvar _ -> Envmap.insert s_env (fresh_tvar s_env t) + | Tuvar _ -> (match fresh_tvar s_env t with + | Some ks -> Envmap.insert s_env ks + | None -> s_env) | Tfn(t1,t2,e) -> e_remove_unifications (t_remove_unifications (t_remove_unifications s_env t1) t2) e | Ttup(ts) -> List.fold_right (fun t s_env -> t_remove_unifications s_env t) ts s_env | Tapp(i,args) -> List.fold_right (fun t s_env -> ta_remove_unifications s_env t) args s_env @@ -532,16 +582,22 @@ and ta_remove_unifications s_env ta = and n_remove_unifications s_env n = match n.nexp with | Nvar _ | Nconst _-> s_env - | Nuvar _ -> Envmap.insert s_env (fresh_nvar s_env n) + | Nuvar _ -> (match fresh_nvar s_env n with + | Some ks -> Envmap.insert s_env ks + | None -> s_env) | N2n n1 | Nneg n1 -> (n_remove_unifications s_env n1) | Nadd(n1,n2) | Nmult(n1,n2) -> (n_remove_unifications (n_remove_unifications s_env n1) n2) and o_remove_unifications s_env o = match o.order with - | Ouvar _ -> Envmap.insert s_env (fresh_ovar s_env o) + | Ouvar _ -> (match fresh_ovar s_env o with + | Some ks -> Envmap.insert s_env ks + | None -> s_env) | _ -> s_env and e_remove_unifications s_env e = match e.effect with - | Euvar _ -> Envmap.insert s_env (fresh_evar s_env e) + | Euvar _ -> (match fresh_evar s_env e with + | Some ks -> Envmap.insert s_env ks + | None -> s_env) | _ -> s_env let rec cs_subst t_env cs = @@ -567,13 +623,14 @@ let subst k_env t cs e = let rec t_to_typ t = - Typ_aux ( - (match t.t with - | Tid i -> Typ_id (Id_aux((Id i), Parse_ast.Unknown)) - | Tvar i -> Typ_var (Kid_aux((Var i),Parse_ast.Unknown)) - | Tfn(t1,t2,e) -> Typ_fn (t_to_typ t1, t_to_typ t2, e_to_ef e) - | Ttup ts -> Typ_tup(List.map t_to_typ ts) - | Tapp(i,args) -> Typ_app(Id_aux((Id i), Parse_ast.Unknown),List.map targ_to_typ_arg args)), Parse_ast.Unknown) + match t.t with + | Tid i -> Typ_aux(Typ_id (Id_aux((Id i), Parse_ast.Unknown)),Parse_ast.Unknown) + | Tvar i -> Typ_aux(Typ_var (Kid_aux((Var i),Parse_ast.Unknown)),Parse_ast.Unknown) + | Tfn(t1,t2,e) -> Typ_aux(Typ_fn (t_to_typ t1, t_to_typ t2, e_to_ef e),Parse_ast.Unknown) + | Ttup ts -> Typ_aux(Typ_tup(List.map t_to_typ ts),Parse_ast.Unknown) + | Tapp(i,args) -> Typ_aux(Typ_app(Id_aux((Id i), Parse_ast.Unknown),List.map targ_to_typ_arg args),Parse_ast.Unknown) + | Tabbrev(t,_) -> t_to_typ t + | Tuvar _ -> assert false and targ_to_typ_arg targ = Typ_arg_aux( (match targ with @@ -589,18 +646,21 @@ and n_to_nexp n = | Nmult(n1,n2) -> Nexp_times(n_to_nexp n1,n_to_nexp n2) | Nadd(n1,n2) -> Nexp_sum(n_to_nexp n1,n_to_nexp n2) | N2n n -> Nexp_exp (n_to_nexp n) - | Nneg n -> Nexp_neg (n_to_nexp n)), Parse_ast.Unknown) + | Nneg n -> Nexp_neg (n_to_nexp n) + | Nuvar _ -> assert false), Parse_ast.Unknown) and e_to_ef ef = Effect_aux( (match ef.effect with | Evar i -> Effect_var (Kid_aux((Var i),Parse_ast.Unknown)) - | Eset effects -> Effect_set effects), Parse_ast.Unknown) + | Eset effects -> Effect_set effects + | Euvar _ -> assert false), Parse_ast.Unknown) and o_to_order o = Ord_aux( (match o.order with | Ovar i -> Ord_var (Kid_aux((Var i),Parse_ast.Unknown)) | Oinc -> Ord_inc - | Odec -> Ord_dec), Parse_ast.Unknown) + | Odec -> Ord_dec + | Ouvar _ -> assert false), Parse_ast.Unknown) let rec get_abbrev d_env t = @@ -742,18 +802,20 @@ let rec type_coerce_internal l d_env t1 cs1 e t2 cs2 = let tl1,tl2 = List.length t1s,List.length t2s in if tl1=tl2 then let ids = List.map (fun _ -> Id_aux(Id (new_id ()),l)) t1s in - let vars = List.map2 (fun i t -> E_aux(E_id(i),(l,Some(([],t),Emp,[],pure_e)))) ids t1s in + let vars = List.map2 (fun i t -> E_aux(E_id(i),(l,Some(([],t),Emp_local,[],pure_e)))) ids t1s in let (coerced_ts,cs,coerced_vars) = List.fold_right2 (fun v (t1,t2) (ts,cs,es) -> let (t',c',e') = type_coerce l d_env t1 v t2 in ((t'::ts),c'@cs,(e'::es))) vars (List.combine t1s t2s) ([],[],[]) in if vars = coerced_vars then (t2,cs,e) - else let e' = E_aux(E_case(e,[(Pat_aux(Pat_exp(P_aux(P_tup (List.map2 (fun i t -> P_aux(P_id i,(l,(Some(([],t),Emp,[],pure_e))))) ids t1s),(l,Some(([],t1),Emp,[],pure_e))), - E_aux(E_tuple coerced_vars,(l,Some(([],t2),Emp,cs,pure_e)))), - (l,Some(([],t2),Emp,[],pure_e))))]), - (l,(Some(([],t2),Emp,[],pure_e)))) in + else let e' = E_aux(E_case(e,[(Pat_aux(Pat_exp(P_aux(P_tup (List.map2 + (fun i t -> P_aux(P_id i,(l,(Some(([],t),Emp_local,[],pure_e))))) + ids t1s),(l,Some(([],t1),Emp_local,[],pure_e))), + E_aux(E_tuple coerced_vars,(l,Some(([],t2),Emp_local,cs,pure_e)))), + (l,Some(([],t2),Emp_local,[],pure_e))))]), + (l,(Some(([],t2),Emp_local,[],pure_e)))) in (t2,cs,e') - else eq_error l ("A tuple of length " ^ (string_of_int tl1) ^ " cannot be used where a tuple of length " ^ (string_of_int tl2) ^ " is expected") + else eq_error l ("Found a tuple of length " ^ (string_of_int tl1) ^ " but expected a tuple of length " ^ (string_of_int tl2)) | Tapp(id1,args1),Tapp(id2,args2) -> if id1=id2 then let t',cs' = type_consistent l d_env t1 t2 in (t',cs',e) @@ -799,37 +861,38 @@ let rec type_coerce_internal l d_env t1 cs1 e t2 cs2 = let t',cs' = type_consistent l d_env t1 t2 in (t',cs',e)) | Tid("bit"),Tapp("vector",[TA_nexp {nexp=Nconst i};TA_nexp r1;TA_ord o;TA_typ {t=Tid "bit"}]) -> let cs = [Eq(l,r1,{nexp = Nconst 1})] in - (t2,cs,E_aux(E_vector_indexed [(i,e)],(l,Some(([],t2),Emp,cs,pure_e)))) + (t2,cs,E_aux(E_vector_indexed [(i,e)],(l,Some(([],t2),Emp_local,cs,pure_e)))) | Tapp("vector",[TA_nexp ({nexp=Nconst i} as b1);TA_nexp r1;TA_ord o;TA_typ {t=Tid "bit"}]),Tid("bit") -> let cs = [Eq(l,r1,{nexp = Nconst 1})] in - (t2,cs,E_aux((E_vector_access (e,(E_aux(E_lit(L_aux(L_num i,l)),(l,Some(([],{t=Tapp("enum",[TA_nexp b1;TA_nexp {nexp=Nconst 0}])}),Emp,cs,pure_e)))))), - (l,Some(([],t2),Emp,cs,pure_e)))) + (t2,cs,E_aux((E_vector_access (e,(E_aux(E_lit(L_aux(L_num i,l)), + (l,Some(([],{t=Tapp("enum",[TA_nexp b1;TA_nexp {nexp=Nconst 0}])}),Emp_local,cs,pure_e)))))), + (l,Some(([],t2),Emp_local,cs,pure_e)))) | Tid("bit"),Tapp("enum",[TA_nexp b1;TA_nexp r1]) -> let t',cs'= type_consistent l d_env {t=Tapp("enum",[TA_nexp{nexp=Nconst 0};TA_nexp{nexp=Nconst 1}])} t2 in - (t2,cs',E_aux(E_case (e,[Pat_aux(Pat_exp(P_aux(P_lit(L_aux(L_zero,l)),(l,Some(([],t1),Emp,[],pure_e))), - E_aux(E_lit(L_aux(L_num 0,l)),(l,Some(([],t2),Emp,[],pure_e)))), - (l,Some(([],t2),Emp,[],pure_e))); - Pat_aux(Pat_exp(P_aux(P_lit(L_aux(L_one,l)),(l,Some(([],t1),Emp,[],pure_e))), - E_aux(E_lit(L_aux(L_num 1,l)),(l,Some(([],t2),Emp,[],pure_e)))), - (l,Some(([],t2),Emp,[],pure_e)));]), - (l,Some(([],t2),Emp,[],pure_e)))) + (t2,cs',E_aux(E_case (e,[Pat_aux(Pat_exp(P_aux(P_lit(L_aux(L_zero,l)),(l,Some(([],t1),Emp_local,[],pure_e))), + E_aux(E_lit(L_aux(L_num 0,l)),(l,Some(([],t2),Emp_local,[],pure_e)))), + (l,Some(([],t2),Emp_local,[],pure_e))); + Pat_aux(Pat_exp(P_aux(P_lit(L_aux(L_one,l)),(l,Some(([],t1),Emp_local,[],pure_e))), + E_aux(E_lit(L_aux(L_num 1,l)),(l,Some(([],t2),Emp_local,[],pure_e)))), + (l,Some(([],t2),Emp_local,[],pure_e)));]), + (l,Some(([],t2),Emp_local,[],pure_e)))) | Tapp("enum",[TA_nexp b1;TA_nexp r1;]),Tid("bit") -> let t',cs'= type_consistent l d_env t1 {t=Tapp("enum",[TA_nexp{nexp=Nconst 0};TA_nexp{nexp=Nconst 1}])} - in (t2,cs',E_aux(E_if(E_aux(E_app(Id_aux(Id "is_zero",l),[e]),(l,Some(([],bool_t),Emp,[],pure_e))), - E_aux(E_lit(L_aux(L_zero,l)),(l,Some(([],bit_t),Emp,[],pure_e))), - E_aux(E_lit(L_aux(L_one,l)),(l,Some(([],bit_t),Emp,[],pure_e)))), - (l,Some(([],bit_t),Emp,cs',pure_e)))) + in (t2,cs',E_aux(E_if(E_aux(E_app(Id_aux(Id "is_one",l),[e]),(l,Some(([],bool_t),External None,[],pure_e))), + E_aux(E_lit(L_aux(L_one,l)),(l,Some(([],bit_t),Emp_local,[],pure_e))), + E_aux(E_lit(L_aux(L_zero,l)),(l,Some(([],bit_t),Emp_local,[],pure_e)))), + (l,Some(([],bit_t),Emp_local,cs',pure_e)))) | Tapp("enum",[TA_nexp b1;TA_nexp r1;]),Tid(i) -> (match Envmap.apply d_env.enum_env i with | Some(enums) -> (t2,[Eq(l,b1,{nexp=Nconst 0});LtEq(l,r1,{nexp=Nconst (List.length enums)})], E_aux(E_case(e, List.mapi (fun i a -> Pat_aux(Pat_exp(P_aux(P_lit(L_aux((L_num i),l)), - (l,Some(([],t1),Emp,[],pure_e))), + (l,Some(([],t1),Emp_local,[],pure_e))), E_aux(E_id(Id_aux(Id a,l)), - (l,Some(([],t2),Emp,[],pure_e)))), - (l,Some(([],t2),Emp,[],pure_e)))) enums), - (l,Some(([],t2),Emp,[],pure_e)))) + (l,Some(([],t2),Emp_local,[],pure_e)))), + (l,Some(([],t2),Emp_local,[],pure_e)))) enums), + (l,Some(([],t2),Emp_local,[],pure_e)))) | None -> eq_error l ("Type mismatch: found a " ^ (t_to_string t1) ^ " but expected " ^ (t_to_string t2))) | Tid("bit"),Tid("bool") -> let e' = E_aux(E_app((Id_aux(Id "is_one",l)),[e]),(l,Some(([],bool_t),External None,[],pure_e))) in @@ -840,11 +903,11 @@ let rec type_coerce_internal l d_env t1 cs1 e t2 cs2 = (t2,[Eq(l,b1,{nexp=Nconst 0});GtEq(l,r1,{nexp=Nconst (List.length enums)})], E_aux(E_case(e, List.mapi (fun i a -> Pat_aux(Pat_exp(P_aux(P_id(Id_aux(Id a,l)), - (l,Some(([],t1),Emp,[],pure_e))), + (l,Some(([],t1),Emp_local,[],pure_e))), E_aux(E_lit(L_aux((L_num i),l)), - (l,Some(([],t2),Emp,[],pure_e)))), - (l,Some(([],t2),Emp,[],pure_e)))) enums), - (l,Some(([],t2),Emp,[],pure_e)))) + (l,Some(([],t2),Emp_local,[],pure_e)))), + (l,Some(([],t2),Emp_local,[],pure_e)))) enums), + (l,Some(([],t2),Emp_local,[],pure_e)))) | None -> eq_error l ("Type mismatch: " ^ (t_to_string t1) ^ " , " ^ (t_to_string t2))) | _,_ -> let t',cs = type_consistent l d_env t1 t2 in (t',cs,e) @@ -858,6 +921,9 @@ let check_tannot l annot constraints efs = | Some((params,t),tag,cs,e) -> effects_eq l efs e; let params = Envmap.to_list (t_remove_unifications (Envmap.from_list params) t) in + (*let _ = Printf.printf "Checked tannot, t after removing uvars is %s\n" (t_to_string t) in *) Some((params,t),tag,cs,e) | None -> raise (Reporting_basic.err_unreachable l "check_tannot given the place holder annotation") + +let tannot_merge l denv t_older t_newer = t_newer diff --git a/src/type_internal.mli b/src/type_internal.mli index 76223409..8184c36f 100644 --- a/src/type_internal.mli +++ b/src/type_internal.mli @@ -54,7 +54,8 @@ and t_arg = | TA_ord of order type tag = - | Emp + | Emp_local + | Emp_global | External of string option | Default | Constructor @@ -129,3 +130,6 @@ val type_consistent : Parse_ast.l -> def_envs -> t -> t -> t * nexp_range list (* type_eq mutates to unify variables, and will raise an exception if the first type cannot be coerced into the second and is inconsistent *) val type_coerce : Parse_ast.l -> def_envs -> t -> exp -> t -> t * nexp_range list * exp + +(* Merge tannots when intersection or unioning two environments. In case of default types, defer to tannot on right *) +val tannot_merge : Parse_ast.l -> def_envs -> tannot -> tannot -> tannot |
