summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes4
-rw-r--r--manual/src/library/stdlib-blurb.etex4
-rwxr-xr-xmanual/tests/check-stdlib-modules2
-rw-r--r--stdlib/.depend16
-rw-r--r--stdlib/StdlibModules2
-rw-r--r--stdlib/in_channel.ml66
-rw-r--r--stdlib/in_channel.mli136
-rw-r--r--stdlib/out_channel.ml47
-rw-r--r--stdlib/out_channel.mli131
-rw-r--r--stdlib/stdlib.ml2
-rw-r--r--stdlib/stdlib.mli6
-rw-r--r--testsuite/tests/basic/patmatch_for_multiple.ml168
-rw-r--r--testsuite/tests/generalized-open/gpr1506.ml12
-rw-r--r--testsuite/tests/typing-sigsubst/sigsubst.ml6
14 files changed, 505 insertions, 97 deletions
diff --git a/Changes b/Changes
index 9fe06a4c24..1b50eb3f34 100644
--- a/Changes
+++ b/Changes
@@ -41,6 +41,10 @@ Working version
by the functions from module Marshal)
(François Pottier, review by Gabriel Scherer and Kate Deplaix)
+- #10545: Add In_channel and Out_channel modules.
+ (Nicolás Ojeda Bär, review by Daniel Bünzli, Simon Cruanes, Gabriel Scherer,
+ Guillaume Munch-Maccagnoni, Alain Frisch and Xavier Leroy)
+
### Other libraries:
- #10192: Add support for Unix domain sockets on Windows and use them
diff --git a/manual/src/library/stdlib-blurb.etex b/manual/src/library/stdlib-blurb.etex
index 65684b1b3f..8f2e00dfe0 100644
--- a/manual/src/library/stdlib-blurb.etex
+++ b/manual/src/library/stdlib-blurb.etex
@@ -77,6 +77,8 @@ integers
\end{tabular}
\subsubsection*{sss:stdlib-io}{input/output:}
\begin{tabular}{lll}
+"In_channel" & p.~\stdpageref{In-underscorechannel} & input channels \\
+"Out_channel" & p.~\stdpageref{Out-underscorechannel} & output channels \\
"Format" & p.~\stdpageref{Format} & pretty printing with automatic
indentation and line breaking \\
"Marshal" & p.~\stdpageref{Marshal} & marshaling of data structures \\
@@ -130,6 +132,7 @@ be called from C \\
\stddocitem{Gc}{memory management control and statistics; finalized values}
\stddocitem{Genlex}{a generic lexical analyzer}
\stddocitem{Hashtbl}{hash tables and hash functions}
+\stddocitem{In_channel}{input channels}
\stddocitem{Int}{integers}
\stddocitem{Int32}{32-bit integers}
\stddocitem{Int64}{64-bit integers}
@@ -143,6 +146,7 @@ be called from C \\
\stddocitem{Nativeint}{processor-native integers}
\stddocitem{Oo}{object-oriented extension}
\stddocitem{Option}{option values}
+\stddocitem{Out_channel}{output channels}
\stddocitem{Parsing}{the run-time library for parsers generated by \texttt{ocamlyacc}}
\stddocitem{Printexc}{facilities for printing exceptions}
\stddocitem{Printf}{formatting printing functions}
diff --git a/manual/tests/check-stdlib-modules b/manual/tests/check-stdlib-modules
index af4d3dadfa..ed17a5e35a 100755
--- a/manual/tests/check-stdlib-modules
+++ b/manual/tests/check-stdlib-modules
@@ -10,7 +10,7 @@ cut -c 2- $TMPDIR/stdlib-$$-files \
exitcode=0
for i in `cat $TMPDIR/stdlib-$$-modules`; do
case $i in
- Stdlib | Camlinternal* | *Labels | Obj | Pervasives) continue;;
+ Stdlib | Camlinternal* | *Labels | Obj | Pervasives | In_channel | Out_channel) continue;;
esac
grep -q -e '"'$i'" & p\.~\\stdpageref{'$i'} &' $1/manual/src/library/stdlib-blurb.etex || {
echo "Module $i is missing from the module description in library/stdlib-blurb.etex." >&2
diff --git a/stdlib/.depend b/stdlib/.depend
index 8e902092f8..c2edf6a3f4 100644
--- a/stdlib/.depend
+++ b/stdlib/.depend
@@ -359,6 +359,14 @@ stdlib__Hashtbl.cmx : hashtbl.ml \
stdlib__Hashtbl.cmi
stdlib__Hashtbl.cmi : hashtbl.mli \
stdlib__Seq.cmi
+stdlib__In_channel.cmo : in_channel.ml \
+ stdlib.cmi \
+ stdlib__In_channel.cmi
+stdlib__In_channel.cmx : in_channel.ml \
+ stdlib.cmx \
+ stdlib__In_channel.cmi
+stdlib__In_channel.cmi : in_channel.mli \
+ stdlib.cmi
stdlib__Int.cmo : int.ml \
stdlib.cmi \
stdlib__Int.cmi
@@ -496,6 +504,14 @@ stdlib__Option.cmx : option.ml \
stdlib__Option.cmi
stdlib__Option.cmi : option.mli \
stdlib__Seq.cmi
+stdlib__Out_channel.cmo : out_channel.ml \
+ stdlib.cmi \
+ stdlib__Out_channel.cmi
+stdlib__Out_channel.cmx : out_channel.ml \
+ stdlib.cmx \
+ stdlib__Out_channel.cmi
+stdlib__Out_channel.cmi : out_channel.mli \
+ stdlib.cmi
stdlib__Parsing.cmo : parsing.ml \
stdlib__Obj.cmi \
stdlib__Lexing.cmi \
diff --git a/stdlib/StdlibModules b/stdlib/StdlibModules
index 4d3351c3a3..7d4b4a25d4 100644
--- a/stdlib/StdlibModules
+++ b/stdlib/StdlibModules
@@ -42,7 +42,7 @@ STDLIB_MODULE_BASENAMES=\
printexc fun gc digest random hashtbl weak \
format scanf callback camlinternalOO oo camlinternalMod genlex ephemeron \
filename complex arrayLabels listLabels bytesLabels stringLabels moreLabels \
- stdLabels bigarray
+ stdLabels bigarray in_channel out_channel
STDLIB_PREFIXED_MODULES=\
$(filter-out stdlib camlinternal%, $(STDLIB_MODULE_BASENAMES))
diff --git a/stdlib/in_channel.ml b/stdlib/in_channel.ml
new file mode 100644
index 0000000000..a221c80484
--- /dev/null
+++ b/stdlib/in_channel.ml
@@ -0,0 +1,66 @@
+(**************************************************************************)
+(* *)
+(* OCaml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2021 Institut National de Recherche en Informatique et *)
+(* en Automatique. *)
+(* *)
+(* All rights reserved. This file is distributed under the terms of *)
+(* the GNU Lesser General Public License version 2.1, with the *)
+(* special exception on linking described in the file LICENSE. *)
+(* *)
+(**************************************************************************)
+
+type t = in_channel
+
+type open_flag = Stdlib.open_flag =
+ | Open_rdonly
+ | Open_wronly
+ | Open_append
+ | Open_creat
+ | Open_trunc
+ | Open_excl
+ | Open_binary
+ | Open_text
+ | Open_nonblock
+
+let stdin = Stdlib.stdin
+let open_bin = Stdlib.open_in_bin
+let open_text = Stdlib.open_in
+let open_gen = Stdlib.open_in_gen
+let seek = Stdlib.LargeFile.seek_in
+let pos = Stdlib.LargeFile.pos_in
+let length = Stdlib.LargeFile.in_channel_length
+let close = Stdlib.close_in
+let close_noerr = Stdlib.close_in_noerr
+
+let input_char ic =
+ match Stdlib.input_char ic with
+ | c -> Some c
+ | exception End_of_file -> None
+
+let input_byte ic =
+ match Stdlib.input_byte ic with
+ | n -> Some n
+ | exception End_of_file -> None
+
+let input_line ic =
+ match Stdlib.input_line ic with
+ | s -> Some s
+ | exception End_of_file -> None
+
+let input = Stdlib.input
+
+let really_input ic buf pos len =
+ match Stdlib.really_input ic buf pos len with
+ | () -> Some ()
+ | exception End_of_file -> None
+
+let really_input_string ic len =
+ match Stdlib.really_input_string ic len with
+ | s -> Some s
+ | exception End_of_file -> None
+
+let set_binary_mode = Stdlib.set_binary_mode_in
diff --git a/stdlib/in_channel.mli b/stdlib/in_channel.mli
new file mode 100644
index 0000000000..14e65e2ced
--- /dev/null
+++ b/stdlib/in_channel.mli
@@ -0,0 +1,136 @@
+(**************************************************************************)
+(* *)
+(* OCaml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2021 Institut National de Recherche en Informatique et *)
+(* en Automatique. *)
+(* *)
+(* All rights reserved. This file is distributed under the terms of *)
+(* the GNU Lesser General Public License version 2.1, with the *)
+(* special exception on linking described in the file LICENSE. *)
+(* *)
+(**************************************************************************)
+
+(** Input channels.
+
+ @since 4.14.0 *)
+
+type t = in_channel
+(** The type of input channel. *)
+
+type open_flag = Stdlib.open_flag =
+ | Open_rdonly (** open for reading. *)
+ | Open_wronly (** open for writing. *)
+ | Open_append (** open for appending: always write at end of file. *)
+ | Open_creat (** create the file if it does not exist. *)
+ | Open_trunc (** empty the file if it already exists. *)
+ | Open_excl (** fail if Open_creat and the file already exists. *)
+ | Open_binary (** open in binary mode (no conversion). *)
+ | Open_text (** open in text mode (may perform conversions). *)
+ | Open_nonblock (** open in non-blocking mode. *)
+(** Opening modes for {!open_gen}. *)
+
+val stdin : t
+(** The standard input for the process. *)
+
+val open_bin : string -> t
+(** Open the named file for reading, and return a new input channel on that
+ file, positioned at the beginning of the file. *)
+
+val open_text : string -> t
+(** Same as {!open_bin}, but the file is opened in text mode, so that newline
+ translation takes place during reads. On operating systems that do not
+ distinguish between text mode and binary mode, this function behaves like
+ {!open_bin}. *)
+
+val open_gen : open_flag list -> int -> string -> t
+(** [open_gen mode perm filename] opens the named file for reading, as described
+ above. The extra arguments [mode] and [perm] specify the opening mode and
+ file permissions. {!open_text} and {!open_bin} are special cases of this
+ function. *)
+
+val seek : t -> int64 -> unit
+(** [seek chan pos] sets the current reading position to [pos] for channel
+ [chan]. This works only for regular files. On files of other kinds, the
+ behavior is unspecified. *)
+
+val pos : t -> int64
+(** Return the current reading position for the given channel. For files opened
+ in text mode under Windows, the returned position is approximate (owing to
+ end-of-line conversion); in particular, saving the current position with
+ {!pos}, then going back to this position using {!seek} will not work. For
+ this programming idiom to work reliably and portably, the file must be
+ opened in binary mode. *)
+
+val length : t -> int64
+(** Return the size (number of characters) of the regular file on which the
+ given channel is opened. If the channel is opened on a file that is not a
+ regular file, the result is meaningless. The returned size does not take
+ into account the end-of-line translations that can be performed when reading
+ from a channel opened in text mode. *)
+
+val close : t -> unit
+(** Close the given channel. Input functions raise a [Sys_error] exception when
+ they are applied to a closed input channel, except {!close}, which does
+ nothing when applied to an already closed channel. *)
+
+val close_noerr : t -> unit
+(** Same as {!close}, but ignore all errors. *)
+
+val input_char : t -> char option
+(** Read one character from the given input channel. Returns [None] if there
+ are no more characters to read. *)
+
+val input_byte : t -> int option
+(** Same as {!input_char}, but return the 8-bit integer representing the
+ character. Returns [None] if the end of file was reached. *)
+
+val input_line : t -> string option
+(** [input_line ic] reads characters from [ic] until a newline or the end of
+ file is reached. Returns the string of all characters read, without the
+ newline (if any). Returns [None] if the end of the file has been reached.
+ In particular, this will be the case if the last line of input is empty.
+
+ A newline is the character [\n] unless the file is open in text mode and
+ {!Sys.win32} is [true] in which case it is the sequence of characters
+ [\r\n]. *)
+
+val input : t -> bytes -> int -> int -> int
+(** [input ic buf pos len] reads up to [len] characters from the given channel
+ [ic], storing them in byte sequence [buf], starting at character number
+ [pos]. It returns the actual number of characters read, between 0 and [len]
+ (inclusive). A return value of 0 means that the end of file was reached.
+
+ Use {!really_input} to read exactly [len] characters.
+
+ @raise Invalid_argument if [pos] and [len] do not designate a valid range of
+ [buf]. *)
+
+val really_input : t -> bytes -> int -> int -> unit option
+(** [really_input ic buf pos len] reads [len] characters from channel [ic],
+ storing them in byte sequence [buf], starting at character number [pos].
+
+ Returns [None] if the end of file is reached before [len] characters have
+ been read.
+
+ @raise Invalid_argument if [pos] and [len] do not designate a valid range of
+ [buf]. *)
+
+val really_input_string : t -> int -> string option
+(** [really_input_string ic len] reads [len] characters from channel [ic] and
+ returns them in a new string. Returns [None] if the end of file is reached
+ before [len] characters have been read. *)
+
+val set_binary_mode : t -> bool -> unit
+(** [set_binary_mode ic true] sets the channel [ic] to binary mode: no
+ translations take place during input.
+
+ [set_binary_mode ic false] sets the channel [ic] to text mode: depending
+ on the operating system, some translations may take place during input. For
+ instance, under Windows, end-of-lines will be translated from [\r\n] to
+ [\n].
+
+ This function has no effect under operating systems that do not distinguish
+ between text mode and binary mode. *)
diff --git a/stdlib/out_channel.ml b/stdlib/out_channel.ml
new file mode 100644
index 0000000000..250b73816c
--- /dev/null
+++ b/stdlib/out_channel.ml
@@ -0,0 +1,47 @@
+(**************************************************************************)
+(* *)
+(* OCaml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2021 Institut National de Recherche en Informatique et *)
+(* en Automatique. *)
+(* *)
+(* All rights reserved. This file is distributed under the terms of *)
+(* the GNU Lesser General Public License version 2.1, with the *)
+(* special exception on linking described in the file LICENSE. *)
+(* *)
+(**************************************************************************)
+
+type t = out_channel
+
+type open_flag = Stdlib.open_flag =
+ | Open_rdonly
+ | Open_wronly
+ | Open_append
+ | Open_creat
+ | Open_trunc
+ | Open_excl
+ | Open_binary
+ | Open_text
+ | Open_nonblock
+
+let stdout = Stdlib.stdout
+let stderr = Stdlib.stderr
+let open_bin = Stdlib.open_out_bin
+let open_text = Stdlib.open_out
+let open_gen = Stdlib.open_out_gen
+let seek = Stdlib.LargeFile.seek_out
+let pos = Stdlib.LargeFile.pos_out
+let length = Stdlib.LargeFile.out_channel_length
+let close = Stdlib.close_out
+let close_noerr = Stdlib.close_out_noerr
+let flush = Stdlib.flush
+let flush_all = Stdlib.flush_all
+let output_char = Stdlib.output_char
+let output_byte = Stdlib.output_byte
+let output_string = Stdlib.output_string
+let output_bytes = Stdlib.output_bytes
+let output = Stdlib.output
+let output_substring = Stdlib.output_substring
+let set_binary_mode = Stdlib.set_binary_mode_out
diff --git a/stdlib/out_channel.mli b/stdlib/out_channel.mli
new file mode 100644
index 0000000000..9b94eaaaba
--- /dev/null
+++ b/stdlib/out_channel.mli
@@ -0,0 +1,131 @@
+(**************************************************************************)
+(* *)
+(* OCaml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2021 Institut National de Recherche en Informatique et *)
+(* en Automatique. *)
+(* *)
+(* All rights reserved. This file is distributed under the terms of *)
+(* the GNU Lesser General Public License version 2.1, with the *)
+(* special exception on linking described in the file LICENSE. *)
+(* *)
+(**************************************************************************)
+
+(** Output channels.
+
+ @since 4.14.0 *)
+
+type t = out_channel
+(** The type of output channel. *)
+
+type open_flag = Stdlib.open_flag =
+ | Open_rdonly (** open for reading. *)
+ | Open_wronly (** open for writing. *)
+ | Open_append (** open for appending: always write at end of file. *)
+ | Open_creat (** create the file if it does not exist. *)
+ | Open_trunc (** empty the file if it already exists. *)
+ | Open_excl (** fail if Open_creat and the file already exists. *)
+ | Open_binary (** open in binary mode (no conversion). *)
+ | Open_text (** open in text mode (may perform conversions). *)
+ | Open_nonblock (** open in non-blocking mode. *)
+(** Opening modes for {!open_gen}. *)
+
+val stdout : t
+(** The standard output for the process. *)
+
+val stderr : t
+(** The standard error output for the process. *)
+
+val open_bin : string -> t
+(** Open the named file for writing, and return a new output channel on that
+ file, positioned at the beginning of the file. The file is truncated to zero
+ length if it already exists. It is created if it does not already exists. *)
+
+val open_text : string -> t
+(** Same as {!open_bin}, but the file is opened in text mode, so that newline
+ translation takes place during writes. On operating systems that do not
+ distinguish between text mode and binary mode, this function behaves like
+ {!open_bin}. *)
+
+val open_gen : open_flag list -> int -> string -> t
+(** [open_gen mode perm filename] opens the named file for writing, as described
+ above. The extra argument [mode] specifies the opening mode. The extra
+ argument [perm] specifies the file permissions, in case the file must be
+ created. {!open_text} and {!open_bin} are special cases of this
+ function. *)
+
+val seek : t -> int64 -> unit
+(** [seek chan pos] sets the current writing position to [pos] for channel
+ [chan]. This works only for regular files. On files of other kinds (such as
+ terminals, pipes and sockets), the behavior is unspecified. *)
+
+val pos : t -> int64
+(** Return the current writing position for the given channel. Does not work on
+ channels opened with the [Open_append] flag (returns unspecified results).
+
+ For files opened in text mode under Windows, the returned position is
+ approximate (owing to end-of-line conversion); in particular, saving the
+ current position with {!pos}, then going back to this position using {!seek}
+ will not work. For this programming idiom to work reliably and portably,
+ the file must be opened in binary mode. *)
+
+val length : t -> int64
+(** Return the size (number of characters) of the regular file on which the
+ given channel is opened. If the channel is opened on a file that is not a
+ regular file, the result is meaningless. *)
+
+val close : t -> unit
+(** Close the given channel, flushing all buffered write operations. Output
+ functions raise a [Sys_error] exception when they are applied to a closed
+ output channel, except {!close} and {!flush}, which do nothing when applied
+ to an already closed channel. Note that {!close} may raise [Sys_error] if
+ the operating system signals an error when flushing or closing. *)
+
+val close_noerr : t -> unit
+(** Same as {!close}, but ignore all errors. *)
+
+val flush : t -> unit
+(** Flush the buffer associated with the given output channel, performing all
+ pending writes on that channel. Interactive programs must be careful about
+ flushing standard output and standard error at the right time. *)
+
+val flush_all : unit -> unit
+(** Flush all open output channels; ignore errors. *)
+
+val output_char : t -> char -> unit
+(** Write the character on the given output channel. *)
+
+val output_byte : t -> int -> unit
+(** Write one 8-bit integer (as the single character with that code) on the
+ given output channel. The given integer is taken modulo 256. *)
+
+val output_string : t -> string -> unit
+(** Write the string on the given output channel. *)
+
+val output_bytes : t -> bytes -> unit
+(** Write the byte sequence on the given output channel. *)
+
+val output : t -> bytes -> int -> int -> unit
+(** [output oc buf pos len] writes [len] characters from byte sequence [buf],
+ starting at offset [pos], to the given output channel [oc].
+
+ @raise Invalid_argument if [pos] and [len] do not designate a valid range of
+ [buf]. *)
+
+val output_substring : t -> string -> int -> int -> unit
+(** Same as {!output} but take a string as argument instead of a byte
+ sequence. *)
+
+val set_binary_mode : t -> bool -> unit
+(** [set_binary_mode oc true] sets the channel [oc] to binary mode: no
+ translations take place during output.
+
+ [set_binary_mode oc false] sets the channel [oc] to text mode: depending on
+ the operating system, some translations may take place during output. For
+ instance, under Windows, end-of-lines will be translated from [\n] to
+ [\r\n].
+
+ This function has no effect under operating systems that do not distinguish
+ between text mode and binary mode. *)
diff --git a/stdlib/stdlib.ml b/stdlib/stdlib.ml
index aac8fcc171..6268f3c592 100644
--- a/stdlib/stdlib.ml
+++ b/stdlib/stdlib.ml
@@ -599,6 +599,7 @@ module Fun = Fun
module Gc = Gc
module Genlex = Genlex
module Hashtbl = Hashtbl
+module In_channel = In_channel
module Int = Int
module Int32 = Int32
module Int64 = Int64
@@ -613,6 +614,7 @@ module Nativeint = Nativeint
module Obj = Obj
module Oo = Oo
module Option = Option
+module Out_channel = Out_channel
module Parsing = Parsing
module Pervasives = Pervasives
module Printexc = Printexc
diff --git a/stdlib/stdlib.mli b/stdlib/stdlib.mli
index c84caee3d3..0844af88b9 100644
--- a/stdlib/stdlib.mli
+++ b/stdlib/stdlib.mli
@@ -1128,12 +1128,12 @@ val really_input_string : in_channel -> int -> string
val input_byte : in_channel -> int
(** Same as {!Stdlib.input_char}, but return the 8-bit integer representing
the character.
- @raise End_of_file if an end of file was reached. *)
+ @raise End_of_file if the end of file was reached. *)
val input_binary_int : in_channel -> int
(** Read an integer encoded in binary format (4 bytes, big-endian)
from the given input channel. See {!Stdlib.output_binary_int}.
- @raise End_of_file if an end of file was reached while reading the
+ @raise End_of_file if the end of file was reached while reading the
integer. *)
val input_value : in_channel -> 'a
@@ -1399,6 +1399,7 @@ module Gc = Gc
module Genlex = Genlex
[@@deprecated "Use the camlp-streams library instead."]
module Hashtbl = Hashtbl
+module In_channel = In_channel
module Int = Int
module Int32 = Int32
module Int64 = Int64
@@ -1413,6 +1414,7 @@ module Nativeint = Nativeint
module Obj = Obj
module Oo = Oo
module Option = Option
+module Out_channel = Out_channel
module Parsing = Parsing
module Pervasives = Pervasives
[@@deprecated "Use Stdlib instead.\n\
diff --git a/testsuite/tests/basic/patmatch_for_multiple.ml b/testsuite/tests/basic/patmatch_for_multiple.ml
index 8f13ce43ae..0191e1c7bc 100644
--- a/testsuite/tests/basic/patmatch_for_multiple.ml
+++ b/testsuite/tests/basic/patmatch_for_multiple.ml
@@ -26,15 +26,15 @@ match (3, 2, 1) with
| _ -> false
;;
[%%expect{|
-(let (*match*/88 = 3 *match*/89 = 2 *match*/90 = 1)
+(let (*match*/90 = 3 *match*/91 = 2 *match*/92 = 1)
(catch
(catch
- (catch (if (!= *match*/89 3) (exit 3) (exit 1)) with (3)
- (if (!= *match*/88 1) (exit 2) (exit 1)))
+ (catch (if (!= *match*/91 3) (exit 3) (exit 1)) with (3)
+ (if (!= *match*/90 1) (exit 2) (exit 1)))
with (2) 0)
with (1) 1))
-(let (*match*/88 = 3 *match*/89 = 2 *match*/90 = 1)
- (catch (if (!= *match*/89 3) (if (!= *match*/88 1) 0 (exit 1)) (exit 1))
+(let (*match*/90 = 3 *match*/91 = 2 *match*/92 = 1)
+ (catch (if (!= *match*/91 3) (if (!= *match*/90 1) 0 (exit 1)) (exit 1))
with (1) 1))
- : bool = false
|}];;
@@ -47,26 +47,26 @@ match (3, 2, 1) with
| _ -> false
;;
[%%expect{|
-(let (*match*/93 = 3 *match*/94 = 2 *match*/95 = 1)
+(let (*match*/95 = 3 *match*/96 = 2 *match*/97 = 1)
(catch
(catch
(catch
- (if (!= *match*/94 3) (exit 6)
- (let (x/97 =a (makeblock 0 *match*/93 *match*/94 *match*/95))
- (exit 4 x/97)))
+ (if (!= *match*/96 3) (exit 6)
+ (let (x/99 =a (makeblock 0 *match*/95 *match*/96 *match*/97))
+ (exit 4 x/99)))
with (6)
- (if (!= *match*/93 1) (exit 5)
- (let (x/96 =a (makeblock 0 *match*/93 *match*/94 *match*/95))
- (exit 4 x/96))))
+ (if (!= *match*/95 1) (exit 5)
+ (let (x/98 =a (makeblock 0 *match*/95 *match*/96 *match*/97))
+ (exit 4 x/98))))
with (5) 0)
- with (4 x/91) (seq (ignore x/91) 1)))
-(let (*match*/93 = 3 *match*/94 = 2 *match*/95 = 1)
+ with (4 x/93) (seq (ignore x/93) 1)))
+(let (*match*/95 = 3 *match*/96 = 2 *match*/97 = 1)
(catch
- (if (!= *match*/94 3)
- (if (!= *match*/93 1) 0
- (exit 4 (makeblock 0 *match*/93 *match*/94 *match*/95)))
- (exit 4 (makeblock 0 *match*/93 *match*/94 *match*/95)))
- with (4 x/91) (seq (ignore x/91) 1)))
+ (if (!= *match*/96 3)
+ (if (!= *match*/95 1) 0
+ (exit 4 (makeblock 0 *match*/95 *match*/96 *match*/97)))
+ (exit 4 (makeblock 0 *match*/95 *match*/96 *match*/97)))
+ with (4 x/93) (seq (ignore x/93) 1)))
- : bool = false
|}];;
@@ -76,8 +76,8 @@ let _ = fun a b ->
| ((true, _) as _g)
| ((false, _) as _g) -> ()
[%%expect{|
-(function a/98[int] b/99 : int 0)
-(function a/98[int] b/99 : int 0)
+(function a/100[int] b/101 : int 0)
+(function a/100[int] b/101 : int 0)
- : bool -> 'a -> unit = <fun>
|}];;
@@ -96,8 +96,8 @@ let _ = fun a b -> match a, b with
| (false, _) as p -> p
(* outside, trivial *)
[%%expect {|
-(function a/102[int] b/103 (let (p/104 =a (makeblock 0 a/102 b/103)) p/104))
-(function a/102[int] b/103 (makeblock 0 a/102 b/103))
+(function a/104[int] b/105 (let (p/106 =a (makeblock 0 a/104 b/105)) p/106))
+(function a/104[int] b/105 (makeblock 0 a/104 b/105))
- : bool -> 'a -> bool * 'a = <fun>
|}]
@@ -106,8 +106,8 @@ let _ = fun a b -> match a, b with
| ((false, _) as p) -> p
(* inside, trivial *)
[%%expect{|
-(function a/106[int] b/107 (let (p/108 =a (makeblock 0 a/106 b/107)) p/108))
-(function a/106[int] b/107 (makeblock 0 a/106 b/107))
+(function a/108[int] b/109 (let (p/110 =a (makeblock 0 a/108 b/109)) p/110))
+(function a/108[int] b/109 (makeblock 0 a/108 b/109))
- : bool -> 'a -> bool * 'a = <fun>
|}];;
@@ -116,11 +116,11 @@ let _ = fun a b -> match a, b with
| (false as x, _) as p -> x, p
(* outside, simple *)
[%%expect {|
-(function a/112[int] b/113
- (let (x/114 =a[int] a/112 p/115 =a (makeblock 0 a/112 b/113))
- (makeblock 0 (int,*) x/114 p/115)))
-(function a/112[int] b/113
- (makeblock 0 (int,*) a/112 (makeblock 0 a/112 b/113)))
+(function a/114[int] b/115
+ (let (x/116 =a[int] a/114 p/117 =a (makeblock 0 a/114 b/115))
+ (makeblock 0 (int,*) x/116 p/117)))
+(function a/114[int] b/115
+ (makeblock 0 (int,*) a/114 (makeblock 0 a/114 b/115)))
- : bool -> 'a -> bool * (bool * 'a) = <fun>
|}]
@@ -129,11 +129,11 @@ let _ = fun a b -> match a, b with
| ((false as x, _) as p) -> x, p
(* inside, simple *)
[%%expect {|
-(function a/118[int] b/119
- (let (x/120 =a[int] a/118 p/121 =a (makeblock 0 a/118 b/119))
- (makeblock 0 (int,*) x/120 p/121)))
-(function a/118[int] b/119
- (makeblock 0 (int,*) a/118 (makeblock 0 a/118 b/119)))
+(function a/120[int] b/121
+ (let (x/122 =a[int] a/120 p/123 =a (makeblock 0 a/120 b/121))
+ (makeblock 0 (int,*) x/122 p/123)))
+(function a/120[int] b/121
+ (makeblock 0 (int,*) a/120 (makeblock 0 a/120 b/121)))
- : bool -> 'a -> bool * (bool * 'a) = <fun>
|}]
@@ -142,15 +142,15 @@ let _ = fun a b -> match a, b with
| (false, x) as p -> x, p
(* outside, complex *)
[%%expect{|
-(function a/128[int] b/129[int]
- (if a/128
- (let (x/130 =a[int] a/128 p/131 =a (makeblock 0 a/128 b/129))
- (makeblock 0 (int,*) x/130 p/131))
- (let (x/132 =a b/129 p/133 =a (makeblock 0 a/128 b/129))
- (makeblock 0 (int,*) x/132 p/133))))
-(function a/128[int] b/129[int]
- (if a/128 (makeblock 0 (int,*) a/128 (makeblock 0 a/128 b/129))
- (makeblock 0 (int,*) b/129 (makeblock 0 a/128 b/129))))
+(function a/130[int] b/131[int]
+ (if a/130
+ (let (x/132 =a[int] a/130 p/133 =a (makeblock 0 a/130 b/131))
+ (makeblock 0 (int,*) x/132 p/133))
+ (let (x/134 =a b/131 p/135 =a (makeblock 0 a/130 b/131))
+ (makeblock 0 (int,*) x/134 p/135))))
+(function a/130[int] b/131[int]
+ (if a/130 (makeblock 0 (int,*) a/130 (makeblock 0 a/130 b/131))
+ (makeblock 0 (int,*) b/131 (makeblock 0 a/130 b/131))))
- : bool -> bool -> bool * (bool * bool) = <fun>
|}]
@@ -160,19 +160,19 @@ let _ = fun a b -> match a, b with
-> x, p
(* inside, complex *)
[%%expect{|
-(function a/134[int] b/135[int]
+(function a/136[int] b/137[int]
(catch
- (if a/134
- (let (x/142 =a[int] a/134 p/143 =a (makeblock 0 a/134 b/135))
- (exit 10 x/142 p/143))
- (let (x/140 =a b/135 p/141 =a (makeblock 0 a/134 b/135))
- (exit 10 x/140 p/141)))
- with (10 x/136[int] p/137) (makeblock 0 (int,*) x/136 p/137)))
-(function a/134[int] b/135[int]
+ (if a/136
+ (let (x/144 =a[int] a/136 p/145 =a (makeblock 0 a/136 b/137))
+ (exit 10 x/144 p/145))
+ (let (x/142 =a b/137 p/143 =a (makeblock 0 a/136 b/137))
+ (exit 10 x/142 p/143)))
+ with (10 x/138[int] p/139) (makeblock 0 (int,*) x/138 p/139)))
+(function a/136[int] b/137[int]
(catch
- (if a/134 (exit 10 a/134 (makeblock 0 a/134 b/135))
- (exit 10 b/135 (makeblock 0 a/134 b/135)))
- with (10 x/136[int] p/137) (makeblock 0 (int,*) x/136 p/137)))
+ (if a/136 (exit 10 a/136 (makeblock 0 a/136 b/137))
+ (exit 10 b/137 (makeblock 0 a/136 b/137)))
+ with (10 x/138[int] p/139) (makeblock 0 (int,*) x/138 p/139)))
- : bool -> bool -> bool * (bool * bool) = <fun>
|}]
@@ -185,15 +185,15 @@ let _ = fun a b -> match a, b with
| (false as x, _) as p -> x, p
(* outside, onecase *)
[%%expect {|
-(function a/144[int] b/145[int]
- (if a/144
- (let (x/146 =a[int] a/144 _p/147 =a (makeblock 0 a/144 b/145))
- (makeblock 0 (int,*) x/146 [0: 1 1]))
- (let (x/148 =a[int] a/144 p/149 =a (makeblock 0 a/144 b/145))
- (makeblock 0 (int,*) x/148 p/149))))
-(function a/144[int] b/145[int]
- (if a/144 (makeblock 0 (int,*) a/144 [0: 1 1])
- (makeblock 0 (int,*) a/144 (makeblock 0 a/144 b/145))))
+(function a/146[int] b/147[int]
+ (if a/146
+ (let (x/148 =a[int] a/146 _p/149 =a (makeblock 0 a/146 b/147))
+ (makeblock 0 (int,*) x/148 [0: 1 1]))
+ (let (x/150 =a[int] a/146 p/151 =a (makeblock 0 a/146 b/147))
+ (makeblock 0 (int,*) x/150 p/151))))
+(function a/146[int] b/147[int]
+ (if a/146 (makeblock 0 (int,*) a/146 [0: 1 1])
+ (makeblock 0 (int,*) a/146 (makeblock 0 a/146 b/147))))
- : bool -> bool -> bool * (bool * bool) = <fun>
|}]
@@ -202,11 +202,11 @@ let _ = fun a b -> match a, b with
| ((false as x, _) as p) -> x, p
(* inside, onecase *)
[%%expect{|
-(function a/150[int] b/151
- (let (x/152 =a[int] a/150 p/153 =a (makeblock 0 a/150 b/151))
- (makeblock 0 (int,*) x/152 p/153)))
-(function a/150[int] b/151
- (makeblock 0 (int,*) a/150 (makeblock 0 a/150 b/151)))
+(function a/152[int] b/153
+ (let (x/154 =a[int] a/152 p/155 =a (makeblock 0 a/152 b/153))
+ (makeblock 0 (int,*) x/154 p/155)))
+(function a/152[int] b/153
+ (makeblock 0 (int,*) a/152 (makeblock 0 a/152 b/153)))
- : bool -> 'a -> bool * (bool * 'a) = <fun>
|}]
@@ -223,14 +223,14 @@ let _ =fun a b -> match a, b with
| (_, _) as p -> p
(* outside, tuplist *)
[%%expect {|
-(function a/163[int] b/164
+(function a/165[int] b/166
(catch
- (if a/163 (if b/164 (let (p/165 =a (field 0 b/164)) p/165) (exit 12))
+ (if a/165 (if b/166 (let (p/167 =a (field 0 b/166)) p/167) (exit 12))
(exit 12))
- with (12) (let (p/166 =a (makeblock 0 a/163 b/164)) p/166)))
-(function a/163[int] b/164
- (catch (if a/163 (if b/164 (field 0 b/164) (exit 12)) (exit 12)) with (12)
- (makeblock 0 a/163 b/164)))
+ with (12) (let (p/168 =a (makeblock 0 a/165 b/166)) p/168)))
+(function a/165[int] b/166
+ (catch (if a/165 (if b/166 (field 0 b/166) (exit 12)) (exit 12)) with (12)
+ (makeblock 0 a/165 b/166)))
- : bool -> bool tuplist -> bool * bool tuplist = <fun>
|}]
@@ -239,19 +239,19 @@ let _ = fun a b -> match a, b with
| ((_, _) as p) -> p
(* inside, tuplist *)
[%%expect{|
-(function a/167[int] b/168
+(function a/169[int] b/170
(catch
(catch
- (if a/167
- (if b/168 (let (p/172 =a (field 0 b/168)) (exit 13 p/172)) (exit 14))
+ (if a/169
+ (if b/170 (let (p/174 =a (field 0 b/170)) (exit 13 p/174)) (exit 14))
(exit 14))
- with (14) (let (p/171 =a (makeblock 0 a/167 b/168)) (exit 13 p/171)))
- with (13 p/169) p/169))
-(function a/167[int] b/168
+ with (14) (let (p/173 =a (makeblock 0 a/169 b/170)) (exit 13 p/173)))
+ with (13 p/171) p/171))
+(function a/169[int] b/170
(catch
(catch
- (if a/167 (if b/168 (exit 13 (field 0 b/168)) (exit 14)) (exit 14))
- with (14) (exit 13 (makeblock 0 a/167 b/168)))
- with (13 p/169) p/169))
+ (if a/169 (if b/170 (exit 13 (field 0 b/170)) (exit 14)) (exit 14))
+ with (14) (exit 13 (makeblock 0 a/169 b/170)))
+ with (13 p/171) p/171))
- : bool -> bool tuplist -> bool * bool tuplist = <fun>
|}]
diff --git a/testsuite/tests/generalized-open/gpr1506.ml b/testsuite/tests/generalized-open/gpr1506.ml
index c01c6db910..025e52ee43 100644
--- a/testsuite/tests/generalized-open/gpr1506.ml
+++ b/testsuite/tests/generalized-open/gpr1506.ml
@@ -103,9 +103,9 @@ include struct open struct type t = T end let x = T end
Line 1, characters 15-41:
1 | include struct open struct type t = T end let x = T end
^^^^^^^^^^^^^^^^^^^^^^^^^^
-Error: The type t/150 introduced by this open appears in the signature
+Error: The type t/152 introduced by this open appears in the signature
Line 1, characters 46-47:
- The value x has no valid type if t/150 is hidden
+ The value x has no valid type if t/152 is hidden
|}];;
module A = struct
@@ -123,9 +123,9 @@ Lines 3-6, characters 4-7:
4 | type t = T
5 | let x = T
6 | end
-Error: The type t/155 introduced by this open appears in the signature
+Error: The type t/157 introduced by this open appears in the signature
Line 7, characters 8-9:
- The value y has no valid type if t/155 is hidden
+ The value y has no valid type if t/157 is hidden
|}];;
module A = struct
@@ -142,9 +142,9 @@ Lines 3-5, characters 4-7:
3 | ....open struct
4 | type t = T
5 | end
-Error: The type t/160 introduced by this open appears in the signature
+Error: The type t/162 introduced by this open appears in the signature
Line 6, characters 8-9:
- The value y has no valid type if t/160 is hidden
+ The value y has no valid type if t/162 is hidden
|}]
(* It was decided to not allow this anymore. *)
diff --git a/testsuite/tests/typing-sigsubst/sigsubst.ml b/testsuite/tests/typing-sigsubst/sigsubst.ml
index 7cfa290283..c64c79ea5b 100644
--- a/testsuite/tests/typing-sigsubst/sigsubst.ml
+++ b/testsuite/tests/typing-sigsubst/sigsubst.ml
@@ -24,11 +24,11 @@ end
Line 3, characters 2-36:
3 | include Comparable with type t = t
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Error: Illegal shadowing of included type t/98 by t/102
+Error: Illegal shadowing of included type t/100 by t/104
Line 2, characters 2-19:
- Type t/98 came from this include
+ Type t/100 came from this include
Line 3, characters 2-23:
- The value print has no valid type if t/98 is shadowed
+ The value print has no valid type if t/100 is shadowed
|}]
module type Sunderscore = sig