From d0b47176ca0020f1e2b430d31e1d88b395241cfa Mon Sep 17 00:00:00 2001 From: Florian Angeletti Date: Sat, 16 Mar 2019 07:57:38 +0100 Subject: [PATCH 1/3] manual: precise constraint on reexports --- manual/manual/refman/typedecl.etex | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/manual/manual/refman/typedecl.etex b/manual/manual/refman/typedecl.etex index 0370a73b9..f3c941748 100644 --- a/manual/manual/refman/typedecl.etex +++ b/manual/manual/refman/typedecl.etex @@ -170,7 +170,9 @@ constructors or fields given in the representation remain attached to the defined type constructor. The type expression in the equation part must agree with the representation: it must be of the same kind (record or variant) and have exactly the same constructors or fields, -in the same order, with the same arguments. +in the same order, with the same arguments. Moreover, the new type +constructor must have the same arity and the same type constraints as the +original type constructor. \end{description} The type variables appearing as type parameters can optionally be From d89e047ccb1a0c08c1f2193fe93a42b7e02a669c Mon Sep 17 00:00:00 2001 From: Florian Angeletti Date: Sat, 16 Mar 2019 08:00:28 +0100 Subject: [PATCH 2/3] testsuite: test reexport failures --- testsuite/tests/typing-misc/records.ml | 83 ++++++++++++++++++++++++++ testsuite/tests/typing-misc/variant.ml | 75 +++++++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/testsuite/tests/typing-misc/records.ml b/testsuite/tests/typing-misc/records.ml index 1d26860ba..79f4c0af6 100644 --- a/testsuite/tests/typing-misc/records.ml +++ b/testsuite/tests/typing-misc/records.ml @@ -164,3 +164,86 @@ Error: This expression has type string t but an expression was expected of type int t Type string is not compatible with type int |}] + +(* reexport *) + +type ('a,'b) def = { x:int } constraint 'b = [> `A] + +type arity = (int, [`A]) def = {x:int};; +[%%expect{| +type ('a, 'b) def = { x : int; } constraint 'b = [> `A ] +Line 3, characters 0-38: +3 | type arity = (int, [`A]) def = {x:int};; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type + (int, [ `A ]) def + They have different arities. +|}] + +type ('a,'b) ct = (int,'b) def = {x:int};; +[%%expect{| +Line 1, characters 0-40: +1 | type ('a,'b) ct = (int,'b) def = {x:int};; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type + (int, [> `A ]) def + Their constraints differ. +|}] + +type ('a,'b) kind = ('a, 'b) def = A constraint 'b = [> `A];; +[%%expect{| +Line 1, characters 0-59: +1 | type ('a,'b) kind = ('a, 'b) def = A constraint 'b = [> `A];; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type + ('a, [> `A ]) def + Their kinds differ. +|}] + +type d = { x:int; y : int } +type mut = d = {x:int; mutable y:int} +[%%expect{| +type d = { x : int; y : int; } +Line 2, characters 0-37: +2 | type mut = d = {x:int; mutable y:int} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + The mutability of field y is different. +|}] + +type missing = d = { x:int } +[%%expect{| +Line 1, characters 0-28: +1 | type missing = d = { x:int } + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + The field y is only present in the original definition. +|}] + +type wrong_type = d = {x:float} +[%%expect{| +Line 1, characters 0-31: +1 | type wrong_type = d = {x:float} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + The types for field x are not equal. +|}] + +type unboxed = d = {x:float} [@@unboxed] +[%%expect{| +Line 1, characters 0-40: +1 | type unboxed = d = {x:float} [@@unboxed] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + Their internal representations differ: + this definition uses unboxed representation. +|}] + +type perm = d = {y:int; x:int} +[%%expect{| +Line 1, characters 0-30: +1 | type perm = d = {y:int; x:int} + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + Fields number 1 have different names, x and y. +|}] diff --git a/testsuite/tests/typing-misc/variant.ml b/testsuite/tests/typing-misc/variant.ml index b1dfd1c04..c7bbd9dde 100644 --- a/testsuite/tests/typing-misc/variant.ml +++ b/testsuite/tests/typing-misc/variant.ml @@ -42,3 +42,78 @@ module Make : val f : [ `A ] -> unit end |}] + + +(* reexport *) +type ('a,'b) def = X of int constraint 'b = [> `A] + +type arity = (int, [`A]) def = X of int;; +[%%expect{| +type ('a, 'b) def = X of int constraint 'b = [> `A ] +Line 3, characters 0-39: +3 | type arity = (int, [`A]) def = X of int;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type + (int, [ `A ]) def + They have different arities. +|}] + +type ('a,'b) ct = (int,'b) def = X of int;; +[%%expect{| +Line 1, characters 0-41: +1 | type ('a,'b) ct = (int,'b) def = X of int;; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type + (int, [> `A ]) def + Their constraints differ. +|}] + +type ('a,'b) kind = ('a, 'b) def = {a:int} constraint 'b = [> `A];; +[%%expect{| +Line 1, characters 0-65: +1 | type ('a,'b) kind = ('a, 'b) def = {a:int} constraint 'b = [> `A];; + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type + ('a, [> `A ]) def + Their kinds differ. +|}] + +type d = X of int | Y of int + +type missing = d = X of int +[%%expect{| +type d = X of int | Y of int +Line 3, characters 0-27: +3 | type missing = d = X of int + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + The field Y is only present in the original definition. +|}] + +type wrong_type = d = X of float +[%%expect{| +Line 1, characters 0-32: +1 | type wrong_type = d = X of float + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + The types for field X are not equal. +|}] + +type unboxed = d = X of float [@@unboxed] +[%%expect{| +Line 1, characters 0-41: +1 | type unboxed = d = X of float [@@unboxed] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + Their internal representations differ: + this definition uses unboxed representation. +|}] + +type perm = d = Y of int | X of int +[%%expect{| +Line 1, characters 0-35: +1 | type perm = d = Y of int | X of int + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Error: This variant or record definition does not match that of type d + Fields number 1 have different names, X and Y. +|}] From c929ace8a126339c46f226a5b4a161da0a3681e9 Mon Sep 17 00:00:00 2001 From: Florian Angeletti Date: Mon, 18 Mar 2019 11:49:26 +0100 Subject: [PATCH 3/3] update Changes --- Changes | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Changes b/Changes index 0d499eadc..06bc58d01 100644 --- a/Changes +++ b/Changes @@ -89,6 +89,11 @@ Working version (Jules Aguillon, with help from Armaël Guéneau, review by Gabriel Scherer and Florian Angeletti) +### Manual and documentation: + +- PR#8515: manual, precise constraints on reexported types + (Florian Angeletti, review by Gabriel Scherer) + ### Bug fixes: - MPR#7937, GPR#2287: fix uncaught Unify exception when looking for type