diff --git a/testsuite/tests/typing-misc/deep.ml b/testsuite/tests/typing-misc/deep.ml new file mode 100644 index 000000000000..1d1a02271952 --- /dev/null +++ b/testsuite/tests/typing-misc/deep.ml @@ -0,0 +1,88 @@ +(* TEST + * expect +*) + +module M : sig + val x : bool * int +end = struct + let x = false , "not an int" +end +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | let x = false , "not an int" +5 | end +Error: Signature mismatch: + Modules do not match: + sig val x : bool * string end + is not included in + sig val x : bool * int end + Values do not match: + val x : bool * string + is not included in + val x : bool * int +|}] + +module T : sig + val f : int -> (float * string ref) list +end = struct + let f x = x + List.length [0.0, ref true] +end +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | let f x = x + List.length [0.0, ref true] +5 | end +Error: Signature mismatch: + Modules do not match: + sig val f : int -> int end + is not included in + sig val f : int -> (float * string ref) list end + Values do not match: + val f : int -> int + is not included in + val f : int -> (float * string ref) list +|}] + +(* Alpha-equivalence *) +module T : sig + val f : ('a list * 'b list -> int) +end = struct + let f : ('c list * 'd ref -> int) = assert false +end +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | let f : ('c list * 'd ref -> int) = assert false +5 | end +Error: Signature mismatch: + Modules do not match: + sig val f : 'c list * 'd ref -> int end + is not included in + sig val f : 'a list * 'b list -> int end + Values do not match: + val f : 'c list * 'd ref -> int + is not included in + val f : 'a list * 'b list -> int +|}] + +module T : sig + type t = int * float +end = struct + type t = bool * float +end +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | type t = bool * float +5 | end +Error: Signature mismatch: + Modules do not match: + sig type t = bool * float end + is not included in + sig type t = int * float end + Type declarations do not match: + type t = bool * float + is not included in + type t = int * float +|}] diff --git a/testsuite/tests/typing-modules/inclusion_errors.ml b/testsuite/tests/typing-modules/inclusion_errors.ml index a20566f55915..f0c258d3fa1c 100644 --- a/testsuite/tests/typing-modules/inclusion_errors.ml +++ b/testsuite/tests/typing-modules/inclusion_errors.ml @@ -1053,6 +1053,70 @@ Error: Signature mismatch: type t = private [> `A of int ] |}];; +module M : sig + type t = private [< `A | `B] +end = struct + type t = private [`A | `B] +end;; +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | type t = private [`A | `B] +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig type t = private [ `A | `B ] end + is not included in + sig type t = private [< `A | `B ] end + Type declarations do not match: + type t = private [ `A | `B ] + is not included in + type t = private [< `A | `B ] +|}];; + +module M : sig + type t = [`A | `B] +end = struct + type t = private [`A | `B] +end;; +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | type t = private [`A | `B] +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig type t = private [ `A | `B ] end + is not included in + sig type t = [ `A | `B ] end + Type declarations do not match: + type t = private [ `A | `B ] + is not included in + type t = [ `A | `B ] + A private type would be revealed. +|}];; + +module M : sig + type t = private [< `A | `B > `B] +end = struct + type t = private [< `A | `B] +end;; +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | type t = private [< `A | `B] +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig type t = private [< `A | `B ] end + is not included in + sig type t = private [< `A | `B > `B ] end + Type declarations do not match: + type t = private [< `A | `B ] + is not included in + type t = private [< `A | `B > `B ] +|}];; + module M : sig type t = private end = struct diff --git a/testsuite/tests/typing-modules/pr10399.ml b/testsuite/tests/typing-modules/pr10399.ml new file mode 100644 index 000000000000..0e376da8401f --- /dev/null +++ b/testsuite/tests/typing-modules/pr10399.ml @@ -0,0 +1,44 @@ +(* TEST + * expect +*) + +(* From jctis: *) + +module PR10399 : sig + type t = < x : int > + + class c : object method x : int method y : bool end + + val o : t +end = struct + type t = < x : int > + + class c = object method x = 3 method y = true end + + let o = new c +end + +[%%expect{| +Lines 7-13, characters 6-3: + 7 | ......struct + 8 | type t = < x : int > + 9 | +10 | class c = object method x = 3 method y = true end +11 | +12 | let o = new c +13 | end +Error: Signature mismatch: + Modules do not match: + sig + type t = < x : int > + class c : object method x : int method y : bool end + val o : c + end + is not included in + sig + type t = < x : int > + class c : object method x : int method y : bool end + val o : t + end + Values do not match: val o : c is not included in val o : t +|}] diff --git a/testsuite/tests/typing-unboxed/test.ml b/testsuite/tests/typing-unboxed/test.ml index fb1ecb82b6f9..e57ed3b4e8c4 100644 --- a/testsuite/tests/typing-unboxed/test.ml +++ b/testsuite/tests/typing-unboxed/test.ml @@ -122,6 +122,28 @@ Error: Signature mismatch: |}] module Bad2 : sig + external f : int -> int = "f" "f_nat" +end = struct + external f : (int [@untagged]) -> int = "f" "f_nat" +end;; + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : (int [@untagged]) -> int = "f" "f_nat" +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig external f : (int [@untagged]) -> int = "f" "f_nat" end + is not included in + sig external f : int -> int = "f" "f_nat" end + Values do not match: + external f : (int [@untagged]) -> int = "f" "f_nat" + is not included in + external f : int -> int = "f" "f_nat" +|}] + +module Bad3 : sig external f : int -> int = "a" "a_nat" end = struct external f : (int [@untagged]) -> int = "f" "f_nat" @@ -143,7 +165,7 @@ Error: Signature mismatch: external f : int -> int = "a" "a_nat" |}] -module Bad3 : sig +module Bad4 : sig external f : float -> float = "f" "f_nat" end = struct external f : float -> (float [@unboxed]) = "f" "f_nat" @@ -165,7 +187,29 @@ Error: Signature mismatch: external f : float -> float = "f" "f_nat" |}] -module Bad4 : sig +module Bad5 : sig + external f : float -> float = "f" "f_nat" +end = struct + external f : (float [@unboxed]) -> float = "f" "f_nat" +end;; + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : (float [@unboxed]) -> float = "f" "f_nat" +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig external f : (float [@unboxed]) -> float = "f" "f_nat" end + is not included in + sig external f : float -> float = "f" "f_nat" end + Values do not match: + external f : (float [@unboxed]) -> float = "f" "f_nat" + is not included in + external f : float -> float = "f" "f_nat" +|}] + +module Bad6 : sig external f : float -> float = "a" "a_nat" end = struct external f : (float [@unboxed]) -> float = "f" "f_nat" @@ -187,9 +231,31 @@ Error: Signature mismatch: external f : float -> float = "a" "a_nat" |}] +module Bad7 : sig + external f : int -> int = "f" "f_nat" +end = struct + external f : int -> int = "f" "f_nat" [@@noalloc] +end;; + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : int -> int = "f" "f_nat" [@@noalloc] +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig external f : int -> int = "f" "f_nat" [@@noalloc] end + is not included in + sig external f : int -> int = "f" "f_nat" end + Values do not match: + external f : int -> int = "f" "f_nat" [@@noalloc] + is not included in + external f : int -> int = "f" "f_nat" +|}] + (* Bad: attributes in the interface but not in the implementation *) -module Bad5 : sig +module Bad8 : sig external f : int -> (int [@untagged]) = "f" "f_nat" end = struct external f : int -> int = "f" "f_nat" @@ -211,7 +277,29 @@ Error: Signature mismatch: external f : int -> (int [@untagged]) = "f" "f_nat" |}] -module Bad6 : sig +module Bad9 : sig + external f : (int [@untagged]) -> int = "f" "f_nat" +end = struct + external f : int -> int = "f" "f_nat" +end;; + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : int -> int = "f" "f_nat" +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig external f : int -> int = "f" "f_nat" end + is not included in + sig external f : (int [@untagged]) -> int = "f" "f_nat" end + Values do not match: + external f : int -> int = "f" "f_nat" + is not included in + external f : (int [@untagged]) -> int = "f" "f_nat" +|}] + +module Bad10 : sig external f : (int [@untagged]) -> int = "f" "f_nat" end = struct external f : int -> int = "a" "a_nat" @@ -233,7 +321,7 @@ Error: Signature mismatch: external f : (int [@untagged]) -> int = "f" "f_nat" |}] -module Bad7 : sig +module Bad11 : sig external f : float -> (float [@unboxed]) = "f" "f_nat" end = struct external f : float -> float = "f" "f_nat" @@ -255,7 +343,29 @@ Error: Signature mismatch: external f : float -> (float [@unboxed]) = "f" "f_nat" |}] -module Bad8 : sig +module Bad12 : sig + external f : (float [@unboxed]) -> float = "f" "f_nat" +end = struct + external f : float -> float = "f" "f_nat" +end;; + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : float -> float = "f" "f_nat" +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig external f : float -> float = "f" "f_nat" end + is not included in + sig external f : (float [@unboxed]) -> float = "f" "f_nat" end + Values do not match: + external f : float -> float = "f" "f_nat" + is not included in + external f : (float [@unboxed]) -> float = "f" "f_nat" +|}] + +module Bad13 : sig external f : (float [@unboxed]) -> float = "f" "f_nat" end = struct external f : float -> float = "a" "a_nat" @@ -277,6 +387,215 @@ Error: Signature mismatch: external f : (float [@unboxed]) -> float = "f" "f_nat" |}] +module Bad14 : sig + external f : int -> int = "f" "f_nat" [@@noalloc] +end = struct + external f : int -> int = "f" "f_nat" +end;; + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : int -> int = "f" "f_nat" +5 | end.. +Error: Signature mismatch: + Modules do not match: + sig external f : int -> int = "f" "f_nat" end + is not included in + sig external f : int -> int = "f" "f_nat" [@@noalloc] end + Values do not match: + external f : int -> int = "f" "f_nat" + is not included in + external f : int -> int = "f" "f_nat" [@@noalloc] +|}] + +(* Bad: claiming something is a primitive when it isn't *) + +module Bad15 : sig + external f : int -> int = "f" "f_nat" +end = struct + let f x = x + 1 +end + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | let f x = x + 1 +5 | end +Error: Signature mismatch: + Modules do not match: + sig val f : int -> int end + is not included in + sig external f : int -> int = "f" "f_nat" end + Values do not match: + val f : int -> int + is not included in + external f : int -> int = "f" "f_nat" +|}] + +(* Good: not claiming something is a primitive when it is *) + +module Good16 : sig + val f : int -> int +end = struct + external f : int -> int = "f" "f_nat" +end +(* The expected error here is that "f" isn't defined -- that means typechecking + succeeded *) + +[%%expect{| +Line 1: +Error: The external function `f' is not available +|}] + +(* Bad: mismatched names and native names *) + +module Bad17 : sig + external f : int -> int = "f" "f_nat" +end = struct + external f : int -> int = "gg" "f_nat" +end + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : int -> int = "gg" "f_nat" +5 | end +Error: Signature mismatch: + Modules do not match: + sig external f : int -> int = "gg" "f_nat" end + is not included in + sig external f : int -> int = "f" "f_nat" end + Values do not match: + external f : int -> int = "gg" "f_nat" + is not included in + external f : int -> int = "f" "f_nat" +|}] + +module Bad18 : sig + external f : int -> int = "f" "f_nat" +end = struct + external f : int -> int = "f" "gg_nat" +end + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : int -> int = "f" "gg_nat" +5 | end +Error: Signature mismatch: + Modules do not match: + sig external f : int -> int = "f" "gg_nat" end + is not included in + sig external f : int -> int = "f" "f_nat" end + Values do not match: + external f : int -> int = "f" "gg_nat" + is not included in + external f : int -> int = "f" "f_nat" +|}] + +module Bad19 : sig + external f : int -> int = "f" "f_nat" +end = struct + external f : int -> int = "gg" "gg_nat" +end + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : int -> int = "gg" "gg_nat" +5 | end +Error: Signature mismatch: + Modules do not match: + sig external f : int -> int = "gg" "gg_nat" end + is not included in + sig external f : int -> int = "f" "f_nat" end + Values do not match: + external f : int -> int = "gg" "gg_nat" + is not included in + external f : int -> int = "f" "f_nat" +|}] + +(* Bad: mismatched arities *) + +(* NB: The compiler checks primitive arities *syntactically*, based on the + number of arrows it sees. Thus, hiding function types behind type synonyms + will produce an error about the primitive arities not matching, even when the + types agree. *) + +module Bad20 : sig + type int_int := int -> int + external f : int -> int_int = "f" "f_nat" +end = struct + external f : int -> int -> int = "f" "f_nat" +end + +[%%expect{| +Lines 4-6, characters 6-3: +4 | ......struct +5 | external f : int -> int -> int = "f" "f_nat" +6 | end +Error: Signature mismatch: + Modules do not match: + sig external f : int -> int -> int = "f" "f_nat" end + is not included in + sig external f : int -> int -> int = "f" "f_nat" end + Values do not match: + external f : int -> int -> int = "f" "f_nat" + is not included in + external f : int -> int -> int = "f" "f_nat" +|}] + +module Bad21 : sig + external f : int -> int -> int = "f" "f_nat" +end = struct + type int_int = int -> int + external f : int -> int_int = "f" "f_nat" +end + +[%%expect{| +Lines 3-6, characters 6-3: +3 | ......struct +4 | type int_int = int -> int +5 | external f : int -> int_int = "f" "f_nat" +6 | end +Error: Signature mismatch: + Modules do not match: + sig + type int_int = int -> int + external f : int -> int_int = "f" "f_nat" + end + is not included in + sig external f : int -> int -> int = "f" "f_nat" end + Values do not match: + external f : int -> int_int = "f" "f_nat" + is not included in + external f : int -> int -> int = "f" "f_nat" +|}] + +(* This will fail with a *type* error, instead of an arity mismatch *) +module Bad22 : sig + external f : int -> int = "f" "f_nat" +end = struct + external f : int -> int -> int = "f" "f_nat" +end + +[%%expect{| +Lines 3-5, characters 6-3: +3 | ......struct +4 | external f : int -> int -> int = "f" "f_nat" +5 | end +Error: Signature mismatch: + Modules do not match: + sig external f : int -> int -> int = "f" "f_nat" end + is not included in + sig external f : int -> int = "f" "f_nat" end + Values do not match: + external f : int -> int -> int = "f" "f_nat" + is not included in + external f : int -> int = "f" "f_nat" +|}] + (* Bad: unboxed or untagged with the wrong type *) external g : (float [@untagged]) -> float = "g" "g_nat";;