From 92730427b78a4c0e555a34e6e4c7b11b7b5aec0b Mon Sep 17 00:00:00 2001 From: Stephane Glondu Date: Wed, 10 Jul 2019 14:49:44 +0200 Subject: [PATCH] New upstream version 4.06.1 --- .gitattributes | 1 + Changes | 61 +- VERSION | 2 +- asmcomp/closure.ml | 88 ++- asmcomp/cmmgen.ml | 2 - boot/ocamlc | Bin 2248118 -> 2250862 bytes boot/ocamldep | Bin 2155345 -> 2158089 bytes boot/ocamllex | Bin 285700 -> 285700 bytes bytecomp/matching.ml | 204 +++--- bytecomp/simplif.ml | 2 +- otherlibs/bigarray/bigarray_stubs.c | 2 +- testsuite/tests/basic-float/float_compare.ml | 6 + .../tests/basic-float/float_compare.reference | 1 + .../robustmatch.compilers.reference | 107 +++ testsuite/tests/basic-more/robustmatch.ml | 285 ++++++++ .../tests/basic-more/robustmatch.reference | 2 + testsuite/tests/basic/patmatch.ml | 239 +++++++ testsuite/tests/basic/patmatch.reference | 77 +++ testsuite/tests/raise-counts/a.ml | 12 + testsuite/tests/raise-counts/b.ml | 1 + testsuite/tests/raise-counts/main.ml | 9 + testsuite/tests/raise-counts/main.reference | 1 + testsuite/tests/raise-counts/ocamltests | 1 + testsuite/tests/typing-misc/polyvars.ml | 12 + testsuite/tests/typing-poly/poly.ml | 2 +- testsuite/tests/warnings/w04_failure.ml | 28 + .../tests/warnings/w04_failure.reference | 9 + typing/parmatch.ml | 616 +++++++++++++----- typing/parmatch.mli | 19 +- typing/typecore.ml | 5 +- typing/types.ml | 4 + typing/types.mli | 5 + 32 files changed, 1476 insertions(+), 327 deletions(-) create mode 100644 testsuite/tests/basic-float/float_compare.ml create mode 100644 testsuite/tests/basic-float/float_compare.reference create mode 100644 testsuite/tests/basic-more/robustmatch.compilers.reference create mode 100644 testsuite/tests/basic-more/robustmatch.ml create mode 100644 testsuite/tests/basic-more/robustmatch.reference create mode 100644 testsuite/tests/raise-counts/a.ml create mode 100644 testsuite/tests/raise-counts/b.ml create mode 100644 testsuite/tests/raise-counts/main.ml create mode 100644 testsuite/tests/raise-counts/main.reference create mode 100644 testsuite/tests/raise-counts/ocamltests create mode 100644 testsuite/tests/warnings/w04_failure.ml create mode 100644 testsuite/tests/warnings/w04_failure.reference diff --git a/.gitattributes b/.gitattributes index ecff398c..0d7fefb0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -147,6 +147,7 @@ testsuite/tests/docstrings/empty.ml text eol=lf testsuite/tests/functors/functors.ml text eol=lf testsuite/tests/translprim/module_coercion.ml text eol=lf testsuite/tests/warnings/w04.ml text eol=lf +testsuite/tests/warnings/w04_failure.ml text eol=lf testsuite/tests/warnings/w32.ml text eol=lf # These are forced to \n to allow the Cygwin testsuite to pass on a diff --git a/Changes b/Changes index 3f87e219..7128bbe8 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,32 @@ +OCaml 4.06.1 (16 Feb 2018): +--------------------------- + +### Bug fixes + +- MPR#7661, GPR#1459: fix faulty compilation of patterns + using extensible variants constructors + (Luc Maranget, review by Thomas Refis and Gabriel Scherer, report + by Abdelraouf Ouadjaout and Thibault Suzanne) + +- MPR#7702, GPR#1553: refresh raise counts when inlining a function + (Vincent Laviron, Xavier Clerc, report by Cheng Sun) + +- MPR#7704, GPR#1559: Soundness issue with private rows and pattern-matching + (Jacques Garrigue, report by Jeremy Yallop, review by Thomas Refis) + +- MPR#7705, GPR#1558: add missing bounds check in Bigarray.Genarray.nth_dim. + (Nicolás Ojeda Bär, report by Jeremy Yallop, review by Gabriel Scherer) + +- MPR#7713, GPR#1587: Make pattern matching warnings more robust + to ill-typed columns; this is a backport of GPR#1550 from 4.07+dev + (Thomas Refis, review by Gabriel Scherer, report by Andreas Hauptmann) + +- GPR#1470: Don't commute negation with float comparison + (Leo White, review by Xavier Leroy) + +- GPR#1538: Make pattern matching compilation more robust to ill-typed columns + (Gabriel Scherer and Thomas Refis, review by Luc Maranget) + OCaml 4.06.0 (3 Nov 2017): -------------------------- @@ -28,7 +57,7 @@ OCaml 4.06.0 (3 Nov 2017): - GPR#1118: Support inherited field in object type expression type t = < m : int > type u = < n : int; t; k : int > - (Runhang Li, reivew by Jeremy Yallop, Leo White, Jacques Garrigue, + (Runhang Li, review by Jeremy Yallop, Leo White, Jacques Garrigue, and Florian Angeletti) * GPR#1232: Support Unicode character escape sequences in string @@ -92,20 +121,20 @@ OCaml 4.06.0 (3 Nov 2017): - MPR#1771, MPR#7309, GPR#1026: Add update to maps. Allows to update a binding in a map or create a new binding if the key had no binding val update: key -> ('a option -> 'a option) -> 'a t -> 'a t - (Sébastien Briais, review by Daniel Buenzli, Alain Frisch and + (Sébastien Briais, review by Daniel Bünzli, Alain Frisch and Gabriel Scherer) - MPR#7515, GPR#1147: Arg.align now optionally uses the tab character '\t' to separate the "unaligned" and "aligned" parts of the documentation string. If tab is not present, then space is used as a fallback. Allows to have spaces in the unaligned part, which is useful for Tuple options. - (Nicolas Ojeda Bar, review by Alain Frisch and Gabriel Scherer) + (Nicolás Ojeda Bär, review by Alain Frisch and Gabriel Scherer) * GPR#615: Format, add symbolic formatters that output symbolic pretty-printing items. New fields have been added to the formatter_out_functions record, thus this change will break any code building such record from scratch. - When building Format.formatter_out_functions values redefinining the out_spaces field, + When building Format.formatter_out_functions values redefining the out_spaces field, "{ fmt_out_funs with out_spaces = f; }" should be replaced by "{ fmt_out_funs with out_spaces = f; out_indent = f; }" to maintain the old behavior. (Richard Bonichon and Pierre Weis, review by Alain Frisch, original request by @@ -156,7 +185,7 @@ OCaml 4.06.0 (3 Nov 2017): - MPR#7564, GPR#1211: Allow forward slashes in the target of symbolic links created by Unix.symlink under Windows. - (Nicolas Ojeda Bar, review by David Allsopp) + (Nicolás Ojeda Bär, review by David Allsopp) * MPR#7640, GPR#1414: reimplementation of Unix.execvpe to fix issues with the 4.05 implementation. The main issue is that the current @@ -176,7 +205,7 @@ OCaml 4.06.0 (3 Nov 2017): - GPR#1217: Restrict Unix.environment in privileged contexts; add Unix.unsafe_environment. - (Jeremy Yallop, review by Mark Shinwell, Nicolas Ojeda Bar, + (Jeremy Yallop, review by Mark Shinwell, Nicolás Ojeda Bär, Damien Doligez and Hannes Mehnert) - GPR#1321: Reimplement Unix.isatty on Windows. It no longer returns true for @@ -248,8 +277,8 @@ OCaml 4.06.0 (3 Nov 2017): allocator represents a trade-off between worse generated code performance for higher compilation speed (especially interesting in some cases graph coloring is necessarily quadratic). - (Marcell Fischbach and Benedikt Meurer, adapted by Nicolas Ojeda - Bar, review by Nicolas Ojeda Bar and Alain Frisch) + (Marcell Fischbach and Benedikt Meurer, adapted by Nicolás Ojeda Bär, review + by Nicolás Ojeda Bär and Alain Frisch) - MPR#6927, GPR#988: On macOS, when compiling bytecode stubs, plugins, and shared libraries through -output-obj, generate dylibs instead of @@ -435,7 +464,7 @@ OCaml 4.06.0 (3 Nov 2017): * MPR#3771, GPR#153, GPR#1200, GPR#1357, GPR#1362, GPR#1363, GPR#1369, GPR#1398, GPR#1446, GPR#1448: Unicode support for the Windows runtime. - (ygrek, Nicolas Ojeda Bar, review by Alain Frisch, David Allsopp, Damien + (ygrek, Nicolás Ojeda Bär, review by Alain Frisch, David Allsopp, Damien Doligez) * MPR#7594, GPR#1274, GPR#1368: String_val now returns 'const char*', not @@ -464,7 +493,7 @@ OCaml 4.06.0 (3 Nov 2017): - GPR#1086: in Sys.getcwd, just fail instead of calling getwd() if HAS_GETCWD is not set. (Report and first fix by Sebastian Markbåge, final fix by Xavier Leroy, - review by MarK Shinwell) + review by Mark Shinwell) - GPR#1269: Remove 50ms delay at exit for programs using threads (Valentin Gatien-Baron, review by Stephen Dolan) @@ -953,7 +982,7 @@ OCaml 4.05.0 (13 Jul 2017): - GPR#1042: Fix escaping of command-line arguments in Unix.create_process{,_env} under Windows. Arguments with tabs should now be received verbatim by the child process. - (Nicolas Ojeda Bar, Andreas Hauptmann review by Xavier Leroy) + (Nicolás Ojeda Bär, Andreas Hauptmann review by Xavier Leroy) ### Debugging and profiling: @@ -1085,7 +1114,7 @@ OCaml 4.05.0 (13 Jul 2017): - GPR#803: new ocamllex-based tool to extract bytecode compiler opcode information from C headers. - (Nicolas Ojeda Bar) + (Nicolás Ojeda Bär) - GPR#827: install missing mli and cmti files, new make target install-compiler-sources for installation of compiler-libs ml files @@ -1739,7 +1768,7 @@ OCaml 4.04.0 (4 Nov 2016): cf. PR#7313, meaning that you may sometimes need to add type annotations to explicitly instantiate non-generalizable type variables. (Jacques Garrigue, following discussion with Jeremy Yallop, - Nicolas Ojeda Bar and Alain Frisch) + Nicolás Ojeda Bär and Alain Frisch) - PR#7112: Aliased arguments ignored for equality of module types (Jacques Garrigue, report by Leo White) @@ -1761,7 +1790,7 @@ OCaml 4.04.0 (4 Nov 2016): (Pierre Chambart, report by Reed Wilson, review by Mark Shinwell) - PR#7260: GADT + subtyping compile time crash - (Jacques Garrigue, report by Nicolas Ojeda Bar) + (Jacques Garrigue, report by Nicolás Ojeda Bär) - PR#7269: Segfault from conjunctive constraints in GADT (Jacques Garrigue, report by Stephen Dolan) @@ -1816,7 +1845,7 @@ OCaml 4.04.0 (4 Nov 2016): (Bogdan Tătăroiu, review by Thomas Braibant and Alain Frisch) - GPR#700: Fix maximum weak bucket size - (Nicolas Ojeda Bar, review by François Bobot) + (Nicolás Ojeda Bär, review by François Bobot) - GPR#708 Allow more module aliases in strengthening (Leo White) @@ -2141,7 +2170,7 @@ OCaml 4.03.0 (25 Apr 2016): - GPR#545: use reraise to preserve backtrace on `match .. with exception e -> raise e` - (Nicolas Ojeda Bar, review by Gabriel Scherer) + (Nicolás Ojeda Bär, review by Gabriel Scherer) ### Runtime system: diff --git a/VERSION b/VERSION index 1b7a77c8..33d444c9 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -4.06.0 +4.06.1 # The version string is the first line of this file. # It must be in the format described in stdlib/sys.mli diff --git a/asmcomp/closure.ml b/asmcomp/closure.ml index e86ecb6b..4fdb3778 100644 --- a/asmcomp/closure.ml +++ b/asmcomp/closure.ml @@ -502,7 +502,8 @@ let simplif_prim fpc p (args, approxs as args_approxs) dbg = (* Substitute variables in a [ulambda] term (a body of an inlined function) and perform some more simplifications on integer primitives. Also perform alpha-conversion on let-bound identifiers to avoid - clashes with locally-generated identifiers. + clashes with locally-generated identifiers, and refresh raise counts + in order to avoid clashes with inlined code from other modules. The variables must not be assigned in the term. This is used to substitute "trivial" arguments for parameters during inline expansion, and also for the translation of let rec @@ -527,18 +528,18 @@ let subst_debuginfo loc dbg = else dbg -let rec substitute loc fpc sb ulam = +let rec substitute loc fpc sb rn ulam = match ulam with Uvar v -> begin try Tbl.find v sb with Not_found -> ulam end | Uconst _ -> ulam | Udirect_apply(lbl, args, dbg) -> let dbg = subst_debuginfo loc dbg in - Udirect_apply(lbl, List.map (substitute loc fpc sb) args, dbg) + Udirect_apply(lbl, List.map (substitute loc fpc sb rn) args, dbg) | Ugeneric_apply(fn, args, dbg) -> let dbg = subst_debuginfo loc dbg in - Ugeneric_apply(substitute loc fpc sb fn, - List.map (substitute loc fpc sb) args, dbg) + Ugeneric_apply(substitute loc fpc sb rn fn, + List.map (substitute loc fpc sb rn) args, dbg) | Uclosure(defs, env) -> (* Question: should we rename function labels as well? Otherwise, there is a risk that function labels are not globally unique. @@ -548,12 +549,12 @@ let rec substitute loc fpc sb ulam = - When we substitute offsets for idents bound by let rec in [close], case [Lletrec], we discard the original let rec body and use only the substituted term. *) - Uclosure(defs, List.map (substitute loc fpc sb) env) - | Uoffset(u, ofs) -> Uoffset(substitute loc fpc sb u, ofs) + Uclosure(defs, List.map (substitute loc fpc sb rn) env) + | Uoffset(u, ofs) -> Uoffset(substitute loc fpc sb rn u, ofs) | Ulet(str, kind, id, u1, u2) -> let id' = Ident.rename id in - Ulet(str, kind, id', substitute loc fpc sb u1, - substitute loc fpc (Tbl.add id (Uvar id') sb) u2) + Ulet(str, kind, id', substitute loc fpc sb rn u1, + substitute loc fpc (Tbl.add id (Uvar id') sb) rn u2) | Uletrec(bindings, body) -> let bindings1 = List.map (fun (id, rhs) -> (id, Ident.rename id, rhs)) bindings in @@ -563,17 +564,17 @@ let rec substitute loc fpc sb ulam = bindings1 sb in Uletrec( List.map - (fun (_id, id', rhs) -> (id', substitute loc fpc sb' rhs)) + (fun (_id, id', rhs) -> (id', substitute loc fpc sb' rn rhs)) bindings1, - substitute loc fpc sb' body) + substitute loc fpc sb' rn body) | Uprim(p, args, dbg) -> - let sargs = List.map (substitute loc fpc sb) args in + let sargs = List.map (substitute loc fpc sb rn) args in let dbg = subst_debuginfo loc dbg in let (res, _) = simplif_prim fpc p (sargs, List.map approx_ulam sargs) dbg in res | Uswitch(arg, sw, dbg) -> - let sarg = substitute loc fpc sb arg in + let sarg = substitute loc fpc sb rn arg in let action = (* Unfortunately, we cannot easily deal with the case of a constructed block (makeblock) bound to a local @@ -589,64 +590,79 @@ let rec substitute loc fpc sb ulam = | _ -> None in begin match action with - | Some u -> substitute loc fpc sb u + | Some u -> substitute loc fpc sb rn u | None -> Uswitch(sarg, { sw with us_actions_consts = - Array.map (substitute loc fpc sb) sw.us_actions_consts; + Array.map (substitute loc fpc sb rn) sw.us_actions_consts; us_actions_blocks = - Array.map (substitute loc fpc sb) sw.us_actions_blocks; + Array.map (substitute loc fpc sb rn) sw.us_actions_blocks; }, dbg) end | Ustringswitch(arg,sw,d) -> Ustringswitch - (substitute loc fpc sb arg, - List.map (fun (s,act) -> s,substitute loc fpc sb act) sw, - Misc.may_map (substitute loc fpc sb) d) + (substitute loc fpc sb rn arg, + List.map (fun (s,act) -> s,substitute loc fpc sb rn act) sw, + Misc.may_map (substitute loc fpc sb rn) d) | Ustaticfail (nfail, args) -> - Ustaticfail (nfail, List.map (substitute loc fpc sb) args) + let nfail = + match rn with + | Some rn -> + begin try + Tbl.find nfail rn + with Not_found -> + fatal_errorf "Closure.split_list: invalid nfail (%d)" nfail + end + | None -> nfail in + Ustaticfail (nfail, List.map (substitute loc fpc sb rn) args) | Ucatch(nfail, ids, u1, u2) -> + let nfail, rn = + match rn with + | Some rn -> + let new_nfail = next_raise_count () in + new_nfail, Some (Tbl.add nfail new_nfail rn) + | None -> nfail, rn in let ids' = List.map Ident.rename ids in let sb' = List.fold_right2 (fun id id' s -> Tbl.add id (Uvar id') s) ids ids' sb in - Ucatch(nfail, ids', substitute loc fpc sb u1, substitute loc fpc sb' u2) + Ucatch(nfail, ids', substitute loc fpc sb rn u1, substitute loc fpc sb' rn u2) | Utrywith(u1, id, u2) -> let id' = Ident.rename id in - Utrywith(substitute loc fpc sb u1, id', - substitute loc fpc (Tbl.add id (Uvar id') sb) u2) + Utrywith(substitute loc fpc sb rn u1, id', + substitute loc fpc (Tbl.add id (Uvar id') sb) rn u2) | Uifthenelse(u1, u2, u3) -> - begin match substitute loc fpc sb u1 with + begin match substitute loc fpc sb rn u1 with Uconst (Uconst_ptr n) -> - if n <> 0 then substitute loc fpc sb u2 else substitute loc fpc sb u3 + if n <> 0 then substitute loc fpc sb rn u2 else substitute loc fpc sb rn u3 | Uprim(Pmakeblock _, _, _) -> - substitute loc fpc sb u2 + substitute loc fpc sb rn u2 | su1 -> - Uifthenelse(su1, substitute loc fpc sb u2, substitute loc fpc sb u3) + Uifthenelse(su1, substitute loc fpc sb rn u2, substitute loc fpc sb rn u3) end | Usequence(u1, u2) -> - Usequence(substitute loc fpc sb u1, substitute loc fpc sb u2) + Usequence(substitute loc fpc sb rn u1, substitute loc fpc sb rn u2) | Uwhile(u1, u2) -> - Uwhile(substitute loc fpc sb u1, substitute loc fpc sb u2) + Uwhile(substitute loc fpc sb rn u1, substitute loc fpc sb rn u2) | Ufor(id, u1, u2, dir, u3) -> let id' = Ident.rename id in - Ufor(id', substitute loc fpc sb u1, substitute loc fpc sb u2, dir, - substitute loc fpc (Tbl.add id (Uvar id') sb) u3) + Ufor(id', substitute loc fpc sb rn u1, substitute loc fpc sb rn u2, dir, + substitute loc fpc (Tbl.add id (Uvar id') sb) rn u3) | Uassign(id, u) -> let id' = try match Tbl.find id sb with Uvar i -> i | _ -> assert false with Not_found -> id in - Uassign(id', substitute loc fpc sb u) + Uassign(id', substitute loc fpc sb rn u) | Usend(k, u1, u2, ul, dbg) -> let dbg = subst_debuginfo loc dbg in - Usend(k, substitute loc fpc sb u1, substitute loc fpc sb u2, - List.map (substitute loc fpc sb) ul, dbg) + Usend(k, substitute loc fpc sb rn u1, substitute loc fpc sb rn u2, + List.map (substitute loc fpc sb rn) ul, dbg) | Uunreachable -> Uunreachable @@ -662,7 +678,7 @@ let no_effects = function let rec bind_params_rec loc fpc subst params args body = match (params, args) with - ([], []) -> substitute loc fpc subst body + ([], []) -> substitute loc fpc subst (Some Tbl.empty) body | (p1 :: pl, a1 :: al) -> if is_simple_argument a1 then bind_params_rec loc fpc (Tbl.add p1 a1 subst) pl al body @@ -947,7 +963,7 @@ let rec close fenv cenv = function Tbl.add id (Uoffset(Uvar clos_ident, pos)) sb) infos Tbl.empty in (Ulet(Immutable, Pgenval, clos_ident, clos, - substitute Location.none !Clflags.float_const_prop sb ubody), + substitute Location.none !Clflags.float_const_prop sb None ubody), approx) end else begin (* General case: recursive definition of values *) diff --git a/asmcomp/cmmgen.ml b/asmcomp/cmmgen.ml index ad1e5853..483123f4 100644 --- a/asmcomp/cmmgen.ml +++ b/asmcomp/cmmgen.ml @@ -292,8 +292,6 @@ let mk_not dbg cmm = tag_int (Cop(Ccmpi (negate_comparison cmp), [c1; c2], dbg'')) dbg' | Cop(Ccmpa cmp, [c1; c2], dbg'') -> tag_int (Cop(Ccmpa (negate_comparison cmp), [c1; c2], dbg'')) dbg' - | Cop(Ccmpf cmp, [c1; c2], dbg'') -> - tag_int (Cop(Ccmpf (negate_comparison cmp), [c1; c2], dbg'')) dbg' | _ -> (* 0 -> 3, 1 -> 1 *) Cop(Csubi, [Cconst_int 3; Cop(Clsl, [c; Cconst_int 1], dbg)], dbg) diff --git a/boot/ocamlc b/boot/ocamlc index 95c6f59d5197c18f58c468294a37dd5a47101a10..a73dfdead12b0b7c8f83ae6c2a6e177c3ae417bb 100755 GIT binary patch delta 51840 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 delta 49990 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 V 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 diff --git a/boot/ocamldep b/boot/ocamldep index b59eabb31c18db40bd4c43030ba7e96c2abf89ad..feec830cfeae2eef6a7c4137f03fc64ada83db26 100755 GIT binary patch delta 45993 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 OZ+3s|V}<-?xBoARhMx@p delta 44367 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 diff --git a/boot/ocamllex b/boot/ocamllex index 084dce874edfd9dec2e9ca3bc3f5089e54b5c2ca..36fe17f9811f598d62c9982799c394b6746e0abd 100755 GIT binary patch delta 23 fcmZqKA=t7*u%U&qg=q`3`d>!F?HYfX@5BKBZSx6C delta 23 fcmZqKA=t7*u%U&qg=q`3`d>za?HYfX@5BKBZR`n4 diff --git a/bytecomp/matching.ml b/bytecomp/matching.ml index 25a819cc..32e8043d 100644 --- a/bytecomp/matching.ml +++ b/bytecomp/matching.ml @@ -33,6 +33,18 @@ let dbg = false Now, see Lefessant-Maranget ``Optimizing Pattern-Matching'' ICFP'2001 *) +(* + Compatibility predicate that considers potential rebindings of constructors + of an extension type. + + "may_compat p q" returns false when p and q never admit a common instance; + returns true when they may have a common instance. +*) + +module MayCompat = + Parmatch.Compat (struct let equal = Types.may_equal_constr end) +let may_compat = MayCompat.compat +and may_compats = MayCompat.compats (* Many functions on the various data structures of the algorithm : @@ -43,6 +55,7 @@ let dbg = false - Jump summaries: mapping from exit numbers to contexts *) + let string_of_lam lam = Printlambda.lambda Format.str_formatter lam ; Format.flush_str_formatter () @@ -170,23 +183,13 @@ let ctx_matcher p = let p = normalize_pat p in match p.pat_desc with | Tpat_construct (_, cstr,omegas) -> - begin match cstr.cstr_tag with - | Cstr_extension _ -> - let nargs = List.length omegas in - (fun q rem -> match q.pat_desc with - | Tpat_construct (_, _cstr',args) - when List.length args = nargs -> - p,args @ rem - | Tpat_any -> p,omegas @ rem - | _ -> raise NoMatch) - | _ -> - (fun q rem -> match q.pat_desc with - | Tpat_construct (_, cstr',args) - when cstr.cstr_tag=cstr'.cstr_tag -> - p,args @ rem - | Tpat_any -> p,omegas @ rem - | _ -> raise NoMatch) - end + (fun q rem -> match q.pat_desc with + | Tpat_construct (_, cstr',args) +(* NB: may_constr_equal considers (potential) constructor rebinding *) + when Types.may_equal_constr cstr cstr' -> + p,args@rem + | Tpat_any -> p,omegas @ rem + | _ -> raise NoMatch) | Tpat_constant cst -> (fun q rem -> match q.pat_desc with | Tpat_constant cst' when const_compare cst cst' = 0 -> @@ -208,24 +211,29 @@ let ctx_matcher p = | Tpat_array omegas -> let len = List.length omegas in (fun q rem -> match q.pat_desc with - | Tpat_array args when List.length args=len -> - p,args @ rem + | Tpat_array args when List.length args = len -> p,args @ rem | Tpat_any -> p, omegas @ rem | _ -> raise NoMatch) | Tpat_tuple omegas -> + let len = List.length omegas in (fun q rem -> match q.pat_desc with - | Tpat_tuple args -> p,args @ rem - | _ -> p, omegas @ rem) - | Tpat_record (l,_) -> (* Records are normalized *) + | Tpat_tuple args when List.length args = len -> p,args @ rem + | Tpat_any -> p, omegas @ rem + | _ -> raise NoMatch) + | Tpat_record (((_, lbl, _) :: _) as l,_) -> (* Records are normalized *) + let len = Array.length lbl.lbl_all in (fun q rem -> match q.pat_desc with - | Tpat_record (l',_) -> + | Tpat_record (((_, lbl', _) :: _) as l',_) + when Array.length lbl'.lbl_all = len -> let l' = all_record_args l' in p, List.fold_right (fun (_, _,p) r -> p::r) l' rem - | _ -> p,List.fold_right (fun (_, _,p) r -> p::r) l rem) + | Tpat_any -> p,List.fold_right (fun (_, _,p) r -> p::r) l rem + | _ -> raise NoMatch) | Tpat_lazy omega -> (fun q rem -> match q.pat_desc with | Tpat_lazy arg -> p, (arg::rem) - | _ -> p, (omega::rem)) + | Tpat_any -> p, (omega::rem) + | _ -> raise NoMatch) | _ -> fatal_error "Matching.ctx_matcher" @@ -287,10 +295,7 @@ let ctx_lub p ctx = let ctx_match ctx pss = List.exists - (fun {right=qs} -> - List.exists - (fun ps -> compats qs ps) - pss) + (fun {right=qs} -> List.exists (fun ps -> may_compats qs ps) pss) ctx type jumps = (int * ctx list) list @@ -420,7 +425,10 @@ let pretty_def def = def ; prerr_endline "+++++++++++++++++++++" -let pretty_pm pm = pretty_cases pm.cases +let pretty_pm pm = + pretty_cases pm.cases ; + if pm.default <> [] then + pretty_def pm.default let rec pretty_precompiled = function @@ -538,37 +546,11 @@ let up_ok_action act1 act2 = with | Exit -> false -(* Nothing is known about exception/extension patterns, - because of potential rebind *) -let rec exc_inside p = match p.pat_desc with - | Tpat_construct (_,{cstr_tag=Cstr_extension _},_) -> true - | Tpat_any|Tpat_constant _|Tpat_var _ - | Tpat_construct (_,_,[]) - | Tpat_variant (_,None,_) - -> false - | Tpat_construct (_,_,ps) - | Tpat_tuple ps - | Tpat_array ps - -> exc_insides ps - | Tpat_variant (_, Some q,_) - | Tpat_alias (q,_,_) - | Tpat_lazy q - -> exc_inside q - | Tpat_record (lps,_) -> - List.exists (fun (_,_,p) -> exc_inside p) lps - | Tpat_or (p1,p2,_) -> exc_inside p1 || exc_inside p2 - -and exc_insides ps = List.exists exc_inside ps - let up_ok (ps,act_p) l = - if exc_insides ps then match l with [] -> true | _::_ -> false - else - List.for_all - (fun (qs,act_q) -> - up_ok_action act_p act_q || - not (Parmatch.compats ps qs)) - l - + List.for_all + (fun (qs,act_q) -> + up_ok_action act_p act_q || not (may_compats ps qs)) + l (* The simplify function normalizes the first column of the match @@ -663,16 +645,6 @@ let rec what_is_cases cases = match cases with (* A few operations on default environments *) let as_matrix cases = get_mins le_pats (List.map (fun (ps,_) -> ps) cases) -(* For extension matching, record no information in matrix *) -let as_matrix_omega cases = - get_mins le_pats - (List.map - (fun (ps,_) -> - match ps with - | [] -> assert false - | _::ps -> omega::ps) - cases) - let cons_default matrix raise_num default = match matrix with | [] -> default @@ -684,7 +656,7 @@ let default_compat p def = let qss = List.fold_right (fun qs r -> match qs with - | q::rem when Parmatch.compat p q -> rem::r + | q::rem when may_compat p q -> rem::r | _ -> r) pss [] in match qss with @@ -801,7 +773,7 @@ let is_or p = match p.pat_desc with | _ -> false (* Conditions for appending to the Or matrix *) -let conda p q = not (compat p q) +let conda p q = not (may_compat p q) and condb act ps qs = not (is_guarded act) && Parmatch.le_pats qs ps let or_ok p ps l = @@ -830,7 +802,7 @@ let insert_or_append p ps act ors no = let rec attempt seen = function | (q::qs,act_q) as cl::rem -> if is_or q then begin - if compat p q then + if may_compat p q then if IdentSet.is_empty (extract_vars IdentSet.empty p) && IdentSet.is_empty (extract_vars IdentSet.empty q) && @@ -841,7 +813,7 @@ let insert_or_append p ps act ors no = or_ok p ps not_e && (* check append condition for head of O *) List.for_all (* check insert condition for tail of O *) (fun cl -> match cl with - | (q::_,_) -> not (compat p q) + | (q::_,_) -> not (may_compat p q) | _ -> assert false) seen then (* insert *) @@ -948,7 +920,7 @@ and split_naive cls args def k = | [] -> let yes = List.rev yes in { me = Pm {cases=yes; args=args; default=def;} ; - matrix = as_matrix_omega yes ; + matrix = as_matrix yes ; top_default=def}, k | (p::_,_ as cl)::rem -> @@ -962,7 +934,7 @@ and split_naive cls args def k = let idef = next_raise_count () in let def = cons_default matrix idef def in { me = Pm {cases=yes; args=args; default=def} ; - matrix = as_matrix_omega yes ; + matrix = as_matrix yes ; top_default = def; }, (idef,next)::nexts else @@ -972,7 +944,7 @@ and split_naive cls args def k = let idef = next_raise_count () in let def = cons_default matrix idef def in { me = Pm {cases=yes; args=args; default=def} ; - matrix = as_matrix_omega yes ; + matrix = as_matrix yes ; top_default = def; }, (idef,next)::nexts | _ -> assert false @@ -1112,21 +1084,12 @@ and dont_precompile_var args cls def k = matrix=as_matrix cls ; top_default=def},k -and is_exc p = match p.pat_desc with -| Tpat_or (p1,p2,_) -> is_exc p1 || is_exc p2 -| Tpat_alias (p,_,_) -> is_exc p -| Tpat_construct (_,{cstr_tag=Cstr_extension _},_) -> true -| _ -> false - and precompile_or argo cls ors args def k = match ors with | [] -> split_constr cls args def k | _ -> let rec do_cases = function | ({pat_desc=Tpat_or _} as orp::patl, action)::rem -> - let do_opt = not (is_exc orp) in - let others,rem = - if do_opt then get_equiv orp rem - else [],rem in + let others,rem = get_equiv orp rem in let orpm = {cases = (patl, action):: @@ -1136,7 +1099,7 @@ and precompile_or argo cls ors args def k = match ors with | _ -> assert false) others ; args = (match args with _::r -> r | _ -> assert false) ; - default = default_compat (if do_opt then orp else omega) def} in + default = default_compat orp def} in let vars = IdentSet.elements (IdentSet.inter @@ -1149,19 +1112,18 @@ and precompile_or argo cls ors args def k = match ors with Lstaticraise (or_num, List.map (fun v -> Lvar v) vs) in - let do_optrec,body,handlers = do_cases rem in - do_opt && do_optrec, + let body,handlers = do_cases rem in explode_or_pat argo new_patl mk_new_action body vars [] orp, - let mat = if do_opt then [[orp]] else [[omega]] in + let mat = [[orp]] in ((mat, or_num, vars , orpm):: handlers) | cl::rem -> - let b,new_ord,new_to_catch = do_cases rem in - b,cl::new_ord,new_to_catch - | [] -> true,[],[] in + let new_ord,new_to_catch = do_cases rem in + cl::new_ord,new_to_catch + | [] -> [],[] in - let do_opt,end_body, handlers = do_cases ors in - let matrix = (if do_opt then as_matrix else as_matrix_omega) (cls@ors) + let end_body, handlers = do_cases ors in + let matrix = as_matrix (cls@ors) and body = {cases=cls@end_body ; args=args ; default=def} in {me = PmOr {body=body ; handlers=handlers ; or_matrix=matrix} ; matrix=matrix ; @@ -1302,18 +1264,23 @@ let get_args_constr p rem = match p with | {pat_desc=Tpat_construct (_, _, args)} -> args @ rem | _ -> assert false +(* NB: matcher_constr applies to default matrices. + + In that context, matching by constructors of extensible + types degrades to arity checking, due to potential rebinding. + This comparison is performed by Types.may_equal_constr. +*) + let matcher_constr cstr = match cstr.cstr_arity with | 0 -> let rec matcher_rec q rem = match q.pat_desc with | Tpat_or (p1,p2,_) -> begin - try - matcher_rec p1 rem - with - | NoMatch -> matcher_rec p2 rem + try matcher_rec p1 rem + with NoMatch -> matcher_rec p2 rem end - | Tpat_construct (_, cstr1, []) when cstr.cstr_tag = cstr1.cstr_tag -> - rem + | Tpat_construct (_, cstr',[]) + when Types.may_equal_constr cstr cstr' -> rem | Tpat_any -> rem | _ -> raise NoMatch in matcher_rec @@ -1333,16 +1300,16 @@ let matcher_constr cstr = match cstr.cstr_arity with rem | _, _ -> assert false end - | Tpat_construct (_, cstr1, [arg]) - when cstr.cstr_tag = cstr1.cstr_tag -> arg::rem + | Tpat_construct (_, cstr', [arg]) + when Types.may_equal_constr cstr cstr' -> arg::rem | Tpat_any -> omega::rem | _ -> raise NoMatch in matcher_rec | _ -> fun q rem -> match q.pat_desc with | Tpat_or (_,_,_) -> raise OrPat - | Tpat_construct (_, cstr1, args) - when cstr.cstr_tag = cstr1.cstr_tag -> args @ rem + | Tpat_construct (_,cstr',args) + when Types.may_equal_constr cstr cstr' -> args @ rem | Tpat_any -> Parmatch.omegas cstr.cstr_arity @ rem | _ -> raise NoMatch @@ -1465,8 +1432,10 @@ let get_arg_lazy p rem = match p with let matcher_lazy p rem = match p.pat_desc with | Tpat_or (_,_,_) -> raise OrPat -| Tpat_var _ -> get_arg_lazy omega rem -| _ -> get_arg_lazy p rem +| Tpat_any +| Tpat_var _ -> omega :: rem +| Tpat_lazy arg -> arg :: rem +| _ -> raise NoMatch (* Inlining the tag tests before calling the primitive that works on lazy blocks. This is also used in translcore.ml. @@ -1592,8 +1561,10 @@ let get_args_tuple arity p rem = match p with let matcher_tuple arity p rem = match p.pat_desc with | Tpat_or (_,_,_) -> raise OrPat -| Tpat_var _ -> get_args_tuple arity omega rem -| _ -> get_args_tuple arity p rem +| Tpat_any +| Tpat_var _ -> omegas arity @ rem +| Tpat_tuple args when List.length args = arity -> args @ rem +| _ -> raise NoMatch let make_tuple_matching loc arity def = function [] -> fatal_error "Matching.make_tuple_matching" @@ -1629,8 +1600,14 @@ let get_args_record num_fields p rem = match p with let matcher_record num_fields p rem = match p.pat_desc with | Tpat_or (_,_,_) -> raise OrPat -| Tpat_var _ -> get_args_record num_fields omega rem -| _ -> get_args_record num_fields p rem +| Tpat_any +| Tpat_var _ -> + record_matching_line num_fields [] @ rem +| Tpat_record ([], _) when num_fields = 0 -> rem +| Tpat_record ((_, lbl, _) :: _ as lbl_pat_list, _) + when Array.length lbl.lbl_all = num_fields -> + record_matching_line num_fields lbl_pat_list @ rem +| _ -> raise NoMatch let make_record_matching loc all_labels def = function [] -> fatal_error "Matching.make_record_matching" @@ -2553,7 +2530,8 @@ let compile_orhandlers compile_fun lambda1 total1 ctx to_catch = | (mat,i,vars,pm)::rem -> begin try let ctx = select_columns mat ctx in - let handler_i, total_i = compile_fun ctx pm in + let handler_i, total_i = + compile_fun ctx pm in match raw_action r with | Lstaticraise (j,args) -> if i=j then diff --git a/bytecomp/simplif.ml b/bytecomp/simplif.ml index 04176603..f07fbc04 100644 --- a/bytecomp/simplif.ml +++ b/bytecomp/simplif.ml @@ -494,7 +494,7 @@ let simplify_lets lam = | Llet(StrictOpt, kind, v, l1, l2) -> begin match count_var v with 0 -> simplif l2 - | _ -> mklet Alias kind v (simplif l1) (simplif l2) + | _ -> mklet StrictOpt kind v (simplif l1) (simplif l2) end | Llet(str, kind, v, l1, l2) -> mklet str kind v (simplif l1) (simplif l2) | Lletrec(bindings, body) -> diff --git a/otherlibs/bigarray/bigarray_stubs.c b/otherlibs/bigarray/bigarray_stubs.c index aa510268..9f89184c 100644 --- a/otherlibs/bigarray/bigarray_stubs.c +++ b/otherlibs/bigarray/bigarray_stubs.c @@ -471,7 +471,7 @@ CAMLprim value caml_ba_dim(value vb, value vn) { struct caml_ba_array * b = Caml_ba_array_val(vb); intnat n = Long_val(vn); - if (n >= b->num_dims) caml_invalid_argument("Bigarray.dim"); + if (n < 0 || n >= b->num_dims) caml_invalid_argument("Bigarray.dim"); return Val_long(b->dim[n]); } diff --git a/testsuite/tests/basic-float/float_compare.ml b/testsuite/tests/basic-float/float_compare.ml new file mode 100644 index 00000000..d5b7a9a1 --- /dev/null +++ b/testsuite/tests/basic-float/float_compare.ml @@ -0,0 +1,6 @@ + +let compare_nan () = + not (nan < 0.0) +[@@inline never] + +let x = print_endline (string_of_bool (compare_nan ())) diff --git a/testsuite/tests/basic-float/float_compare.reference b/testsuite/tests/basic-float/float_compare.reference new file mode 100644 index 00000000..27ba77dd --- /dev/null +++ b/testsuite/tests/basic-float/float_compare.reference @@ -0,0 +1 @@ +true diff --git a/testsuite/tests/basic-more/robustmatch.compilers.reference b/testsuite/tests/basic-more/robustmatch.compilers.reference new file mode 100644 index 00000000..2ccfe59b --- /dev/null +++ b/testsuite/tests/basic-more/robustmatch.compilers.reference @@ -0,0 +1,107 @@ +File "robustmatch.ml", line 33, characters 6-122: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(AB, MAB, A) +File "robustmatch.ml", line 54, characters 4-73: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, 1) +File "robustmatch.ml", line 64, characters 4-73: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, (B|C)) +File "robustmatch.ml", line 69, characters 4-73: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, (B|C)) +File "robustmatch.ml", line 74, characters 4-73: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, "") +File "robustmatch.ml", line 85, characters 4-66: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, (B|C)) +File "robustmatch.ml", line 90, characters 4-87: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, (Y|Z)) +File "robustmatch.ml", line 96, characters 4-66: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, (Y|Z)) +File "robustmatch.ml", line 107, characters 4-66: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, (B|C)) +File "robustmatch.ml", line 129, characters 4-66: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, B) +File "robustmatch.ml", line 151, characters 4-66: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, B) +File "robustmatch.ml", line 156, characters 4-87: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, Y) +File "robustmatch.ml", line 162, characters 4-66: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, Y) +File "robustmatch.ml", line 167, characters 4-66: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, A) +File "robustmatch.ml", line 176, characters 4-90: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, [| _ |]) +File "robustmatch.ml", line 182, characters 4-69: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, [| _ |]) +File "robustmatch.ml", line 187, characters 4-90: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, [| _ |]) +File "robustmatch.ml", line 200, characters 4-89: +Warning 4: this pattern-matching is fragile. +It will remain exhaustive when constructors are added to type repr. +File "robustmatch.ml", line 210, characters 4-75: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, 'a') +File "robustmatch.ml", line 219, characters 4-74: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, `B) +File "robustmatch.ml", line 228, characters 4-89: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, (3, "*")) +File "robustmatch.ml", line 239, characters 4-113: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, {x=3; y="*"}) +File "robustmatch.ml", line 244, characters 4-113: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, {a=1; b="coucou"; c='b'}) +File "robustmatch.ml", line 253, characters 4-72: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, (3, "*")) +File "robustmatch.ml", line 263, characters 4-82: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, {x=3; y="*"}) +File "robustmatch.ml", line 272, characters 4-71: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R1, R1, lazy 0) +File "robustmatch.ml", line 281, characters 4-99: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +(R2, R2, "") diff --git a/testsuite/tests/basic-more/robustmatch.ml b/testsuite/tests/basic-more/robustmatch.ml new file mode 100644 index 00000000..e4768d0a --- /dev/null +++ b/testsuite/tests/basic-more/robustmatch.ml @@ -0,0 +1,285 @@ +(* TEST + flags += "-w +4+8+9+11+12+52+56+57" + include testing +*) + +module GPR1493 = struct + type t1 = { x : int; y : string; } + type t2 = { a : int; b : string; c : string list; } + + type t = .. + type t += C1 of t1 | C2 of t2 + + let f (x : t) = + match x with + | C1 { x; y } -> () + | C2 { a;b;c } -> () + | _ -> () +end + +module Coherence_illustration = struct + type ab = A | B + + module M : sig + type mab = A | B + + type _ t = AB : ab t | MAB : mab t + end = struct + type mab = ab = A | B + + type _ t = AB : ab t | MAB : mab t + + let f (type x) (t1 : x t) (t2 : x t) (x : x) = + match t1, t2, x with + | AB, AB, A -> () + | MAB, _, A -> () + | _, AB, B -> () + | _, MAB, B -> () + end + + open M + + let f (type x) (t1 : x t) (t2 : x t) (x : x) = + match t1, t2, x with + | AB, AB, A -> () + | MAB, _, A -> () + | _, AB, B -> () + | _, MAB, B -> () +end + +module M1 = struct + type _ repr = R1 : int repr | R2 : string repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, 0 -> () + | _, R2, "coucou" -> () +end + +module M2 = struct + type c = A | B | C + type _ repr = R1 : c repr | R2 : string repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, "coucou" -> () + + let g (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | _, R2, "coucou" -> () + | R1, _, A -> () + + let h (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | _, R2, "coucou" -> () + | R1, _, _ -> () +end + +module M3 = struct + type c1 = A | B | C + type c2 = X | Y | Z + type _ repr = R1 : c1 repr | R2 : c2 repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, X -> () + + let g (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, X -> () + | R1, _, _ -> () + + let h (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, _ -> () + | _, R2, X -> () +end + +module M3_gadt = struct + type c1 = A | B | C + type _ c2 = X : int c2 | Y : char c2 | Z : char c2 + type _ repr = R1 : c1 repr | R2 : int c2 repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, X -> () + + let g (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, X -> () + | R1, _, _ -> () + + let h (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, _ -> () + | _, R2, X -> () +end + +module M3_gadt_bis = struct + type _ c1 = A : int c1 | B : int c1 | C : char c1 + type _ c2 = X : int c2 | Y : char c2 | Z : char c2 + type _ repr = R1 : int c1 repr | R2 : int c2 repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, X -> () + + let g (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, X -> () + | R1, _, B -> () + + let h (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, _ -> () + | _, R2, X -> () +end + +module M3_gadt_bis_harder = struct + type _ c1 = A : int c1 | B : int c1 | C : char c1 + type _ c2 = X : int c2 | Y : char c2 | Z : char c2 + type _ repr = R1 : 'a c1 repr | R2 : 'a c2 repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, X -> () + + let g (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, A -> () + | _, R2, X -> () + | R1, _, _ -> () + + let h (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, _ -> () + | _, R2, X -> () + + let h (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, C -> () + | _, R2, Y -> () +end + +module M4 = struct + type _ repr = R1 : int repr | R2 : int array repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | _, R1, 0 -> () + | R2, _, [||] -> () + | _, R1, 1 -> () + + let g (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, _ -> () + | _, R2, [||] -> () + + let h (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | _, R2, [||] -> () + | R1, _, 0 -> () + | R1, _, _ -> () + + let i (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | _, R2, [||] -> () + | R1, _, 0 -> () + | R1, _, _ -> () + | _, R2, _ -> () + + let j (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | _, R2, [||] -> () + | R1, _, 0 -> () + | _, _, _ -> () +end + +module M5 = struct + type _ repr = R1 : char repr | R2 : string repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, 'c' -> () + | _, R2, "coucou" -> () +end + +module M6 = struct + type _ repr = R1 : [ `A | `B ] repr | R2 : string repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, `A -> () + | _, R2, "coucou" -> () +end + +module M7 = struct + type _ repr = R1 : (int * string) repr | R2 : (int * string * char) repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, (3, "") -> () + | _, R2, (1, "coucou", 'a') -> () +end + +module M8 = struct + type r1 = { x : int; y : string } + type r2 = { a : int; b : string; c : char } + type _ repr = R1 : r1 repr | R2 : r2 repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, { x = 3; y = "" } -> () + | _, R2, { a = 1; b = "coucou"; c = 'a' } -> () + + let g (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R2, _, { a = 1; b = "coucou"; c = 'a' } -> () + | _, R1, { x = 3; y = "" } -> () +end + +module M9 = struct + type _ repr = R1 : (int * string) repr | R2 : int repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, (3, "") -> () + | _, R2, 1 -> () +end + +module M10 = struct + type r = { x : int; y : string } + type _ repr = R1 : r repr | R2 : int repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, { x = 3; y = "" } -> () + | _, R2, 1 -> () +end + +module M11 = struct + type _ repr = R1 : int lazy_t repr | R2 : int repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, lazy 1 -> () + | _, R2, 1 -> () +end + +module M12 = struct + type _ repr = R1 : unit repr | R2 : string repr + + let f (type a) (r1 : a repr) (r2 : a repr) (a : a) = + match r1, r2, a with + | R1, _, () -> () + | _, R2, "coucou" -> () + | _, R2, "foo" -> () +end diff --git a/testsuite/tests/basic-more/robustmatch.reference b/testsuite/tests/basic-more/robustmatch.reference new file mode 100644 index 00000000..197c9280 --- /dev/null +++ b/testsuite/tests/basic-more/robustmatch.reference @@ -0,0 +1,2 @@ + +All tests succeeded. diff --git a/testsuite/tests/basic/patmatch.ml b/testsuite/tests/basic/patmatch.ml index 43026be2..c1c00239 100644 --- a/testsuite/tests/basic/patmatch.ml +++ b/testsuite/tests/basic/patmatch.ml @@ -1633,3 +1633,242 @@ end let () = GPR234HList.test () let () = printf "GPR#234=Ok\n%!" + +module MPR7761 = struct + + let zyva msg c r = + if r <> c then begin + Printf.printf "'%c' pas bon pour %s (should be '%c')\n%!"r msg c + end else + Printf.printf "%s -> '%c'\n%!" msg r + + module A = struct + type t = .. + type t += + | A + | B + + let f x y = match x, y with + | (A | B), A -> 'a' + | (A | B), B -> 'b' + | _, _ -> '_' + + let () = + zyva "f A A" 'a' (f A A) ; + zyva "f A B" 'b' (f A B) ; + printf "PR#7661-A=Ok\n%!" + end + + module B = struct + type t = .. + type t += + | A + | B + + type t += C + type t += D + + let f x y = match x, y with + | B, C -> 'x' + | (A | B), A -> 'a' + | (A | B), B -> 'b' + | (C | D), (A|B|C) -> 'c' + | _, _ -> '_' + + let g x y = match x, y with + | Some B, C -> 'x' + | (Some A | Some B), A -> 'a' + | (Some A | Some B), B -> 'b' + | (Some C | Some D), (A|B|C) -> 'c' + | _, _ -> '_' + + let () = + zyva "f B C" 'x' (f B C) ; + zyva "f A A" 'a' (f A A) ; + zyva "f B A" 'a' (f B A) ; + zyva "f A B" 'b' (f A B) ; + zyva "f B B" 'b' (f B B) ; + zyva "f C B" 'c' (f C B) ; + zyva "f D B" 'c' (f D B) ; + zyva "f C A" 'c' (f C A) ; + zyva "f D A" 'c' (f D A) ; + zyva "f C C" 'c' (f C C) ; + zyva "f D C" 'c' (f D C) ; + zyva "f A D" '_' (f A D) ; + zyva "f C D" '_' (f C D) ; +(***************) + zyva "g (Some B) C" 'x' (g (Some B) C) ; + zyva "g (Some A) A" 'a' (g (Some A) A) ; + zyva "g (Some B) A" 'a' (g (Some B) A) ; + zyva "g (Some A) B" 'b' (g (Some A) B) ; + zyva "g (Some B) B" 'b' (g (Some B) B) ; + zyva "g (Some C) B" 'c' (g (Some C) B) ; + zyva "g (Some D) B" 'c' (g (Some D) B) ; + zyva "g (Some C) A" 'c' (g (Some C) A) ; + zyva "g (Some D) A" 'c' (g (Some D) A) ; + zyva "g (Some C) C" 'c' (g (Some C) C) ; + zyva "g (Some D) C" 'c' (g (Some D) C) ; + zyva "g (Some A) D" '_' (g (Some A) D) ; + zyva "g (Some C) D" '_' (g (Some C) D) ; +(***************) + printf "PR#7661-B=Ok\n%!" + end + + module C = struct + type t = .. + type t += + | A + | B + + type t += C + type t += D=A + + let f x y = match x, y with + | B, C -> 'x' + | (A | B), A -> 'a' + | (A | B), B -> 'b' + | (C | D), (A|B|C) -> 'c' + | _, _ -> '_' + + let g x y = match x, y with + | Some B, C -> 'x' + | (Some A | Some B), A -> 'a' + | (Some A | Some B), B -> 'b' + | (Some C | Some D), (A|B|C) -> 'c' + | _, _ -> '_' + + let () = + zyva "f B C" 'x' (f B C) ; + zyva "f A A" 'a' (f A A) ; + zyva "f B A" 'a' (f B A) ; + zyva "f A B" 'b' (f A B) ; + zyva "f B B" 'b' (f B B) ; + zyva "f C B" 'c' (f C B) ; + zyva "f D B" 'b' (f D B) ; + zyva "f C A" 'c' (f C A) ; + zyva "f D A" 'a' (f D A) ; + zyva "f C C" 'c' (f C C) ; + zyva "f D C" 'c' (f D C) ; + zyva "f A D" 'a' (f A D) ; + zyva "f B D" 'a' (f B D) ; + zyva "f C D" 'c' (f C D) ; + zyva "f D D" 'a' (f D D) ; +(***************) + zyva "g (Some B) C" 'x' (g (Some B) C) ; + zyva "g (Some A) A" 'a' (g (Some A) A) ; + zyva "g (Some B) A" 'a' (g (Some B) A) ; + zyva "g (Some A) B" 'b' (g (Some A) B) ; + zyva "g (Some B) B" 'b' (g (Some B) B) ; + zyva "g (Some C) B" 'c' (g (Some C) B) ; + zyva "g (Some D) B" 'b' (g (Some D) B) ; + zyva "g (Some C) A" 'c' (g (Some C) A) ; + zyva "g (Some D) A" 'a' (g (Some D) A) ; + zyva "g (Some C) C" 'c' (g (Some C) C) ; + zyva "g (Some D) C" 'c' (g (Some D) C) ; + zyva "g (Some A) D" 'a' (g (Some A) D) ; + zyva "g (Some B) D" 'a' (g (Some B) D) ; + zyva "g (Some C) D" 'c' (g (Some C) D) ; + zyva "g (Some D) D" 'a' (g (Some D) D) ; +(***************) + printf "PR#7661-C=Ok\n%!" + end + + module D = struct + type t = .. + type t += A | B of int + type t += C=A + + let f x y = match x,y with + | true,A -> 'a' + | _,B _ -> 'b' + | false,A -> 'c' + | _,_ -> '_' + + let g x y = match x,y with + | true,A -> 'a' + | _,C -> 'b' + | false,A -> 'c' + | _,_ -> '_' + + let () = + zyva "f true A" 'a' (f true A) ; + zyva "f true (B 0)" 'b' (f true (B 0)) ; + zyva "f false A" 'c' (f false A) ; + zyva "g true A" 'a' (g true A) ; + zyva "g false A" 'b' (g false A) ; + zyva "g true (B 0)" '_' (g true (B 0)) ; +(***************) + printf "PR#7661-D=Ok\n%!" + end + + module E = struct + + module type S = sig + type t = .. + type t += A|B|C + type u = X|Y|Z + + val fAYX : char + val gAYX : char + val fAZY : char + val gAZY : char + end + + module Z(T:S) : sig end = struct + + open T + + let f x y z = match x,y,z with + | A,X,_ -> '1' + | _,X,X -> '2' + | B,_,X -> '3' + | C,_,X -> '4' + | C,_,Y -> '5' + | _,_,_ -> '_' + + let g x y z = match x,y,z with + | A,X,_ -> '1' + | _,X,X -> '2' + | (B|C),_,X -> '3' + | C,_,Y -> '5' + | _,_,_ -> '_' + + let () = + zyva "f A Y X" fAYX (f A Y X) ; + zyva "g A Y X" gAYX (g A Y X) ; + zyva "f A Z Y" fAZY (f A Z Y) ; + zyva "g A Z Y" gAZY (g A Z Y) ; + () + end + + module A = + Z + (struct + type t = .. + type t += A|B + type t += C=A + type u = X|Y|Z + + let fAYX = '4' + and gAYX = '3' + and fAZY = '5' + and gAZY = '5' + end) + + module B = + Z + (struct + type t = .. + type t += A|B + type t += C + type u = X|Y|Z + + let fAYX = '_' + and gAYX = '_' + and fAZY = '_' + and gAZY = '_' + end) + + let () = printf "PR#7661-E=Ok\n%!" + end +end diff --git a/testsuite/tests/basic/patmatch.reference b/testsuite/tests/basic/patmatch.reference index 11cd189a..79f68157 100644 --- a/testsuite/tests/basic/patmatch.reference +++ b/testsuite/tests/basic/patmatch.reference @@ -74,3 +74,80 @@ PR#6646=Ok PR#6676=Ok 48 GPR#234=Ok +f A A -> 'a' +f A B -> 'b' +PR#7661-A=Ok +f B C -> 'x' +f A A -> 'a' +f B A -> 'a' +f A B -> 'b' +f B B -> 'b' +f C B -> 'c' +f D B -> 'c' +f C A -> 'c' +f D A -> 'c' +f C C -> 'c' +f D C -> 'c' +f A D -> '_' +f C D -> '_' +g (Some B) C -> 'x' +g (Some A) A -> 'a' +g (Some B) A -> 'a' +g (Some A) B -> 'b' +g (Some B) B -> 'b' +g (Some C) B -> 'c' +g (Some D) B -> 'c' +g (Some C) A -> 'c' +g (Some D) A -> 'c' +g (Some C) C -> 'c' +g (Some D) C -> 'c' +g (Some A) D -> '_' +g (Some C) D -> '_' +PR#7661-B=Ok +f B C -> 'x' +f A A -> 'a' +f B A -> 'a' +f A B -> 'b' +f B B -> 'b' +f C B -> 'c' +f D B -> 'b' +f C A -> 'c' +f D A -> 'a' +f C C -> 'c' +f D C -> 'c' +f A D -> 'a' +f B D -> 'a' +f C D -> 'c' +f D D -> 'a' +g (Some B) C -> 'x' +g (Some A) A -> 'a' +g (Some B) A -> 'a' +g (Some A) B -> 'b' +g (Some B) B -> 'b' +g (Some C) B -> 'c' +g (Some D) B -> 'b' +g (Some C) A -> 'c' +g (Some D) A -> 'a' +g (Some C) C -> 'c' +g (Some D) C -> 'c' +g (Some A) D -> 'a' +g (Some B) D -> 'a' +g (Some C) D -> 'c' +g (Some D) D -> 'a' +PR#7661-C=Ok +f true A -> 'a' +f true (B 0) -> 'b' +f false A -> 'c' +g true A -> 'a' +g false A -> 'b' +g true (B 0) -> '_' +PR#7661-D=Ok +f A Y X -> '4' +g A Y X -> '3' +f A Z Y -> '5' +g A Z Y -> '5' +f A Y X -> '_' +g A Y X -> '_' +f A Z Y -> '_' +g A Z Y -> '_' +PR#7661-E=Ok diff --git a/testsuite/tests/raise-counts/a.ml b/testsuite/tests/raise-counts/a.ml new file mode 100644 index 00000000..323fe2af --- /dev/null +++ b/testsuite/tests/raise-counts/a.ml @@ -0,0 +1,12 @@ +let _unused _ = try () with _ -> () + +let trigger_bug x = + let ok = + match x with + | None + | Some "" -> true + | Some _ -> false + in + if x = Some "" && not ok then + failwith "impossible" +[@@inline always] diff --git a/testsuite/tests/raise-counts/b.ml b/testsuite/tests/raise-counts/b.ml new file mode 100644 index 00000000..e346c8b2 --- /dev/null +++ b/testsuite/tests/raise-counts/b.ml @@ -0,0 +1 @@ +let bug x = A.trigger_bug x diff --git a/testsuite/tests/raise-counts/main.ml b/testsuite/tests/raise-counts/main.ml new file mode 100644 index 00000000..b881b832 --- /dev/null +++ b/testsuite/tests/raise-counts/main.ml @@ -0,0 +1,9 @@ +(* TEST + modules = "a.ml b.ml" +*) + +(* PR#7702 *) + +let () = + B.bug (Some ""); + print_endline "OK." diff --git a/testsuite/tests/raise-counts/main.reference b/testsuite/tests/raise-counts/main.reference new file mode 100644 index 00000000..d5c32f4a --- /dev/null +++ b/testsuite/tests/raise-counts/main.reference @@ -0,0 +1 @@ +OK. diff --git a/testsuite/tests/raise-counts/ocamltests b/testsuite/tests/raise-counts/ocamltests new file mode 100644 index 00000000..d389d156 --- /dev/null +++ b/testsuite/tests/raise-counts/ocamltests @@ -0,0 +1 @@ +main.ml diff --git a/testsuite/tests/typing-misc/polyvars.ml b/testsuite/tests/typing-misc/polyvars.ml index 4cdbd804..cb99f4e7 100644 --- a/testsuite/tests/typing-misc/polyvars.ml +++ b/testsuite/tests/typing-misc/polyvars.ml @@ -72,3 +72,15 @@ type 'a foo = 'a constraint 'a = [< `Tag of & int];; [%%expect{| type 'a foo = 'a constraint 'a = [< `Tag of & int ] |}] + +(* PR#7704 *) +type t = private [> `A of string ];; +function (`A x : t) -> x;; +[%%expect{| +type t = private [> `A of string ] +Line _, characters 0-24: +Warning 8: this pattern-matching is not exhaustive. +Here is an example of a case that is not matched: +` +- : t -> string = +|}] diff --git a/testsuite/tests/typing-poly/poly.ml b/testsuite/tests/typing-poly/poly.ml index 6e21e0f4..bc1990c7 100644 --- a/testsuite/tests/typing-poly/poly.ml +++ b/testsuite/tests/typing-poly/poly.ml @@ -914,7 +914,7 @@ type t = A | B Line _, characters 0-41: Warning 8: this pattern-matching is not exhaustive. Here is an example of a case that is not matched: -(`AnyExtraTag, `AnyExtraTag) +(`, `) - : [> `A | `B ] * [> `A | `B ] -> int = Line _, characters 0-29: Warning 8: this pattern-matching is not exhaustive. diff --git a/testsuite/tests/warnings/w04_failure.ml b/testsuite/tests/warnings/w04_failure.ml new file mode 100644 index 00000000..929226cd --- /dev/null +++ b/testsuite/tests/warnings/w04_failure.ml @@ -0,0 +1,28 @@ +type ab = A | B +type xy = X | Y + +type _ repr = AB : ab repr | XY : xy repr + +(* Correctly reports fragility w.r.t. [repr], [ab] and [xy]. *) + +let vocal_fragile (type t) (r1 : t repr) (r2 : t repr) (t : t) = + match r1, r2, t with + | AB, _, A -> () + | _, XY, X -> () + | _, _, _ -> () + +(* Fails to report fragility on [ab] and [xy]. *) + +let silent_fragile1 (type t) (r1 : t repr) (r2 : t repr) (t : t) = + match r1, r2, t with + | AB, _, A -> () + | _, XY, X -> () + | _, AB, _ -> () + | XY, _, _ -> () + +let silent_fragile2 (type t) (r1 : t repr) (r2 : t repr) (t : t) = + match r1, r2, t with + | AB, _, A -> () + | _, XY, X -> () + | AB, _, _ -> () + | _, XY, _ -> () diff --git a/testsuite/tests/warnings/w04_failure.reference b/testsuite/tests/warnings/w04_failure.reference new file mode 100644 index 00000000..8af70f40 --- /dev/null +++ b/testsuite/tests/warnings/w04_failure.reference @@ -0,0 +1,9 @@ +File "w04_failure.ml", line 9, characters 2-78: +Warning 4: this pattern-matching is fragile. +It will remain exhaustive when constructors are added to type repr. +File "w04_failure.ml", line 9, characters 2-78: +Warning 4: this pattern-matching is fragile. +It will remain exhaustive when constructors are added to type ab. +File "w04_failure.ml", line 9, characters 2-78: +Warning 4: this pattern-matching is fragile. +It will remain exhaustive when constructors are added to type xy. diff --git a/typing/parmatch.ml b/typing/parmatch.ml index a2e64f65..cb5e07b0 100644 --- a/typing/parmatch.ml +++ b/typing/parmatch.ml @@ -44,11 +44,215 @@ let omega_list l = List.map (fun _ -> omega) l let zero = make_pat (Tpat_constant (Const_int 0)) Ctype.none Env.empty +(*******************) +(* Coherence check *) +(*******************) + +(* For some of the operations we do in this module, we would like (because it + simplifies matters) to assume that patterns appearing on a given column in a + pattern matrix are /coherent/ (think "of the same type"). + Unfortunately that is not always true. + + Consider the following (well-typed) example: + {[ + type _ t = S : string t | U : unit t + + let f (type a) (t1 : a t) (t2 : a t) (a : a) = + match t1, t2, a with + | U, _, () -> () + | _, S, "" -> () + ]} + + Clearly the 3rd column contains incoherent patterns. + + On the example above, most of the algorithms will explore the pattern matrix + as illustrated by the following tree: + + {v + S + -------> | "" | + U | S, "" | __/ | () | + --------> | _, () | \ ¬ S + | U, _, () | __/ -------> | () | + | _, S, "" | \ + ---------> | S, "" | ----------> | "" | + ¬ U S + v} + + where following an edge labelled by a pattern P means "assuming the value I + am matching on is filtered by [P] on the column I am currently looking at, + then the following submatrix is still reachable". + + Notice that at any point of that tree, if the first column of a matrix is + incoherent, then the branch leading to it can only be taken if the scrutinee + is ill-typed. + In the example above the only case where we have a matrix with an incoherent + first column is when we consider [t1, t2, a] to be [U, S, ...]. However such + a value would be ill-typed, so we can never actually get there. + + Checking the first column at each step of the recursion and making the + concious decision of "aborting" the algorithm whenever the first column + becomes incoherent, allows us to retain the initial assumption in later + stages of the algorithms. + + --- + + N.B. two patterns can be considered coherent even though they might not be of + the same type. + + That's in part because we only care about the "head" of patterns and leave + checking coherence of subpatterns for the next steps of the algorithm: + ('a', 'b') and (1, ()) will be deemed coherent because they are both a tuples + of arity 2 (we'll notice at a later stage the incoherence of 'a' and 1). + + But also because it can be hard/costly to determine exactly whether two + patterns are of the same type or not (eg. in the example above with _ and S, + but see also the module [Coherence_illustration] in + testsuite/tests/basic-more/robustmatch.ml). + + For the moment our weak, loosely-syntactic, coherence check seems to be + enough and we leave it to each user to consider (and document!) what happens + when an "incoherence" is not detected by this check. +*) + + +let simplify_head_pat p k = + let rec simplify_head_pat p k = + match p.pat_desc with + | Tpat_alias (p,_,_) -> simplify_head_pat p k + | Tpat_var (_,_) -> omega :: k + | Tpat_or (p1,p2,_) -> simplify_head_pat p1 (simplify_head_pat p2 k) + | _ -> p :: k + in simplify_head_pat p k + +let rec simplified_first_col = function + | [] -> [] + | [] :: _ -> assert false (* the rows are non-empty! *) + | (p::_) :: rows -> + simplify_head_pat p (simplified_first_col rows) + +(* Given the simplified first column of a matrix, this function first looks for + a "discriminating" pattern on that column (i.e. a non-omega one) and then + check that every other head pattern in the column is coherent with that one. +*) +let all_coherent column = + let coherent_heads hp1 hp2 = + match hp1.pat_desc, hp2.pat_desc with + | (Tpat_var _ | Tpat_alias _ | Tpat_or _), _ + | _, (Tpat_var _ | Tpat_alias _ | Tpat_or _) -> + assert false + | Tpat_construct (_, c, _), Tpat_construct (_, c', _) -> + c.cstr_consts = c'.cstr_consts + && c.cstr_nonconsts = c'.cstr_nonconsts + | Tpat_constant c1, Tpat_constant c2 -> begin + match c1, c2 with + | Const_char _, Const_char _ + | Const_int _, Const_int _ + | Const_int32 _, Const_int32 _ + | Const_int64 _, Const_int64 _ + | Const_nativeint _, Const_nativeint _ + | Const_float _, Const_float _ + | Const_string _, Const_string _ -> true + | ( Const_char _ + | Const_int _ + | Const_int32 _ + | Const_int64 _ + | Const_nativeint _ + | Const_float _ + | Const_string _), _ -> false + end + | Tpat_tuple l1, Tpat_tuple l2 -> List.length l1 = List.length l2 + | Tpat_record ((_, lbl1, _) :: _, _), Tpat_record ((_, lbl2, _) :: _, _) -> + Array.length lbl1.lbl_all = Array.length lbl2.lbl_all + | Tpat_any, _ + | _, Tpat_any + | Tpat_record ([], _), Tpat_record (_, _) + | Tpat_record (_, _), Tpat_record ([], _) + | Tpat_variant _, Tpat_variant _ + | Tpat_array _, Tpat_array _ + | Tpat_lazy _, Tpat_lazy _ -> true + | _, _ -> false + in + match + List.find (fun head_pat -> + match head_pat.pat_desc with + | Tpat_var _ | Tpat_alias _ | Tpat_or _ -> assert false + | Tpat_any -> false + | _ -> true + ) column + with + | exception Not_found -> + (* only omegas on the column: the column is coherent. *) + true + | discr_pat -> + List.for_all (coherent_heads discr_pat) column + +let first_column simplified_matrix = + List.map fst simplified_matrix + (***********************) (* Compatibility check *) (***********************) -(* p and q compatible means, there exists V that matches both *) +(* Patterns p and q compatible means: + there exists value V that matches both, However.... + + The case of extension types is dubious, as constructor rebind permits + that different constructors are the same (and are thus compatible). + + Compilation must take this into account, consider: + + type t = .. + type t += A|B + type t += C=A + + let f x y = match x,y with + | true,A -> '1' + | _,C -> '2' + | false,A -> '3' + | _,_ -> '_' + + As C is bound to A the value of f false A is '2' (and not '3' as it would + be in the absence of rebinding). + + Not considering rebinding, patterns "false,A" and "_,C" are incompatible + and the compiler can swap the second and third clause, resulting in the + (more efficiently compiled) matching + + match x,y with + | true,A -> '1' + | false,A -> '3' + | _,C -> '2' + | _,_ -> '_' + + This is not correct: when C is bound to A, "f false A" returns '2' (not '3') + + + However, diagnostics do not take constructor rebinding into account. + Notice, that due to module abstraction constructor rebinding is hidden. + + module X : sig type t = .. type t += A|B end = struct + type t = .. + type t += A + type t += B=A + end + + open X + + let f x = match x with + | A -> '1' + | B -> '2' + | _ -> '_' + + The second clause above will NOT (and cannot) be flagged as useless. + + Finally, there are two compatibility fonction + compat p q ---> 'syntactic compatibility, used for diagnostics. + may_compat p q ---> a safe approximation of possible compat, + for compilation + +*) + let is_absent tag row = Btype.row_field tag !row = Rabsent @@ -80,38 +284,67 @@ let records_args l1 l2 = combine [] [] l1 l2 -let rec compat p q = - match p.pat_desc,q.pat_desc with + +module Compat + (Constr:sig + val equal : + Types.constructor_description -> + Types.constructor_description -> + bool + end) = struct + + let rec compat p q = match p.pat_desc,q.pat_desc with +(* Variables match any value *) + | ((Tpat_any|Tpat_var _),_) + | (_,(Tpat_any|Tpat_var _)) -> true +(* Structural induction *) | Tpat_alias (p,_,_),_ -> compat p q | _,Tpat_alias (q,_,_) -> compat p q - | (Tpat_any|Tpat_var _),_ -> true - | _,(Tpat_any|Tpat_var _) -> true - | Tpat_or (p1,p2,_),_ -> compat p1 q || compat p2 q - | _,Tpat_or (q1,q2,_) -> compat p q1 || compat p q2 - | Tpat_constant c1, Tpat_constant c2 -> const_compare c1 c2 = 0 + | Tpat_or (p1,p2,_),_ -> + (compat p1 q || compat p2 q) + | _,Tpat_or (q1,q2,_) -> + (compat p q1 || compat p q2) +(* Constructors, with special case for extension *) + | Tpat_construct (_, c1,ps1), Tpat_construct (_, c2,ps2) -> + Constr.equal c1 c2 && compats ps1 ps2 +(* More standard stuff *) + | Tpat_variant(l1,op1, _), Tpat_variant(l2,op2,_) -> + l1=l2 && ocompat op1 op2 + | Tpat_constant c1, Tpat_constant c2 -> + const_compare c1 c2 = 0 | Tpat_tuple ps, Tpat_tuple qs -> compats ps qs | Tpat_lazy p, Tpat_lazy q -> compat p q - | Tpat_construct (_, c1,ps1), Tpat_construct (_, c2,ps2) -> - Types.equal_tag c1.cstr_tag c2.cstr_tag && compats ps1 ps2 - | Tpat_variant(l1,Some p1, _r1), Tpat_variant(l2,Some p2,_) -> - l1=l2 && compat p1 p2 - | Tpat_variant (l1,None, _r1), Tpat_variant(l2,None,_) -> - l1 = l2 - | Tpat_variant (_, None, _), Tpat_variant (_,Some _, _) -> false - | Tpat_variant (_, Some _, _), Tpat_variant (_, None, _) -> false | Tpat_record (l1,_),Tpat_record (l2,_) -> let ps,qs = records_args l1 l2 in compats ps qs | Tpat_array ps, Tpat_array qs -> List.length ps = List.length qs && compats ps qs - | _,_ -> - assert false + | _,_ -> false -and compats ps qs = match ps,qs with -| [], [] -> true -| p::ps, q::qs -> compat p q && compats ps qs -| _,_ -> assert false + and ocompat op oq = match op,oq with + | None,None -> true + | Some p,Some q -> compat p q + | (None,Some _)|(Some _,None) -> false + + and compats ps qs = match ps,qs with + | [], [] -> true + | p::ps, q::qs -> compat p q && compats ps qs + | _,_ -> false + +end + +module SyntacticCompat = + Compat + (struct + let equal c1 c2 = Types.equal_tag c1.cstr_tag c2.cstr_tag + end) + +let compat = SyntacticCompat.compat +and compats = SyntacticCompat.compats + +(* Due to (potential) rebinding, two extension constructors + of the same arity type may equal *) exception Empty (* Empty pattern *) @@ -288,9 +521,9 @@ let simple_match p1 p2 = | Tpat_variant(l1, _, _), Tpat_variant(l2, _, _) -> l1 = l2 | Tpat_constant(c1), Tpat_constant(c2) -> const_compare c1 c2 = 0 - | Tpat_tuple _, Tpat_tuple _ -> true | Tpat_lazy _, Tpat_lazy _ -> true | Tpat_record _ , Tpat_record _ -> true + | Tpat_tuple p1s, Tpat_tuple p2s | Tpat_array p1s, Tpat_array p2s -> List.length p1s = List.length p2s | _, (Tpat_any | Tpat_var(_)) -> true | _, _ -> false @@ -774,7 +1007,7 @@ let complete_constrs p all_tags = let constrs = get_variant_constructors p.pat_env c.cstr_res in let others = List.filter - (fun cnstr -> ConstructorTagHashtbl.mem not_tags cnstr.cstr_tag) + (fun cnstr -> ConstructorTagHashtbl.mem not_tags cnstr.cstr_tag) constrs in let const, nonconst = List.partition (fun cnstr -> cnstr.cstr_arity = 0) others in @@ -805,6 +1038,8 @@ let build_other_constant proj make first next p env = in the first column of env *) +let some_other_tag = "" + let build_other ext env = match env with | ({pat_desc = Tpat_construct (lid, {cstr_tag=Cstr_extension _},_)},_) :: _ -> (* let c = {c with cstr_name = "*extension*"} in *) (* PR#7330 *) @@ -840,7 +1075,7 @@ let build_other ext env = match env with [] row.row_fields with [] -> - make_other_pat "AnyExtraTag" true + make_other_pat some_other_tag true | pat::other_pats -> List.fold_left (fun p_res pat -> @@ -950,6 +1185,20 @@ and has_instances = function | [] -> true | q::rem -> has_instance q && has_instances rem +(* + In two places in the following function, we check the coherence of the first + column of (pss + qs). + If it is incoherent, then we exit early saying that (pss + qs) is not + satisfiable (which is equivalent to saying "oh, we shouldn't have considered + that branch, no good result came come from here"). + + But what happens if we have a coherent but ill-typed column? + - we might end up returning [false], which is equivalent to noticing the + incompatibility: clearly this is fine. + - if we end up returning [true] then we're saying that [qs] is useful while + it is not. This is sad but not the end of the world, we're just allowing dead + code to survive. +*) let rec satisfiable pss qs = match pss with | [] -> has_instances qs | _ -> @@ -960,26 +1209,36 @@ let rec satisfiable pss qs = match pss with | {pat_desc = Tpat_alias(q,_,_)}::qs -> satisfiable pss (q::qs) | {pat_desc = (Tpat_any | Tpat_var(_))}::qs -> - let q0 = discr_pat omega pss in - begin match filter_all q0 pss with - (* first column of pss is made of variables only *) - | [] -> satisfiable (filter_extra pss) qs - | constrs -> - if full_match false constrs then - List.exists - (fun (p,pss) -> - not (is_absent_pat p) && - satisfiable pss (simple_match_args p omega @ qs)) - constrs - else - satisfiable (filter_extra pss) qs + if not (all_coherent (simplified_first_col pss)) then + false + else begin + let q0 = discr_pat omega pss in + match filter_all q0 pss with + (* first column of pss is made of variables only *) + | [] -> satisfiable (filter_extra pss) qs + | constrs -> + if full_match false constrs then + List.exists + (fun (p,pss) -> + not (is_absent_pat p) && + satisfiable pss (simple_match_args p omega @ qs)) + constrs + else + satisfiable (filter_extra pss) qs end | {pat_desc=Tpat_variant (l,_,r)}::_ when is_absent l r -> false | q::qs -> - let q0 = discr_pat q pss in - satisfiable (filter_one q0 pss) (simple_match_args q0 q @ qs) + if not (all_coherent (q :: simplified_first_col pss)) then + false + else begin + let q0 = discr_pat q pss in + satisfiable (filter_one q0 pss) (simple_match_args q0 q @ qs) + end -(* Also return the remaining cases, to enable GADT handling *) +(* Also return the remaining cases, to enable GADT handling + + For considerations regarding the coherence check, see the comment on + [satisfiable] above. *) let rec satisfiables pss qs = match pss with | [] -> if has_instances qs then [qs] else [] | _ -> @@ -990,36 +1249,43 @@ let rec satisfiables pss qs = match pss with | {pat_desc = Tpat_alias(q,_,_)}::qs -> satisfiables pss (q::qs) | {pat_desc = (Tpat_any | Tpat_var(_))}::qs -> - let q0 = discr_pat omega pss in - let wild p = - List.map (fun qs -> p::qs) (satisfiables (filter_extra pss) qs) in - begin match filter_all q0 pss with - (* first column of pss is made of variables only *) - | [] -> - wild omega - | (p,_)::_ as constrs -> - let for_constrs () = - List.flatten ( - List.map - (fun (p,pss) -> - if is_absent_pat p then [] else - List.map (set_args p) - (satisfiables pss (simple_match_args p omega @ qs))) - constrs ) - in - if full_match false constrs then for_constrs () else - match p.pat_desc with - Tpat_construct _ -> - (* activate this code for checking non-gadt constructors *) - wild (build_other_constrs constrs p) @ for_constrs () - | _ -> - wild omega + if not (all_coherent (simplified_first_col pss)) then + [] + else begin + let q0 = discr_pat omega pss in + let wild p = + List.map (fun qs -> p::qs) (satisfiables (filter_extra pss) qs) in + match filter_all q0 pss with + (* first column of pss is made of variables only *) + | [] -> + wild omega + | (p,_)::_ as constrs -> + let for_constrs () = + List.flatten ( + List.map + (fun (p,pss) -> + if is_absent_pat p then [] else + List.map (set_args p) + (satisfiables pss (simple_match_args p omega @ qs))) + constrs ) + in + if full_match false constrs then for_constrs () else + match p.pat_desc with + Tpat_construct _ -> + (* activate this code for checking non-gadt constructors *) + wild (build_other_constrs constrs p) @ for_constrs () + | _ -> + wild omega end | {pat_desc=Tpat_variant (l,_,r)}::_ when is_absent l r -> [] | q::qs -> - let q0 = discr_pat q pss in - List.map (set_args q0) - (satisfiables (filter_one q0 pss) (simple_match_args q0 q @ qs)) + if not (all_coherent (q :: simplified_first_col pss)) then + [] + else begin + let q0 = discr_pat q pss in + List.map (set_args q0) + (satisfiables (filter_one q0 pss) (simple_match_args q0 q @ qs)) + end (* Now another satisfiable function that additionally @@ -1143,52 +1409,67 @@ let rec exhaust_gadt (ext:Path.t option) pss n = match pss with | [] -> Rsome [omegas n] | []::_ -> Rnone | pss -> - let q0 = discr_pat omega pss in - begin match filter_all q0 pss with - (* first column of pss is made of variables only *) - | [] -> - begin match exhaust_gadt ext (filter_extra pss) (n-1) with - | Rsome r -> Rsome (List.map (fun row -> q0::row) r) - | r -> r - end - | constrs -> - let try_non_omega (p,pss) = - if is_absent_pat p then - Rnone - else - match - exhaust_gadt - ext pss (List.length (simple_match_args p omega) + n - 1) - with - | Rsome r -> Rsome (List.map (fun row -> (set_args p row)) r) - | r -> r in - let before = try_many_gadt try_non_omega constrs in - if - full_match false constrs && not (should_extend ext constrs) - then - before - else - (* - D = filter_extra pss is the default matrix - as it is included in pss, one can avoid - recursive calls on specialized matrices, - Essentially : - * D exhaustive => pss exhaustive - * D non-exhaustive => we have a non-filtered value - *) - let r = exhaust_gadt ext (filter_extra pss) (n-1) in - match r with - | Rnone -> before - | Rsome r -> - try - let p = build_other ext constrs in - let dug = List.map (fun tail -> p :: tail) r in - match before with - | Rnone -> Rsome dug - | Rsome x -> Rsome (x @ dug) + if not (all_coherent (simplified_first_col pss)) then + (* We're considering an ill-typed branch, we won't actually be able to + produce a well typed value taking that branch. *) + Rnone + else begin + (* Assuming the first column is ill-typed but considered coherent, we + might end up producing an ill-typed witness of non-exhaustivity + corresponding to the current branch. + + If [exhaust] has been called by [do_check_partial], then the witnesses + produced get typechecked and the ill-typed ones are discarded. + + If [exhaust] has been called by [do_check_fragile], then it is possible + we might fail to warn the user that the matching is fragile. See for + example testsuite/tests/warnings/w04_failure.ml. *) + let q0 = discr_pat omega pss in + match filter_all q0 pss with + (* first column of pss is made of variables only *) + | [] -> + begin match exhaust_gadt ext (filter_extra pss) (n-1) with + | Rsome r -> Rsome (List.map (fun row -> q0::row) r) + | r -> r + end + | constrs -> + let try_non_omega (p,pss) = + if is_absent_pat p then + Rnone + else + match + exhaust_gadt + ext pss (List.length (simple_match_args p omega) + n - 1) with - (* cannot occur, since constructors don't make a full signature *) - | Empty -> fatal_error "Parmatch.exhaust" + | Rsome r -> Rsome (List.map (fun row -> (set_args p row)) r) + | r -> r in + let before = try_many_gadt try_non_omega constrs in + if + full_match false constrs && not (should_extend ext constrs) + then + before + else + (* + D = filter_extra pss is the default matrix + as it is included in pss, one can avoid + recursive calls on specialized matrices, + Essentially : + * D exhaustive => pss exhaustive + * D non-exhaustive => we have a non-filtered value + *) + let r = exhaust_gadt ext (filter_extra pss) (n-1) in + match r with + | Rnone -> before + | Rsome r -> + try + let p = build_other ext constrs in + let dug = List.map (fun tail -> p :: tail) r in + match before with + | Rnone -> Rsome dug + | Rsome x -> Rsome (x @ dug) + with + (* cannot occur, since constructors don't make a full signature *) + | Empty -> fatal_error "Parmatch.exhaust" end let exhaust_gadt ext pss n = @@ -1223,35 +1504,38 @@ let rec pressure_variants tdefs = function | [] -> false | []::_ -> true | pss -> - let q0 = discr_pat omega pss in - begin match filter_all q0 pss with - [] -> pressure_variants tdefs (filter_extra pss) - | constrs -> - let rec try_non_omega = function - (_p,pss) :: rem -> - let ok = pressure_variants tdefs pss in - try_non_omega rem && ok - | [] -> true - in - if full_match (tdefs=None) constrs then - try_non_omega constrs - else if tdefs = None then - pressure_variants None (filter_extra pss) - else - let full = full_match true constrs in - let ok = - if full then try_non_omega constrs - else try_non_omega (filter_all q0 (mark_partial pss)) + if not (all_coherent (simplified_first_col pss)) then + true + else begin + let q0 = discr_pat omega pss in + match filter_all q0 pss with + [] -> pressure_variants tdefs (filter_extra pss) + | constrs -> + let rec try_non_omega = function + (_p,pss) :: rem -> + let ok = pressure_variants tdefs pss in + try_non_omega rem && ok + | [] -> true in - begin match constrs, tdefs with - ({pat_desc=Tpat_variant _} as p,_):: _, Some env -> - let row = row_of_pat p in - if Btype.row_fixed row - || pressure_variants None (filter_extra pss) then () - else close_variant env row - | _ -> () - end; - ok + if full_match (tdefs=None) constrs then + try_non_omega constrs + else if tdefs = None then + pressure_variants None (filter_extra pss) + else + let full = full_match true constrs in + let ok = + if full then try_non_omega constrs + else try_non_omega (filter_all q0 (mark_partial pss)) + in + begin match constrs, tdefs with + ({pat_desc=Tpat_variant _} as p,_):: _, Some env -> + let row = row_of_pat p in + if Btype.row_fixed row + || pressure_variants None (filter_extra pss) then () + else close_variant env row + | _ -> () + end; + ok end @@ -1370,7 +1654,7 @@ let filter_one q rs = (* Back to normal matrices *) -let make_vector r = r.no_ors +let make_vector r = List.rev r.no_ors let make_matrix rs = List.map make_vector rs @@ -1413,6 +1697,12 @@ let extract_columns pss qs = match pss with The idea is to first look for or patterns (recursive case), then check or-patterns argument usefulness (terminal case) *) +let rec simplified_first_usefulness_col = function + | [] -> [] + | row :: rows -> + match row.active with + | [] -> assert false (* the rows are non-empty! *) + | p :: _ -> simplify_head_pat p (simplified_first_usefulness_col rows) let rec every_satisfiables pss qs = match qs.active with | [] -> @@ -1461,10 +1751,16 @@ let rec every_satisfiables pss qs = match qs.active with Unused | _ -> (* standard case, filter matrix *) - let q0 = discr_pat q pss in - every_satisfiables - (filter_one q0 pss) - {qs with active=simple_match_args q0 q @ rem} + (* The handling of incoherent matrices is kept in line with + [satisfiable] *) + if not (all_coherent (uq :: simplified_first_usefulness_col pss)) then + Unused + else begin + let q0 = discr_pat q pss in + every_satisfiables + (filter_one q0 pss) + {qs with active=simple_match_args q0 q @ rem} + end end (* @@ -1690,6 +1986,8 @@ let rec do_match pss qs = match qs with do_match (do_filter_var pss) qs | _ -> let q0 = normalize_pat q in + (* [pss] will (or won't) match [q0 :: qs] regardless of the coherence of + its first column. *) do_match (do_filter_one q0 pss) (simple_match_args q0 q @ qs) @@ -2245,13 +2543,25 @@ let rec do_stable rs = match rs with collect_stable rs | _ -> let rs = push_vars rs in - match filter_all rs with - | [] -> - do_stable (List.map snd rs) - | (_,rs)::env -> - List.fold_left - (fun xs (_,rs) -> IdSet.inter xs (do_stable rs)) - (do_stable rs) env + if not (all_coherent (first_column rs)) then begin + (* If the first column is incoherent, then all the variables of this + matrix are stable. *) + List.fold_left (fun acc (_, { seen; _ }) -> + List.fold_left IdSet.union acc seen + ) IdSet.empty rs + end else begin + (* If the column is ill-typed but deemed coherent, we might spuriously + warn about some variables being unstable. + As sad as that might be, the warning can be silenced by splitting the + or-pattern... *) + match filter_all rs with + | [] -> + do_stable (List.map snd rs) + | (_,rs)::env -> + List.fold_left + (fun xs (_,rs) -> IdSet.inter xs (do_stable rs)) + (do_stable rs) env + end let stable p = do_stable [{unseen=[p]; seen=[];}] diff --git a/typing/parmatch.mli b/typing/parmatch.mli index 0fb4f757..feecb0c5 100644 --- a/typing/parmatch.mli +++ b/typing/parmatch.mli @@ -35,8 +35,20 @@ val const_compare : constant -> constant -> int val le_pat : pattern -> pattern -> bool val le_pats : pattern list -> pattern list -> bool -val compat : pattern -> pattern -> bool -val compats : pattern list -> pattern list -> bool + +(* Exported compatibility functor, abstracted over constructor equality *) +module Compat : + functor + (Constr: sig + val equal : + Types.constructor_description -> + Types.constructor_description -> + bool + end) -> sig + val compat : pattern -> pattern -> bool + val compats : pattern list -> pattern list -> bool + end + exception Empty val lub : pattern -> pattern -> pattern val lubs : pattern list -> pattern list -> pattern list @@ -83,3 +95,6 @@ val inactive : partial:partial -> pattern -> bool (* Ambiguous bindings *) val check_ambiguous_bindings : case list -> unit + +(* The tag used for open polymorphic variant types *) +val some_other_tag : label diff --git a/typing/typecore.ml b/typing/typecore.ml index b4cfb8b0..bf86107c 100644 --- a/typing/typecore.ml +++ b/typing/typecore.ml @@ -1213,7 +1213,10 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env row_more = newvar (); row_fixed = false; row_name = None } in - unify_pat_types loc !env (newty (Tvariant row)) expected_ty; + (* PR#7404: allow some_other_tag blindly, as it would not unify with + the abstract row variable *) + if l = Parmatch.some_other_tag then assert (constrs <> None) + else unify_pat_types loc !env (newty (Tvariant row)) expected_ty; let k arg = rp k { pat_desc = Tpat_variant(l, arg, ref {row with row_more = newvar()}); diff --git a/typing/types.ml b/typing/types.ml index 51d58a9a..7ef6eaff 100644 --- a/typing/types.ml +++ b/typing/types.ml @@ -331,6 +331,10 @@ let equal_tag t1 t2 = Path.same path1 path2 && b1 = b2 | (Cstr_constant _|Cstr_block _|Cstr_unboxed|Cstr_extension _), _ -> false +let may_equal_constr c1 c2 = match c1.cstr_tag,c2.cstr_tag with +| Cstr_extension _,Cstr_extension _ -> c1.cstr_arity = c2.cstr_arity +| tag1,tag2 -> equal_tag tag1 tag2 + type label_description = { lbl_name: string; (* Short name *) lbl_res: type_expr; (* Type of the result *) diff --git a/typing/types.mli b/typing/types.mli index 633aa31d..28317b52 100644 --- a/typing/types.mli +++ b/typing/types.mli @@ -473,8 +473,13 @@ and constructor_tag = | Cstr_extension of Path.t * bool (* Extension constructor true if a constant false if a block*) +(* Constructors are the same *) val equal_tag : constructor_tag -> constructor_tag -> bool +(* Constructors may be the same, given potential rebinding *) +val may_equal_constr : + constructor_description -> constructor_description -> bool + type label_description = { lbl_name: string; (* Short name *) lbl_res: type_expr; (* Type of the result *) -- 2.30.2