summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/type_check.ml41
-rw-r--r--test/typecheck/fail/duplicate_ctor.expect6
-rw-r--r--test/typecheck/fail/duplicate_ctor.sail3
-rw-r--r--test/typecheck/fail/duplicate_type_id.expect6
-rw-r--r--test/typecheck/fail/duplicate_type_id.sail3
5 files changed, 48 insertions, 11 deletions
diff --git a/src/type_check.ml b/src/type_check.ml
index 4f0d90bc..d341fadc 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -590,6 +590,10 @@ end = struct
|| Bindings.mem id env.enums
|| Bindings.mem id builtin_typs
+ let bound_ctor_fn env id =
+ Bindings.mem id env.top_val_specs
+ || Bindings.mem id env.union_ids
+
let get_overloads id env =
try Bindings.find id env.overloads with
| Not_found -> []
@@ -941,9 +945,14 @@ end = struct
| Not_found -> typ_error env (id_loc id) ("No val spec found for " ^ string_of_id id)
let add_union_id id bind env =
- typ_print (lazy (adding ^ "union identifier " ^ string_of_id id ^ " : " ^ string_of_bind bind));
- { env with union_ids = Bindings.add id bind env.union_ids }
-
+ if bound_ctor_fn env id
+ then typ_error env (id_loc id) ("A union constructor or function already exists with name " ^ string_of_id id )
+ else
+ begin
+ typ_print (lazy (adding ^ "union identifier " ^ string_of_id id ^ " : " ^ string_of_bind bind));
+ { env with union_ids = Bindings.add id bind env.union_ids }
+ end
+
let get_union_id id env =
try
let bind = Bindings.find id env.union_ids in
@@ -1151,15 +1160,25 @@ end = struct
let get_toplevel_lets env = env.top_letbinds
let add_variant id variant env =
- typ_print (lazy (adding ^ "variant " ^ string_of_id id));
- { env with variants = Bindings.add id variant env.variants }
-
+ if bound_typ_id env id
+ then typ_error env (id_loc id) ("Cannot create variant " ^ string_of_id id ^ ", type name is already bound")
+ else
+ begin
+ typ_print (lazy (adding ^ "variant " ^ string_of_id id));
+ { env with variants = Bindings.add id variant env.variants }
+ end
+
let add_scattered_variant id typq env =
- typ_print (lazy (adding ^ "scattered variant " ^ string_of_id id));
- { env with
- variants = Bindings.add id (typq, []) env.variants;
- scattered_variant_envs = Bindings.add id env env.scattered_variant_envs
- }
+ if bound_typ_id env id
+ then typ_error env (id_loc id) ("Cannot create scattered variant " ^ string_of_id id ^ ", type name is already bound")
+ else
+ begin
+ typ_print (lazy (adding ^ "scattered variant " ^ string_of_id id));
+ { env with
+ variants = Bindings.add id (typq, []) env.variants;
+ scattered_variant_envs = Bindings.add id env env.scattered_variant_envs
+ }
+ end
let add_variant_clause id tu env =
match Bindings.find_opt id env.variants with
diff --git a/test/typecheck/fail/duplicate_ctor.expect b/test/typecheck/fail/duplicate_ctor.expect
new file mode 100644
index 00000000..28253714
--- /dev/null
+++ b/test/typecheck/fail/duplicate_ctor.expect
@@ -0,0 +1,6 @@
+Type error:
+[duplicate_ctor.sail]:3:15-19
+3 |union foo2 = { Bar1 : int }
+  | ^--^
+  | Constructor or function already exists for Bar1
+  |
diff --git a/test/typecheck/fail/duplicate_ctor.sail b/test/typecheck/fail/duplicate_ctor.sail
new file mode 100644
index 00000000..44a133d3
--- /dev/null
+++ b/test/typecheck/fail/duplicate_ctor.sail
@@ -0,0 +1,3 @@
+union foo1 = { Bar1 : int }
+
+union foo2 = { Bar1 : int } \ No newline at end of file
diff --git a/test/typecheck/fail/duplicate_type_id.expect b/test/typecheck/fail/duplicate_type_id.expect
new file mode 100644
index 00000000..1cd2f4a8
--- /dev/null
+++ b/test/typecheck/fail/duplicate_type_id.expect
@@ -0,0 +1,6 @@
+Type error:
+[duplicate_type_id.sail]:3:6-10
+3 |union foo1 = { Bar2 : unit }
+  | ^--^
+  | Cannot create variant foo1, type name is already bound
+  |
diff --git a/test/typecheck/fail/duplicate_type_id.sail b/test/typecheck/fail/duplicate_type_id.sail
new file mode 100644
index 00000000..fe600096
--- /dev/null
+++ b/test/typecheck/fail/duplicate_type_id.sail
@@ -0,0 +1,3 @@
+union foo1 = { Bar1 : unit }
+
+union foo1 = { Bar2 : unit } \ No newline at end of file