summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlasdair2020-08-06 17:22:47 +0100
committerAlasdair2020-08-06 17:22:47 +0100
commitbe32e9e3d3e70ddea1ecfc41dafbc054060b7b78 (patch)
tree8f1ee1a9fff6317e87cbee13cbbd618647098241 /src
parent9f7dfbf61c1c2ce82fad4044f8f3f78c5d122b9d (diff)
Forbid duplicate top-level letbindings
Diffstat (limited to 'src')
-rw-r--r--src/type_check.ml16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/type_check.ml b/src/type_check.ml
index d341fadc..2ae7836f 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -1156,7 +1156,7 @@ end = struct
let add_toplevel_lets ids env =
{ env with top_letbinds = IdSet.union ids env.top_letbinds }
-
+
let get_toplevel_lets env = env.top_letbinds
let add_variant id variant env =
@@ -4909,23 +4909,31 @@ and propagate_lexp_effect_aux = function
(* 7. Checking toplevel definitions *)
(**************************************************************************)
+let check_duplicate_letbinding l pat env =
+ match IdSet.choose_opt (IdSet.inter (pat_ids pat) (Env.get_toplevel_lets env)) with
+ | Some id ->
+ typ_error env l ("Duplicate toplevel let binding " ^ string_of_id id)
+ | None -> ()
+
let check_letdef orig_env (LB_aux (letbind, (l, _))) =
- typ_print (lazy "\nChecking top-level let");
+ typ_print (lazy ("\nChecking top-level let" |> cyan |> clear));
begin
match letbind with
| LB_val (P_aux (P_typ (typ_annot, _), _) as pat, bind) ->
+ check_duplicate_letbinding l pat orig_env;
let checked_bind = propagate_exp_effect (crule check_exp orig_env (strip_exp bind) typ_annot) in
let tpat, env = bind_pat_no_guard orig_env (strip_pat pat) typ_annot in
if (BESet.is_empty (effect_set (effect_of checked_bind)) || !opt_no_effects)
then
- [DEF_val (LB_aux (LB_val (tpat, checked_bind), (l, None)))], Env.add_toplevel_lets (pat_ids tpat) env
+ [DEF_val (LB_aux (LB_val (tpat, checked_bind), (l, None)))], Env.add_toplevel_lets l (pat_ids tpat) env
else typ_error env l ("Top-level definition with effects " ^ string_of_effect (effect_of checked_bind))
| LB_val (pat, bind) ->
+ check_duplicate_letbinding l pat orig_env;
let inferred_bind = propagate_exp_effect (irule infer_exp orig_env (strip_exp bind)) in
let tpat, env = bind_pat_no_guard orig_env (strip_pat pat) (typ_of inferred_bind) in
if (BESet.is_empty (effect_set (effect_of inferred_bind)) || !opt_no_effects)
then
- [DEF_val (LB_aux (LB_val (tpat, inferred_bind), (l, None)))], Env.add_toplevel_lets (pat_ids tpat) env
+ [DEF_val (LB_aux (LB_val (tpat, inferred_bind), (l, None)))], Env.add_toplevel_lets l (pat_ids tpat) env
else typ_error env l ("Top-level definition with effects " ^ string_of_effect (effect_of inferred_bind))
end