summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Yallop <yallop@gmail.com>2017-01-09 07:09:03 +0000
committerJeremy Yallop <yallop@gmail.com>2017-09-25 14:57:23 +0100
commit570937a3cd9735edd19708309467b46d796d9be0 (patch)
treeae328c1d0cb07198f914e6a591bed2ef551da247
parentb602f3347e4db68693566bee28009b12221a61d9 (diff)
downloadocaml-570937a3cd9735edd19708309467b46d796d9be0.tar.gz
let-rec check: extension constructor access inspects the defining module.
(from Stephen Dolan's review)
-rw-r--r--testsuite/tests/letrec-disallowed/extension_constructor.ml12
-rw-r--r--testsuite/tests/letrec-disallowed/extension_constructor.ml.reference7
-rw-r--r--typing/typecore.ml7
3 files changed, 25 insertions, 1 deletions
diff --git a/testsuite/tests/letrec-disallowed/extension_constructor.ml b/testsuite/tests/letrec-disallowed/extension_constructor.ml
new file mode 100644
index 0000000000..eb013ea8df
--- /dev/null
+++ b/testsuite/tests/letrec-disallowed/extension_constructor.ml
@@ -0,0 +1,12 @@
+(* Example from Stephen Dolan.
+ Accessing an extension constructor involves accessing the module
+ in which it's defined.
+ *)
+module type T =
+ sig exception A of int end;;
+
+let rec x =
+ let module M = (val m) in
+ M.A 42
+and (m : (module T)) =
+ (module (struct exception A of int end));;
diff --git a/testsuite/tests/letrec-disallowed/extension_constructor.ml.reference b/testsuite/tests/letrec-disallowed/extension_constructor.ml.reference
new file mode 100644
index 0000000000..f680d73703
--- /dev/null
+++ b/testsuite/tests/letrec-disallowed/extension_constructor.ml.reference
@@ -0,0 +1,7 @@
+
+# * * * module type T = sig exception A of int end
+# Characters 15-49:
+ ..let module M = (val m) in
+ M.A 42
+Error: This kind of expression is not allowed as right-hand side of `let rec'
+#
diff --git a/typing/typecore.ml b/typing/typecore.ml
index 28114e377c..6195136951 100644
--- a/typing/typecore.ml
+++ b/typing/typecore.ml
@@ -2002,11 +2002,16 @@ struct
involves inspecting the elements (PR#6939). *)
Use.inspect (list expression env exprs)
| Texp_construct (_, desc, exprs) ->
+ let access_constructor =
+ match desc.cstr_tag with
+ | Cstr_extension (pth, _) -> Use.inspect (path env pth)
+ | _ -> Use.empty
+ in
let use = match desc.cstr_tag with
| Cstr_unboxed -> (fun x -> x)
| Cstr_constant _ | Cstr_block _ | Cstr_extension _ -> Use.guard
in
- use (list expression env exprs)
+ Use.join access_constructor (use (list expression env exprs))
| Texp_variant (_, eo) ->
Use.guard (option expression env eo)
| Texp_record { fields = es; extended_expression = eo;