summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Garrigue <garrigue at math.nagoya-u.ac.jp>2015-10-16 00:13:40 +0000
committerJacques Garrigue <garrigue at math.nagoya-u.ac.jp>2015-10-16 00:13:40 +0000
commite34f40ad87b04a823a0172e1399e28199f89ba68 (patch)
tree4dd4acb3c9483188744c700041d8143e8b4f8113
parent4188f0543de0818211298ac96acfd49ad82b0b87 (diff)
downloadocaml-gadt-warnings.tar.gz
switch to 'pat -> .' and add P/Texp_unreachablegadt-warnings
git-svn-id: http://caml.inria.fr/svn/ocaml/branches/gadt-warnings@16507 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--bytecomp/matching.ml1
-rw-r--r--bytecomp/translcore.ml14
-rw-r--r--bytecomp/translcore.mli1
-rw-r--r--parsing/ast_helper.ml10
-rw-r--r--parsing/ast_helper.mli2
-rw-r--r--parsing/ast_mapper.ml3
-rw-r--r--parsing/parser.mly4
-rw-r--r--parsing/parsetree.mli4
-rw-r--r--parsing/pprintast.ml14
-rw-r--r--parsing/printast.ml4
-rw-r--r--testsuite/tests/typing-gadts/omega07.ml2
-rw-r--r--testsuite/tests/typing-gadts/pr5332.ml2
-rw-r--r--testsuite/tests/typing-gadts/pr5332.ml.reference2
-rw-r--r--testsuite/tests/typing-gadts/pr6163.ml2
-rw-r--r--testsuite/tests/typing-gadts/pr6163.ml.principal.reference2
-rw-r--r--testsuite/tests/typing-gadts/pr6163.ml.reference2
-rw-r--r--testsuite/tests/typing-gadts/test.ml2
-rw-r--r--testsuite/tests/typing-gadts/test.ml.principal.reference2
-rw-r--r--testsuite/tests/typing-gadts/test.ml.reference2
-rw-r--r--testsuite/tests/typing-warnings/exhaustiveness.ml4
-rw-r--r--testsuite/tests/typing-warnings/exhaustiveness.ml.reference8
-rw-r--r--tools/depend.ml3
-rw-r--r--tools/ocamlprof.ml26
-rw-r--r--typing/parmatch.ml4
-rw-r--r--typing/parmatch.mli4
-rw-r--r--typing/printtyped.ml2
-rw-r--r--typing/tast_mapper.ml2
-rw-r--r--typing/typeclass.ml3
-rw-r--r--typing/typecore.ml48
-rw-r--r--typing/typecore.mli2
-rw-r--r--typing/typedtree.ml9
-rw-r--r--typing/typedtree.mli9
-rw-r--r--typing/typedtreeIter.ml2
-rw-r--r--typing/typedtreeMap.ml2
-rw-r--r--typing/untypeast.ml4
-rw-r--r--utils/warnings.ml2
36 files changed, 111 insertions, 98 deletions
diff --git a/bytecomp/matching.ml b/bytecomp/matching.ml
index 1bdeef8ea7..0683821c27 100644
--- a/bytecomp/matching.ml
+++ b/bytecomp/matching.ml
@@ -2948,6 +2948,7 @@ let check_partial is_mutable is_lazy pat_act_list = function
| Partial -> Partial
| Total ->
if
+ pat_act_list = [] || (* allow empty case list *)
List.exists
(fun (pats, lam) ->
is_mutable pats && (is_guarded lam || is_lazy pats))
diff --git a/bytecomp/translcore.ml b/bytecomp/translcore.ml
index 6b43989130..49f27d8ae7 100644
--- a/bytecomp/translcore.ml
+++ b/bytecomp/translcore.ml
@@ -26,6 +26,7 @@ type error =
| Illegal_letrec_expr
| Free_super_var
| Unknown_builtin_primitive of string
+ | Unreachable_reached
exception Error of Location.t * error
@@ -956,6 +957,8 @@ and transl_exp0 e =
cl_env = e.exp_env;
cl_attributes = [];
}
+ | Texp_unreachable ->
+ raise (Error (e.exp_loc, Unreachable_reached))
and transl_list expr_list =
List.map transl_exp expr_list
@@ -971,6 +974,8 @@ and transl_case {c_lhs; c_guard; c_rhs} =
c_lhs, transl_guard c_guard c_rhs
and transl_cases cases =
+ let cases =
+ List.filter (fun c -> c.c_rhs.exp_desc <> Texp_unreachable) cases in
List.map transl_case cases
and transl_case_try {c_lhs; c_guard; c_rhs} =
@@ -985,9 +990,14 @@ and transl_case_try {c_lhs; c_guard; c_rhs} =
c_lhs, transl_guard c_guard c_rhs
and transl_cases_try cases =
+ let cases =
+ List.filter (fun c -> c.c_rhs.exp_desc <> Texp_unreachable) cases in
List.map transl_case_try cases
and transl_tupled_cases patl_expr_list =
+ let patl_expr_list =
+ List.filter (fun (_,_,e) -> e.exp_desc <> Texp_unreachable)
+ patl_expr_list in
List.map (fun (patl, guard, expr) -> (patl, transl_guard guard expr))
patl_expr_list
@@ -1241,7 +1251,9 @@ let report_error ppf = function
fprintf ppf
"Ancestor names can only be used to select inherited methods"
| Unknown_builtin_primitive prim_name ->
- fprintf ppf "Unknown builtin primitive \"%s\"" prim_name
+ fprintf ppf "Unknown builtin primitive \"%s\"" prim_name
+ | Unreachable_reached ->
+ fprintf ppf "Unreachable expression was reached"
let () =
Location.register_error_of_exn
diff --git a/bytecomp/translcore.mli b/bytecomp/translcore.mli
index 75ba9fcf02..a02de11862 100644
--- a/bytecomp/translcore.mli
+++ b/bytecomp/translcore.mli
@@ -32,6 +32,7 @@ type error =
| Illegal_letrec_expr
| Free_super_var
| Unknown_builtin_primitive of string
+ | Unreachable_reached
exception Error of Location.t * error
diff --git a/parsing/ast_helper.ml b/parsing/ast_helper.ml
index 0c7357f34d..276603d846 100644
--- a/parsing/ast_helper.ml
+++ b/parsing/ast_helper.ml
@@ -115,19 +115,13 @@ module Exp = struct
let pack ?loc ?attrs a = mk ?loc ?attrs (Pexp_pack a)
let open_ ?loc ?attrs a b c = mk ?loc ?attrs (Pexp_open (a, b, c))
let extension ?loc ?attrs a = mk ?loc ?attrs (Pexp_extension a)
+ let unreachable ?loc ?attrs () = mk ?loc ?attrs Pexp_unreachable
let case lhs ?guard rhs =
{
pc_lhs = lhs;
pc_guard = guard;
- pc_rhs = Some rhs;
- }
-
- let case_lhs lhs =
- {
- pc_lhs = lhs;
- pc_guard = None;
- pc_rhs = None;
+ pc_rhs = rhs;
}
end
diff --git a/parsing/ast_helper.mli b/parsing/ast_helper.mli
index 1b42a24034..90c5bf9a2e 100644
--- a/parsing/ast_helper.mli
+++ b/parsing/ast_helper.mli
@@ -139,9 +139,9 @@ module Exp:
val pack: ?loc:loc -> ?attrs:attrs -> module_expr -> expression
val open_: ?loc:loc -> ?attrs:attrs -> override_flag -> lid -> expression -> expression
val extension: ?loc:loc -> ?attrs:attrs -> extension -> expression
+ val unreachable: ?loc:loc -> ?attrs:attrs -> unit -> expression
val case: pattern -> ?guard:expression -> expression -> case
- val case_lhs: pattern -> case
end
(** Value declarations *)
diff --git a/parsing/ast_mapper.ml b/parsing/ast_mapper.ml
index 12298c96c9..05823a7ee8 100644
--- a/parsing/ast_mapper.ml
+++ b/parsing/ast_mapper.ml
@@ -376,6 +376,7 @@ module E = struct
| Pexp_open (ovf, lid, e) ->
open_ ~loc ~attrs ovf (map_loc sub lid) (sub.expr sub e)
| Pexp_extension x -> extension ~loc ~attrs (sub.extension sub x)
+ | Pexp_unreachable -> unreachable ~loc ~attrs ()
end
module P = struct
@@ -600,7 +601,7 @@ let default_mapper =
{
pc_lhs = this.pat this pc_lhs;
pc_guard = map_opt (this.expr this) pc_guard;
- pc_rhs = map_opt (this.expr this) pc_rhs;
+ pc_rhs = this.expr this pc_rhs;
}
);
diff --git a/parsing/parser.mly b/parsing/parser.mly
index 3f20e46d2c..2f8d65f84c 100644
--- a/parsing/parser.mly
+++ b/parsing/parser.mly
@@ -1490,8 +1490,8 @@ match_case:
{ Exp.case $1 $3 }
| pattern WHEN seq_expr MINUSGREATER seq_expr
{ Exp.case $1 ~guard:$3 $5 }
- | pattern MINUSGREATER UNDERSCORE
- { Exp.case_lhs $1 }
+ | pattern MINUSGREATER DOT
+ { Exp.case $1 (Exp.unreachable ~loc:(rhs_loc 3) ())}
;
fun_def:
MINUSGREATER seq_expr { $2 }
diff --git a/parsing/parsetree.mli b/parsing/parsetree.mli
index d9a4d7cd01..95dbd4f83c 100644
--- a/parsing/parsetree.mli
+++ b/parsing/parsetree.mli
@@ -320,12 +320,14 @@ and expression_desc =
*)
| Pexp_extension of extension
(* [%id] *)
+ | Pexp_unreachable
+ (* . *)
and case = (* (P -> E) or (P when E0 -> E) *)
{
pc_lhs: pattern;
pc_guard: expression option;
- pc_rhs: expression option;
+ pc_rhs: expression;
}
(* Value descriptions *)
diff --git a/parsing/pprintast.ml b/parsing/pprintast.ml
index def0099718..bf563edb71 100644
--- a/parsing/pprintast.ml
+++ b/parsing/pprintast.ml
@@ -614,6 +614,8 @@ class printer ()= object(self:'self)
| Pexp_variant (l,Some eo) ->
pp f "@[<2>`%s@;%a@]" l self#simple_expr eo
| Pexp_extension e -> self#extension f e
+ | Pexp_unreachable ->
+ pp f "."
| _ -> self#expression1 f x
method expression1 f x =
if x.pexp_attributes <> [] then self#expression f x
@@ -1341,15 +1343,9 @@ class printer ()= object(self:'self)
method case_list f l : unit =
let aux f {pc_lhs; pc_guard; pc_rhs} =
- match pc_rhs with
- | Some pc_rhs ->
- pp f "@;| @[<2>%a%a@;->@;%a@]"
- self#pattern pc_lhs
- (self#option self#expression ~first:"@;when@;") pc_guard
- self#under_pipe#expression pc_rhs
- | None ->
- pp f "@;| @[<2>%a@;-> _@]"
- self#pattern pc_lhs
+ pp f "@;| @[<2>%a%a@;->@;%a@]"
+ self#pattern pc_lhs (self#option self#expression ~first:"@;when@;")
+ pc_guard self#under_pipe#expression pc_rhs
in
self#list aux f l ~sep:""
method label_x_expression_param f (l,e) =
diff --git a/parsing/printast.ml b/parsing/printast.ml
index 9aa10b6751..8297ac9ef4 100644
--- a/parsing/printast.ml
+++ b/parsing/printast.ml
@@ -365,6 +365,8 @@ and expression i ppf x =
| Pexp_extension (s, arg) ->
line i ppf "Pexp_extension \"%s\"\n" s.txt;
payload i ppf arg
+ | Pexp_unreachable ->
+ line i ppf "Pexp_unreachable"
and value_description i ppf x =
line i ppf "value_description %a %a\n" fmt_string_loc
@@ -842,7 +844,7 @@ and case i ppf {pc_lhs; pc_guard; pc_rhs} =
| None -> ()
| Some g -> line (i+1) ppf "<when>\n"; expression (i + 2) ppf g
end;
- option (i+1) expression ppf pc_rhs;
+ expression (i+1) ppf pc_rhs;
and value_binding i ppf x =
line i ppf "<def>\n";
diff --git a/testsuite/tests/typing-gadts/omega07.ml b/testsuite/tests/typing-gadts/omega07.ml
index 472cbc9e11..ddd7133cfd 100644
--- a/testsuite/tests/typing-gadts/omega07.ml
+++ b/testsuite/tests/typing-gadts/omega07.ml
@@ -204,7 +204,7 @@ let rec diff : type a b. (a,b) le -> a nat -> b nat -> (a,b) diff =
| NZ, m, LeZ _ -> Diff (m, PlusZ m)
| NS x, NS y, LeS q ->
(match diff q x y with Diff (m, p) -> Diff (m, PlusS p))
- | _ -> _
+ | _ -> .
;;
let rec diff : type a b. (a,b) le -> b nat -> (a,b) diff =
diff --git a/testsuite/tests/typing-gadts/pr5332.ml b/testsuite/tests/typing-gadts/pr5332.ml
index 6473ca6265..862706326f 100644
--- a/testsuite/tests/typing-gadts/pr5332.ml
+++ b/testsuite/tests/typing-gadts/pr5332.ml
@@ -12,7 +12,7 @@ let f : type env a. (env, a) typ -> (env, a) typ -> int = fun ta tb ->
| Tint, Tint -> 0
| Tbool, Tbool -> 1
| Tvar var, tb -> 2
- | _ -> _ (* error *)
+ | _ -> . (* error *)
;;
(* let x = f Tint (Tvar Zero) ;; *)
diff --git a/testsuite/tests/typing-gadts/pr5332.ml.reference b/testsuite/tests/typing-gadts/pr5332.ml.reference
index 2e943424d9..10656769d1 100644
--- a/testsuite/tests/typing-gadts/pr5332.ml.reference
+++ b/testsuite/tests/typing-gadts/pr5332.ml.reference
@@ -7,7 +7,7 @@
| Tbool : ('env, bool) typ
| Tvar : ('env, 'a) var -> ('env, 'a) typ
# Characters 162-163:
- | _ -> _ (* error *)
+ | _ -> . (* error *)
^
Error: This match case could not be refuted.
Here is an example of value that would reach it: (Tint, Tvar Zero)
diff --git a/testsuite/tests/typing-gadts/pr6163.ml b/testsuite/tests/typing-gadts/pr6163.ml
index 8258e0819b..dc5bb8c67e 100644
--- a/testsuite/tests/typing-gadts/pr6163.ml
+++ b/testsuite/tests/typing-gadts/pr6163.ml
@@ -11,5 +11,5 @@ let f (Aux x) =
| Succ (Succ Zero) -> "2"
| Succ (Succ (Succ Zero)) -> "3"
| Succ (Succ (Succ (Succ Zero))) -> "4"
- | _ -> _
+ | _ -> . (* error *)
;;
diff --git a/testsuite/tests/typing-gadts/pr6163.ml.principal.reference b/testsuite/tests/typing-gadts/pr6163.ml.principal.reference
index fd34007b82..c19965bfc6 100644
--- a/testsuite/tests/typing-gadts/pr6163.ml.principal.reference
+++ b/testsuite/tests/typing-gadts/pr6163.ml.principal.reference
@@ -6,7 +6,7 @@
[ `Succ of [< [< [< [ `Zero ] pre_nat ] pre_nat ] pre_nat ] ] nat ->
aux
# Characters 162-163:
- | _ -> _
+ | _ -> . (* error *)
^
Error: This match case could not be refuted.
Here is an example of value that would reach it:
diff --git a/testsuite/tests/typing-gadts/pr6163.ml.reference b/testsuite/tests/typing-gadts/pr6163.ml.reference
index fd34007b82..c19965bfc6 100644
--- a/testsuite/tests/typing-gadts/pr6163.ml.reference
+++ b/testsuite/tests/typing-gadts/pr6163.ml.reference
@@ -6,7 +6,7 @@
[ `Succ of [< [< [< [ `Zero ] pre_nat ] pre_nat ] pre_nat ] ] nat ->
aux
# Characters 162-163:
- | _ -> _
+ | _ -> . (* error *)
^
Error: This match case could not be refuted.
Here is an example of value that would reach it:
diff --git a/testsuite/tests/typing-gadts/test.ml b/testsuite/tests/typing-gadts/test.ml
index 076920baeb..cfd14a2055 100644
--- a/testsuite/tests/typing-gadts/test.ml
+++ b/testsuite/tests/typing-gadts/test.ml
@@ -129,7 +129,7 @@ module PR6437 = struct
let rec f : type g1 g2. (g1, g2) ctx * g1 var -> g2 var = function
| Cons g, O -> O
| Cons g, S n -> S (f (g, n))
- | _ -> _
+ | _ -> .
(*| Nil, _ -> (assert false) *) (* warns, but shouldn't *)
end;;
diff --git a/testsuite/tests/typing-gadts/test.ml.principal.reference b/testsuite/tests/typing-gadts/test.ml.principal.reference
index a2d931d2e6..671f7af1ef 100644
--- a/testsuite/tests/typing-gadts/test.ml.principal.reference
+++ b/testsuite/tests/typing-gadts/test.ml.principal.reference
@@ -71,7 +71,7 @@ module PR6862 :
let g : int t -> int = function I -> 1 | _ -> 2 (* no warning *)
^
Warning 51: this match case is unreachable.
-Consider replacing it with '<pat> -> _'
+Consider replacing it with a refutation case '<pat> -> .'
module PR6220 :
sig
type 'a t = I : int t | F : float t
diff --git a/testsuite/tests/typing-gadts/test.ml.reference b/testsuite/tests/typing-gadts/test.ml.reference
index 096ca071b3..5c0eb39cb0 100644
--- a/testsuite/tests/typing-gadts/test.ml.reference
+++ b/testsuite/tests/typing-gadts/test.ml.reference
@@ -71,7 +71,7 @@ module PR6862 :
let g : int t -> int = function I -> 1 | _ -> 2 (* no warning *)
^
Warning 51: this match case is unreachable.
-Consider replacing it with '<pat> -> _'
+Consider replacing it with a refutation case '<pat> -> .'
module PR6220 :
sig
type 'a t = I : int t | F : float t
diff --git a/testsuite/tests/typing-warnings/exhaustiveness.ml b/testsuite/tests/typing-warnings/exhaustiveness.ml
index 0e3f5cbe20..57aac3f13c 100644
--- a/testsuite/tests/typing-warnings/exhaustiveness.ml
+++ b/testsuite/tests/typing-warnings/exhaustiveness.ml
@@ -82,7 +82,7 @@ let harder : (zero succ, zero succ, zero succ) plus option -> bool =
function None -> false
;;
let harder : (zero succ, zero succ, zero succ) plus option -> bool =
- function None -> false | Some (PlusS _) -> _
+ function None -> false | Some (PlusS _) -> .
;;
let inv_zero : type a b c d. (a,b,c) plus -> (c,d,zero) plus -> bool =
fun p1 p2 ->
@@ -94,4 +94,4 @@ let inv_zero : type a b c d. (a,b,c) plus -> (c,d,zero) plus -> bool =
(* Empty match *)
type _ t = Int : int t;;
-let f (x : bool t) = match x with _ -> _;;
+let f (x : bool t) = match x with _ -> . ;;
diff --git a/testsuite/tests/typing-warnings/exhaustiveness.ml.reference b/testsuite/tests/typing-warnings/exhaustiveness.ml.reference
index 890b918012..a8b3f4418f 100644
--- a/testsuite/tests/typing-warnings/exhaustiveness.ml.reference
+++ b/testsuite/tests/typing-warnings/exhaustiveness.ml.reference
@@ -20,7 +20,7 @@ Characters 172-200:
| _, _, _, _, _, _, _, G, _, _ -> 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Warning 51: this match case is unreachable.
-Consider replacing it with '<pat> -> _'
+Consider replacing it with a refutation case '<pat> -> .'
val f :
'a t * 'b t * 'c t * 'd t * 'e t * 'f t * 'g t * v * ('a, 'b, 'c, 'd) u *
('e, 'f, 'g, 'g) u -> int = <fun>
@@ -33,19 +33,19 @@ Characters 62-63:
let f (x : int t) = match x with A -> 1 | _ -> 2;; (* warn *)
^
Warning 51: this match case is unreachable.
-Consider replacing it with '<pat> -> _'
+Consider replacing it with a refutation case '<pat> -> .'
val f : int t -> int = <fun>
# Characters 53-54:
let f (x : unit t option) = match x with None -> 1 | _ -> 2 ;; (* warn? *)
^
Warning 51: this match case is unreachable.
-Consider replacing it with '<pat> -> _'
+Consider replacing it with a refutation case '<pat> -> .'
val f : unit t option -> int = <fun>
# Characters 53-59:
let f (x : unit t option) = match x with None -> 1 | Some _ -> 2 ;; (* warn *)
^^^^^^
Warning 51: this match case is unreachable.
-Consider replacing it with '<pat> -> _'
+Consider replacing it with a refutation case '<pat> -> .'
val f : unit t option -> int = <fun>
# val f : int t option -> int = <fun>
# Characters 27-49:
diff --git a/tools/depend.ml b/tools/depend.ml
index c788eb2ec5..b9c84368e7 100644
--- a/tools/depend.ml
+++ b/tools/depend.ml
@@ -201,6 +201,7 @@ let rec add_expr bv exp =
| Pexp_pack m -> add_module bv m
| Pexp_open (_ovf, m, e) -> open_module bv m.txt; add_expr bv e
| Pexp_extension _ -> ()
+ | Pexp_unreachable -> ()
and add_cases bv cases =
List.iter (add_case bv) cases
@@ -208,7 +209,7 @@ and add_cases bv cases =
and add_case bv {pc_lhs; pc_guard; pc_rhs} =
let bv = add_pattern bv pc_lhs in
add_opt add_expr bv pc_guard;
- add_opt add_expr bv pc_rhs
+ add_expr bv pc_rhs
and add_bindings recf bv pel =
let bv' = List.fold_left (fun bv x -> add_pattern bv x.pvb_pat) bv pel in
diff --git a/tools/ocamlprof.ml b/tools/ocamlprof.ml
index 18e4681e2a..69af5f5bc0 100644
--- a/tools/ocamlprof.ml
+++ b/tools/ocamlprof.ml
@@ -153,15 +153,14 @@ let rec rewrite_patexp_list iflag l =
and rewrite_cases iflag l =
List.iter
(fun pc ->
- rewrite_exp_opt iflag pc.pc_guard;
- rewrite_exp_opt iflag pc.pc_rhs)
+ begin match pc.pc_guard with
+ | None -> ()
+ | Some g -> rewrite_exp iflag g
+ end;
+ rewrite_exp iflag pc.pc_rhs
+ )
l
-and rewrite_exp_opt iflag o =
- match o with
- None -> ()
- | Some e -> rewrite_exp iflag e
-
and rewrite_labelexp_list iflag l =
rewrite_exp_list iflag (List.map snd l)
@@ -188,7 +187,7 @@ and rw_exp iflag sexp =
rewrite_cases iflag caselist
| Pexp_fun (_, _, p, e) ->
- let l = [{pc_lhs=p; pc_guard=None; pc_rhs=Some e}] in
+ let l = [{pc_lhs=p; pc_guard=None; pc_rhs=e}] in
if !instr_fun then
rewrite_function iflag l
else
@@ -295,6 +294,7 @@ and rw_exp iflag sexp =
| Pexp_open (_ovf, _, e) -> rewrite_exp iflag e
| Pexp_pack (smod) -> rewrite_mod iflag smod
| Pexp_extension _ -> ()
+ | Pexp_unreachable -> ()
and rewrite_ifbody iflag ghost sifbody =
if !instr_if && not ghost then
@@ -306,19 +306,17 @@ and rewrite_ifbody iflag ghost sifbody =
and rewrite_annotate_exp_list l =
List.iter
(function
- | {pc_guard=Some scond; pc_rhs=Some sbody} ->
+ | {pc_guard=Some scond; pc_rhs=sbody} ->
insert_profile rw_exp scond;
insert_profile rw_exp sbody;
- | {pc_rhs=Some {pexp_desc = Pexp_constraint(sbody, _)}}
- (* let f x : t = e *)
+ | {pc_rhs={pexp_desc = Pexp_constraint(sbody, _)}} (* let f x : t = e *)
-> insert_profile rw_exp sbody
- | {pc_rhs=Some sexp} -> insert_profile rw_exp sexp
- | {pc_rhs=None} -> ())
+ | {pc_rhs=sexp} -> insert_profile rw_exp sexp)
l
and rewrite_function iflag = function
| [{pc_lhs=_; pc_guard=None;
- pc_rhs=Some ({pexp_desc = (Pexp_function _|Pexp_fun _)} as sexp)}] ->
+ pc_rhs={pexp_desc = (Pexp_function _|Pexp_fun _)} as sexp}] ->
rewrite_exp iflag sexp
| l -> rewrite_funmatching l
diff --git a/typing/parmatch.ml b/typing/parmatch.ml
index f1715923ab..16f51e252c 100644
--- a/typing/parmatch.ml
+++ b/typing/parmatch.ml
@@ -1907,7 +1907,7 @@ let do_check_fragile_gadt = do_check_fragile_param exhaust_gadt
let check_unused pred tdefs casel =
if Warnings.is_active Warnings.Unused_match
- || List.exists (fun c -> c.c_rhs = None) casel then
+ || List.exists (fun c -> c.c_rhs.exp_desc = Texp_unreachable) casel then
let rec do_rec pref = function
| [] -> ()
| {c_lhs=q; c_guard; c_rhs} :: rem ->
@@ -1917,7 +1917,7 @@ let check_unused pred tdefs casel =
get_mins le_pats (List.filter (compats qs) pref) in
(* First look for redundant or partially redundant patterns *)
let r = every_satisfiables (make_rows pss) (make_row qs) in
- let refute = (c_rhs = None) in
+ let refute = (c_rhs.exp_desc = Texp_unreachable) in
(* Do not warn for unused _ -> _ *)
if r = Unused && refute && q.pat_desc = Tpat_any then () else
let r =
diff --git a/typing/parmatch.mli b/typing/parmatch.mli
index b245724baf..89ab101821 100644
--- a/typing/parmatch.mli
+++ b/typing/parmatch.mli
@@ -62,13 +62,13 @@ val check_partial_gadt:
((string, constructor_description) Hashtbl.t ->
(string, label_description) Hashtbl.t ->
Parsetree.pattern -> pattern option) ->
- Location.t -> case_pat list -> partial
+ Location.t -> case list -> partial
val check_unused:
(bool ->
(string, constructor_description) Hashtbl.t ->
(string, label_description) Hashtbl.t ->
Parsetree.pattern -> pattern option) ->
- Env.t -> case_pat list -> unit
+ Env.t -> case list -> unit
(* Irrefutability tests *)
val irrefutable : pattern -> bool
diff --git a/typing/printtyped.ml b/typing/printtyped.ml
index 8270b6d8a8..ff0de30358 100644
--- a/typing/printtyped.ml
+++ b/typing/printtyped.ml
@@ -377,6 +377,8 @@ and expression i ppf x =
| Texp_pack me ->
line i ppf "Texp_pack";
module_expr i ppf me
+ | Texp_unreachable ->
+ line i ppf "Texp_unreachable"
and value_description i ppf x =
line i ppf "value_description %a %a\n" fmt_ident x.val_id fmt_location x.val_loc;
diff --git a/typing/tast_mapper.ml b/typing/tast_mapper.ml
index 7c7c774bb5..cddfd3e484 100644
--- a/typing/tast_mapper.ml
+++ b/typing/tast_mapper.ml
@@ -328,6 +328,8 @@ let expr sub x =
Texp_object (sub.class_structure sub cl, sl)
| Texp_pack mexpr ->
Texp_pack (sub.module_expr sub mexpr)
+ | Texp_unreachable ->
+ Texp_unreachable
in
{x with exp_extra; exp_desc; exp_env}
diff --git a/typing/typeclass.ml b/typing/typeclass.ml
index 6beeff6f22..73d4732998 100644
--- a/typing/typeclass.ml
+++ b/typing/typeclass.ml
@@ -957,8 +957,9 @@ and class_expr cl_num val_env met_env scl =
| _ -> true
in
let partial =
+ let dummy = type_exp val_env (Ast_helper.Exp.unreachable ()) in
Typecore.check_partial val_env pat.pat_type pat.pat_loc
- [{c_lhs = pat; c_guard = None; c_rhs = None}]
+ [{c_lhs = pat; c_guard = None; c_rhs = dummy}]
in
Ctype.raise_nongen_level ();
let cl = class_expr cl_num val_env' met_env scl' in
diff --git a/typing/typecore.ml b/typing/typecore.ml
index 30e9119344..aa2112c874 100644
--- a/typing/typecore.ml
+++ b/typing/typecore.ml
@@ -172,10 +172,11 @@ let iter_expression f e =
| Pexp_letmodule (_, me, e) -> expr e; module_expr me
| Pexp_object { pcstr_fields = fs } -> List.iter class_field fs
| Pexp_pack me -> module_expr me
+ | Pexp_unreachable -> ()
and case {pc_lhs = _; pc_guard; pc_rhs} =
may expr pc_guard;
- may expr pc_rhs
+ expr pc_rhs
and binding x =
expr x.pvb_expr
@@ -245,7 +246,7 @@ let all_idents_cases el =
List.iter
(fun cp ->
may (iter_expression f) cp.pc_guard;
- may (iter_expression f) cp.pc_rhs
+ iter_expression f cp.pc_rhs
)
el;
Hashtbl.fold (fun x () rest -> x :: rest) idents []
@@ -615,7 +616,7 @@ end) = struct
open Name
let get_type_path env d =
- match (get_type d).desc with
+ match (repr (get_type d)).desc with
| Tconstr(p, _, _) -> p
| _ -> assert false
@@ -1504,7 +1505,7 @@ let rec final_subexpression sexp =
| Pexp_sequence (_, e)
| Pexp_try (e, _)
| Pexp_ifthenelse (_, e, _)
- | Pexp_match (_, {pc_rhs=Some e} :: _)
+ | Pexp_match (_, {pc_rhs=e} :: _)
-> final_subexpression e
| _ -> sexp
@@ -1631,9 +1632,9 @@ let rec type_approx env sexp =
| Pexp_fun (p, _, _, e) ->
let ty = if is_optional p then type_option (newvar ()) else newvar () in
newty (Tarrow(p, ty, type_approx env e, Cok))
- | Pexp_function ({pc_rhs=Some e}::_) ->
+ | Pexp_function ({pc_rhs=e}::_) ->
newty (Tarrow(Nolabel, newvar (), type_approx env e, Cok))
- | Pexp_match (_, {pc_rhs=Some e}::_) -> type_approx env e
+ | Pexp_match (_, {pc_rhs=e}::_) -> type_approx env e
| Pexp_try (e, _) -> type_approx env e
| Pexp_tuple l -> newty (Ttuple(List.map (type_approx env) l))
| Pexp_ifthenelse (_,e,_) -> type_approx env e
@@ -2838,6 +2839,13 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
| Pexp_extension ext ->
raise (Error_forward (Typetexp.error_of_extension ext))
+ | Pexp_unreachable ->
+ re { exp_desc = Texp_unreachable;
+ exp_loc = loc; exp_extra = [];
+ exp_type = instance env ty_expected;
+ exp_attributes = sexp.pexp_attributes;
+ exp_env = env }
+
and type_function ?in_function loc attrs env ty_expected l caselist =
let (loc_fun, ty_fun) =
match in_function with Some p -> p
@@ -3620,9 +3628,10 @@ and type_cases ?in_function env ty_arg ty_res partial_flag loc caselist =
List.map
(fun {pc_lhs; pc_guard; pc_rhs} ->
let loc =
- match pc_rhs with
- | None -> pc_lhs.ppat_loc
- | Some e -> e.pexp_loc
+ let open Location in
+ match pc_guard with
+ | None -> pc_rhs.pexp_loc
+ | Some g -> {pc_rhs.pexp_loc with loc_start=g.pexp_loc.loc_start}
in
if !Clflags.principal then begin_def (); (* propagation of pattern *)
let scope = Some (Annot.Idef loc) in
@@ -3664,10 +3673,6 @@ and type_cases ?in_function env ty_arg ty_res partial_flag loc caselist =
let cases =
List.map2
(fun (pat, (ext_env, unpacks)) {pc_lhs; pc_guard; pc_rhs} ->
- match pc_guard, pc_rhs with
- | None, None -> { c_lhs = pat; c_guard = None; c_rhs = None}
- | Some _, None -> assert false
- | _, Some pc_rhs ->
let sexp = wrap_unpacks pc_rhs unpacks in
let ty_res' =
if !Clflags.principal then begin
@@ -3692,14 +3697,14 @@ and type_cases ?in_function env ty_arg ty_res partial_flag loc caselist =
{
c_lhs = pat;
c_guard = guard;
- c_rhs = Some {exp with exp_type = instance env ty_res'}
+ c_rhs = {exp with exp_type = instance env ty_res'}
}
)
pat_env_list caselist
in
if !Clflags.principal || has_gadts then begin
let ty_res' = instance env ty_res in
- List.iter (fun c -> may (fun e -> unify_exp env e ty_res') c.c_rhs) cases
+ List.iter (fun c -> unify_exp env c.c_rhs ty_res') cases
end;
let partial =
if partial_flag then
@@ -3720,11 +3725,6 @@ and type_cases ?in_function env ty_arg ty_res partial_flag loc caselist =
(* Ensure that existential types do not escape *)
unify_exp_types loc env (instance env ty_res) (newvar ()) ;
end;
- let cases = Misc.filter_map
- (function {c_rhs=None} -> None
- | {c_lhs;c_guard;c_rhs=Some c_rhs} -> Some{c_lhs;c_guard;c_rhs}) cases
- in
- if cases = [] then [], Partial else
cases, partial
(* Typing of let bindings *)
@@ -3893,10 +3893,10 @@ and type_let ?(check = fun s -> Warnings.Unused_var s)
&& Warnings.is_active Warnings.Unused_rec_flag then
Location.prerr_warning (List.hd spat_sexp_list).pvb_pat.ppat_loc
Warnings.Unused_rec_flag;
- List.iter
- (fun pat ->
- ignore(check_partial env pat.pat_type pat.pat_loc [case pat None]))
- pat_list;
+ List.iter2
+ (fun pat exp ->
+ ignore(check_partial env pat.pat_type pat.pat_loc [case pat exp]))
+ pat_list exp_list;
end_def();
List.iter2
(fun pat exp ->
diff --git a/typing/typecore.mli b/typing/typecore.mli
index d6aa126d10..e842f8ff66 100644
--- a/typing/typecore.mli
+++ b/typing/typecore.mli
@@ -43,7 +43,7 @@ val type_self_pattern:
Env.t * Env.t * Env.t
val check_partial:
?lev:int -> Env.t -> type_expr ->
- Location.t -> Typedtree.case_pat list -> Typedtree.partial
+ Location.t -> Typedtree.case list -> Typedtree.partial
val type_expect:
?in_function:(Location.t * type_expr) ->
Env.t -> Parsetree.expression -> type_expr -> Typedtree.expression
diff --git a/typing/typedtree.ml b/typing/typedtree.ml
index 0ba2027545..b57deb4925 100644
--- a/typing/typedtree.ml
+++ b/typing/typedtree.ml
@@ -105,22 +105,19 @@ and expression_desc =
| Texp_lazy of expression
| Texp_object of class_structure * string list
| Texp_pack of module_expr
+ | Texp_unreachable
and meth =
Tmeth_name of string
| Tmeth_val of Ident.t
-and case = expression case_expr
-
-and 'rhs case_expr =
+and case =
{
c_lhs: pattern;
c_guard: expression option;
- c_rhs: 'rhs;
+ c_rhs: expression;
}
-and case_pat = expression option case_expr
-
(* Value expressions for the class language *)
and class_expr =
diff --git a/typing/typedtree.mli b/typing/typedtree.mli
index 46d5f4ccdc..9fdcd26058 100644
--- a/typing/typedtree.mli
+++ b/typing/typedtree.mli
@@ -104,22 +104,19 @@ and expression_desc =
| Texp_lazy of expression
| Texp_object of class_structure * string list
| Texp_pack of module_expr
+ | Texp_unreachable
and meth =
Tmeth_name of string
| Tmeth_val of Ident.t
-and case = expression case_expr
-
-and 'rhs case_expr =
+and case =
{
c_lhs: pattern;
c_guard: expression option;
- c_rhs: 'rhs;
+ c_rhs: expression;
}
-and case_pat = expression option case_expr
-
(* Value expressions for the class language *)
and class_expr =
diff --git a/typing/typedtreeIter.ml b/typing/typedtreeIter.ml
index 8de50d711b..574ebef441 100644
--- a/typing/typedtreeIter.ml
+++ b/typing/typedtreeIter.ml
@@ -345,6 +345,8 @@ module MakeIterator(Iter : IteratorArgument) : sig
iter_class_structure cl
| Texp_pack (mexpr) ->
iter_module_expr mexpr
+ | Texp_unreachable ->
+ ()
end;
Iter.leave_expression exp;
diff --git a/typing/typedtreeMap.ml b/typing/typedtreeMap.ml
index e6c05de591..8431fac05a 100644
--- a/typing/typedtreeMap.ml
+++ b/typing/typedtreeMap.ml
@@ -377,6 +377,8 @@ module MakeMap(Map : MapArgument) = struct
Texp_object (map_class_structure cl, string_list)
| Texp_pack (mexpr) ->
Texp_pack (map_module_expr mexpr)
+ | Texp_unreachable ->
+ Texp_unreachable
in
let exp_extra = List.map map_exp_extra exp.exp_extra in
Map.leave_expression {
diff --git a/typing/untypeast.ml b/typing/untypeast.ml
index 62085d24dd..88c3f8435c 100644
--- a/typing/untypeast.ml
+++ b/typing/untypeast.ml
@@ -329,7 +329,7 @@ let case sub {c_lhs; c_guard; c_rhs} =
{
pc_lhs = sub.pat sub c_lhs;
pc_guard = map_opt (sub.expr sub) c_guard;
- pc_rhs = Some (sub.expr sub c_rhs);
+ pc_rhs = sub.expr sub c_rhs;
}
let value_binding sub vb =
@@ -444,6 +444,8 @@ let expression sub exp =
Pexp_object (sub.class_structure sub cl)
| Texp_pack (mexpr) ->
Pexp_pack (sub.module_expr sub mexpr)
+ | Texp_unreachable ->
+ Pexp_unreachable
in
List.fold_right (exp_extra sub) exp.exp_extra
(Exp.mk ~loc ~attrs desc)
diff --git a/utils/warnings.ml b/utils/warnings.ml
index 6ecdf382c9..44d5d2785c 100644
--- a/utils/warnings.ml
+++ b/utils/warnings.ml
@@ -392,7 +392,7 @@ let message = function
Printf.sprintf "expected tailcall"
| Unreachable_case ->
"this match case is unreachable.\n\
- Consider replacing it with '<pat> -> _'"
+ Consider replacing it with a refutation case '<pat> -> .'"
;;
let nerrors = ref 0;;