@@ -3647,72 +3647,135 @@ let check_recursive_class_bindings env ids exprs =
3647
3647
raise(Error (expr.cl_loc, env, Illegal_class_expr )))
3648
3648
exprs
3649
3649
3650
- (* Is the return value annotated with "local_" *)
3651
- let is_local_returning_expr e =
3652
- let combine (local1 , loc1 ) (local2 , loc2 ) =
3653
- match local1, local2 with
3654
- | true , true -> true , loc1
3655
- | false , false -> false , loc1
3656
- | false , true ->
3657
- raise(Error (loc1, Env. empty, Local_return_annotation_mismatch loc2))
3658
- | true , false ->
3659
- raise(Error (loc2, Env. empty, Local_return_annotation_mismatch loc1))
3660
- in
3661
- let rec loop e =
3662
- match Jane_syntax.Expression. of_ast e with
3663
- | Some (jexp , _attrs ) -> begin
3664
- match jexp with
3665
- | Jexp_comprehension _ -> false , e.pexp_loc
3666
- | Jexp_immutable_array _ -> false , e.pexp_loc
3667
- | Jexp_layout (Lexp_constant _ ) -> false , e.pexp_loc
3668
- | Jexp_layout (Lexp_newtype (_ , _ , e )) -> loop e
3669
- | Jexp_n_ary_function _ -> false , e.pexp_loc
3670
- end
3671
- | None ->
3672
- match e.pexp_desc with
3673
- | Pexp_apply
3674
- ({ pexp_desc = Pexp_extension (
3675
- {txt = " extension.local" | " ocaml.local" | " local" }, PStr [] ) },
3676
- [Nolabel , _]) ->
3677
- true , e.pexp_loc
3678
- | Pexp_apply
3679
- ({ pexp_desc = Pexp_extension (
3680
- {txt = " extension.unique" | " ocaml.unique" | " unique" }, PStr [] ) },
3681
- [Nolabel , exp]) ->
3682
- loop exp
3683
- | Pexp_apply
3684
- ({ pexp_desc = Pexp_extension (
3685
- {txt = " extension.once" | " ocaml.once" | " once" }, PStr [] ) },
3686
- [Nolabel , exp]) ->
3687
- loop exp
3688
- | Pexp_ident _ | Pexp_constant _ | Pexp_apply _ | Pexp_tuple _
3689
- | Pexp_construct _ | Pexp_variant _ | Pexp_record _ | Pexp_field _
3690
- | Pexp_setfield _ | Pexp_array _ | Pexp_while _ | Pexp_for _ | Pexp_send _
3691
- | Pexp_new _ | Pexp_setinstvar _ | Pexp_override _ | Pexp_assert _
3692
- | Pexp_lazy _ | Pexp_object _ | Pexp_pack _ | Pexp_function _ | Pexp_fun _
3693
- | Pexp_letop _ | Pexp_extension _ | Pexp_unreachable ->
3694
- false , e.pexp_loc
3695
- | Pexp_let (_, _, e) | Pexp_sequence (_, e) | Pexp_constraint (e, _)
3696
- | Pexp_coerce (e, _, _) | Pexp_letmodule (_, _, e) | Pexp_letexception (_, e)
3697
- | Pexp_poly (e, _) | Pexp_newtype (_, e) | Pexp_open (_, e)
3698
- | Pexp_ifthenelse (_ , e , None)->
3699
- loop e
3700
- | Pexp_ifthenelse (_ , e1 , Some e2 )-> combine (loop e1) (loop e2)
3701
- | Pexp_match (_ , cases ) -> begin
3702
- match cases with
3703
- | [] -> false , e.pexp_loc
3704
- | first :: rest ->
3705
- List. fold_left
3706
- (fun acc pc -> combine acc (loop pc.pc_rhs))
3707
- (loop first.pc_rhs) rest
3650
+ module Is_local_returning : sig
3651
+ val function_ : Parsetree .case list -> bool
3652
+ end = struct
3653
+
3654
+ (* Is the return value annotated with "local_"?
3655
+ [assert false] can work either way *)
3656
+
3657
+ type local_returning_flag =
3658
+ | Local of Location .t (* location of a local return *)
3659
+ | Not of Location .t (* location of a non-local return *)
3660
+ | Either
3661
+ [@@ warning "-unused-constructor" ]
3662
+
3663
+ let combine flag1 flag2 =
3664
+ match flag1, flag2 with
3665
+ | (Local _ as flag), Local _
3666
+ | (Local _ as flag), Either
3667
+ | (Not _ as flag), Not _
3668
+ | (Not _ as flag), Either
3669
+ | Either , (Local _ as flag)
3670
+ | Either , (Not _ as flag)
3671
+ | (Either as flag ), Either ->
3672
+ flag
3673
+
3674
+ | Local local_loc, Not not_local_loc
3675
+ | Not not_local_loc , Local local_loc ->
3676
+ raise(Error (not_local_loc, Env. empty,
3677
+ Local_return_annotation_mismatch local_loc))
3678
+
3679
+ let expr e =
3680
+ let rec loop e =
3681
+ match Jane_syntax.Expression. of_ast e with
3682
+ | Some (jexp , _attrs ) -> begin
3683
+ match jexp with
3684
+ | Jexp_comprehension _ -> Not e.pexp_loc
3685
+ | Jexp_immutable_array _ -> Not e.pexp_loc
3686
+ | Jexp_layout (Lexp_constant _ ) -> Not e.pexp_loc
3687
+ | Jexp_layout (Lexp_newtype (_ , _ , e )) -> loop e
3688
+ | Jexp_n_ary_function _ -> Not e.pexp_loc
3689
+ end
3690
+ | None ->
3691
+ match e.pexp_desc with
3692
+ | Pexp_apply
3693
+ ({ pexp_desc = Pexp_extension (
3694
+ {txt = " extension.local" | " ocaml.local" | " local" }, PStr [] ) },
3695
+ [Nolabel , _]) ->
3696
+ Local e.pexp_loc
3697
+ | Pexp_apply
3698
+ ({ pexp_desc = Pexp_extension (
3699
+ {txt = " extension.unique" | " ocaml.unique" | " unique" }, PStr [] ) },
3700
+ [Nolabel , exp]) ->
3701
+ loop exp
3702
+ | Pexp_apply
3703
+ ({ pexp_desc = Pexp_extension (
3704
+ {txt = " extension.once" | " ocaml.once" | " once" }, PStr [] ) },
3705
+ [Nolabel , exp]) ->
3706
+ loop exp
3707
+ | Pexp_ident _ | Pexp_constant _ | Pexp_apply _ | Pexp_tuple _
3708
+ | Pexp_construct _ | Pexp_variant _ | Pexp_record _ | Pexp_field _
3709
+ | Pexp_setfield _ | Pexp_array _ | Pexp_while _ | Pexp_for _ | Pexp_send _
3710
+ | Pexp_new _ | Pexp_setinstvar _ | Pexp_override _ | Pexp_assert _
3711
+ | Pexp_lazy _ | Pexp_object _ | Pexp_pack _ | Pexp_function _ | Pexp_fun _
3712
+ | Pexp_letop _ | Pexp_extension _ | Pexp_unreachable ->
3713
+ Not e.pexp_loc
3714
+ | Pexp_let (_, _, e) | Pexp_sequence (_, e) | Pexp_constraint (e, _)
3715
+ | Pexp_coerce (e, _, _) | Pexp_letmodule (_, _, e) | Pexp_letexception (_, e)
3716
+ | Pexp_poly (e, _) | Pexp_newtype (_, e) | Pexp_open (_, e)
3717
+ | Pexp_ifthenelse (_ , e , None)->
3718
+ loop e
3719
+ | Pexp_ifthenelse (_ , e1 , Some e2 )-> combine (loop e1) (loop e2)
3720
+ | Pexp_match (_ , cases ) -> begin
3721
+ match cases with
3722
+ | [] -> Not e.pexp_loc
3723
+ | first :: rest ->
3724
+ List. fold_left
3725
+ (fun acc pc -> combine acc (loop pc.pc_rhs))
3726
+ (loop first.pc_rhs) rest
3727
+ end
3728
+ | Pexp_try (e , cases ) ->
3729
+ List. fold_left
3730
+ (fun acc pc -> combine acc (loop pc.pc_rhs))
3731
+ (loop e) cases
3732
+ in
3733
+ loop e
3734
+
3735
+ let function_ cases =
3736
+ let rec loop_cases cases =
3737
+ match cases with
3738
+ | [] -> Misc. fatal_error " empty cases in function_"
3739
+ | [{pc_lhs = _; pc_guard = None ; pc_rhs = e}] ->
3740
+ loop_body e
3741
+ | case :: cases ->
3742
+ let is_local_returning_case case =
3743
+ expr case.pc_rhs
3744
+ in
3745
+ List. fold_left
3746
+ (fun acc case -> combine acc (is_local_returning_case case))
3747
+ (is_local_returning_case case) cases
3748
+ and loop_body e =
3749
+ if Builtin_attributes. has_curry e.pexp_attributes then
3750
+ expr e
3751
+ else begin
3752
+ match Jane_syntax.Expression. of_ast e with
3753
+ | Some (jexp , _attrs ) -> begin
3754
+ match jexp with
3755
+ | Jexp_n_ary_function (_ , _ , Pfunction_cases (cases , _ , _ )) ->
3756
+ loop_cases cases
3757
+ | Jexp_n_ary_function (_ , _ , Pfunction_body body ) ->
3758
+ loop_body body
3759
+ | Jexp_comprehension _ | Jexp_immutable_array _ ->
3760
+ expr e
3761
+ | Jexp_layout (Lexp_constant _ | Lexp_newtype _ ) ->
3762
+ Not e.pexp_loc
3763
+ end
3764
+ | None -> match e.pexp_desc, e.pexp_attributes with
3765
+ | Pexp_fun (_ , _ , _ , e ), _ -> loop_body e
3766
+ | Pexp_function cases , _ -> loop_cases cases
3767
+ | Pexp_constraint (e , _ ), _ -> loop_body e
3768
+ | Pexp_let (Nonrecursive , _, e),
3769
+ [{Parsetree. attr_name = {txt= " #default" };_}] -> loop_body e
3770
+ | _ -> expr e
3708
3771
end
3709
- | Pexp_try ( e , cases ) ->
3710
- List. fold_left
3711
- ( fun acc pc -> combine acc (loop pc.pc_rhs))
3712
- (loop e) cases
3713
- in
3714
- let local, _ = loop e in
3715
- local
3772
+ in
3773
+ match loop_cases cases with
3774
+ | Local _ -> true
3775
+ | Either | Not _ -> false
3776
+ (* [fun _ -> assert false] must not be local-returning for
3777
+ backward compatibility *)
3778
+ end
3716
3779
3717
3780
let rec is_an_uncurried_function e =
3718
3781
if Builtin_attributes. has_curry e.pexp_attributes then false
@@ -3729,40 +3792,6 @@ let rec is_an_uncurried_function e =
3729
3792
| _ -> false
3730
3793
end
3731
3794
3732
- let is_local_returning_function cases =
3733
- let rec loop_cases cases =
3734
- match cases with
3735
- | [] -> false
3736
- | [{pc_lhs = _; pc_guard = None ; pc_rhs = e}] ->
3737
- loop_body e
3738
- | cases ->
3739
- List. for_all (fun case -> is_local_returning_expr case.pc_rhs) cases
3740
- and loop_body e =
3741
- if Builtin_attributes. has_curry e.pexp_attributes then
3742
- is_local_returning_expr e
3743
- else begin
3744
- match Jane_syntax.Expression. of_ast e with
3745
- | Some (jexp , _attrs ) -> begin
3746
- match jexp with
3747
- | Jexp_n_ary_function (_ , _ , Pfunction_cases (cases , _ , _ )) ->
3748
- loop_cases cases
3749
- | Jexp_n_ary_function (_ , _ , Pfunction_body body ) ->
3750
- loop_body body
3751
- | Jexp_comprehension _ | Jexp_immutable_array _ ->
3752
- is_local_returning_expr e
3753
- | Jexp_layout (Lexp_constant _ | Lexp_newtype _ ) -> false
3754
- end
3755
- | None -> match e.pexp_desc, e.pexp_attributes with
3756
- | Pexp_fun (_ , _ , _ , e ), _ -> loop_body e
3757
- | Pexp_function cases , _ -> loop_cases cases
3758
- | Pexp_constraint (e , _ ), _ -> loop_body e
3759
- | Pexp_let (Nonrecursive , _, e),
3760
- [{Parsetree. attr_name = {txt= " #default" };_}] -> loop_body e
3761
- | _ -> is_local_returning_expr e
3762
- end
3763
- in
3764
- loop_cases cases
3765
-
3766
3795
(* The "rest of the function" extends from the start of the first parameter
3767
3796
to the end of the overall function. The parser does not construct such
3768
3797
a location so we forge one for type errors.
@@ -6154,7 +6183,7 @@ and type_function
6154
6183
match in_function with
6155
6184
| Some (_ , _ , region_locked ) -> env, region_locked
6156
6185
| None ->
6157
- let region_locked = not (is_local_returning_function caselist) in
6186
+ let region_locked = not (Is_local_returning. function_ caselist) in
6158
6187
let env =
6159
6188
Env. add_closure_lock
6160
6189
?closure_context:expected_mode.closure_context
0 commit comments