@@ -611,44 +611,65 @@ let enter_orpat_variables loc env p1_vs p2_vs =
611
611
raise (Error (loc, env, err)) in
612
612
unify_vars p1_vs p2_vs
613
613
614
- let rec build_as_type env p =
615
- let as_ty = build_as_type_aux env p in
616
- (* Cf. #1655 *)
617
- List. fold_left (fun as_ty (extra , _loc , _attrs ) ->
618
- match extra with
619
- | Tpat_type _ | Tpat_open _ | Tpat_unpack -> as_ty
620
- | Tpat_constraint cty ->
621
- begin_def () ;
622
- let ty = instance cty.ctyp_type in
623
- end_def () ;
624
- generalize_structure ty;
625
- (* This call to unify can't fail since the pattern is well typed. *)
626
- unify ! env (instance as_ty) (instance ty);
627
- ty
628
- ) as_ty p.pat_extra
614
+ let rec build_as_type_and_mode env p =
615
+ let as_ty, as_mode = build_as_type_aux env p in
616
+ let as_ty =
617
+ (* Cf. #1655 *)
618
+ List. fold_left (fun as_ty (extra , _loc , _attrs ) ->
619
+ match extra with
620
+ | Tpat_type _ | Tpat_open _ | Tpat_unpack -> as_ty
621
+ | Tpat_constraint cty ->
622
+ begin_def () ;
623
+ let ty = instance cty.ctyp_type in
624
+ end_def () ;
625
+ generalize_structure ty;
626
+ (* This call to unify can't fail since the pattern is well typed. *)
627
+ unify ! env (instance as_ty) (instance ty);
628
+ ty
629
+ ) as_ty p.pat_extra
630
+ in
631
+ as_ty, as_mode
632
+
633
+ and build_as_type env p =
634
+ fst (build_as_type_and_mode env p)
629
635
630
636
and build_as_type_aux env p =
631
637
match p.pat_desc with
632
- Tpat_alias (p1,_, _) -> build_as_type env p1
638
+ Tpat_alias (p1,_, _) -> build_as_type_and_mode env p1
633
639
| Tpat_tuple pl ->
634
640
let tyl = List. map (build_as_type env) pl in
635
- newty (Ttuple tyl)
641
+ newty (Ttuple tyl), p.pat_mode
636
642
| Tpat_construct (_ , cstr , pl ) ->
637
- let keep = cstr.cstr_private = Private || cstr.cstr_existentials <> [] in
638
- if keep then p.pat_type else
639
- let tyl = List. map (build_as_type env) pl in
640
- let ty_args, ty_res = instance_constructor cstr in
641
- List. iter2 (fun (p ,ty ) -> unify_pat env {p with pat_type = ty})
642
- (List. combine pl tyl) ty_args;
643
- ty_res
643
+ let priv = (cstr.cstr_private = Private ) in
644
+ let mode =
645
+ if priv || pl <> [] then p.pat_mode
646
+ else Value_mode. newvar ()
647
+ in
648
+ let keep = priv || cstr.cstr_existentials <> [] in
649
+ let ty =
650
+ if keep then p.pat_type else
651
+ let tyl = List. map (build_as_type env) pl in
652
+ let ty_args, ty_res = instance_constructor cstr in
653
+ List. iter2 (fun (p ,ty ) -> unify_pat env {p with pat_type = ty})
654
+ (List. combine pl tyl) ty_args;
655
+ ty_res
656
+ in
657
+ ty, mode
644
658
| Tpat_variant (l , p' , _ ) ->
645
659
let ty = Option. map (build_as_type env) p' in
646
- newty (Tvariant {row_fields= [l, Rpresent ty]; row_more= newvar() ;
647
- row_bound= () ; row_name= None ;
648
- row_fixed= None ; row_closed= false })
660
+ let mode =
661
+ if p' = None then Value_mode. newvar ()
662
+ else p.pat_mode
663
+ in
664
+ let ty =
665
+ newty (Tvariant {row_fields= [l, Rpresent ty]; row_more= newvar() ;
666
+ row_bound= () ; row_name= None ;
667
+ row_fixed= None ; row_closed= false })
668
+ in
669
+ ty, mode
649
670
| Tpat_record (lpl ,_ ) ->
650
671
let lbl = snd3 (List. hd lpl) in
651
- if lbl.lbl_private = Private then p.pat_type else
672
+ if lbl.lbl_private = Private then p.pat_type, p.pat_mode else
652
673
let ty = newvar () in
653
674
let ppl = List. map (fun (_ , l , p ) -> l.lbl_pos, p) lpl in
654
675
let do_label lbl =
@@ -666,19 +687,40 @@ and build_as_type_aux env p =
666
687
unify_pat env p ty_res'
667
688
end in
668
689
Array. iter do_label lbl.lbl_all;
669
- ty
690
+ ty, p.pat_mode
670
691
| Tpat_or (p1 , p2 , row ) ->
671
692
begin match row with
672
693
None ->
673
- let ty1 = build_as_type env p1 and ty2 = build_as_type env p2 in
694
+ let ty1, mode1 = build_as_type_and_mode env p1 in
695
+ let ty2, mode2 = build_as_type_and_mode env p2 in
674
696
unify_pat env {p2 with pat_type = ty2} ty1;
675
- ty1
697
+ ty1, Value_mode. join [mode1; mode2]
676
698
| Some row ->
677
699
let row = row_repr row in
678
- newty (Tvariant {row with row_closed= false ; row_more= newvar() })
700
+ let all_constant =
701
+ List. for_all
702
+ (function
703
+ | _ , (Rpresent (Some _ ) | Reither (false , _ , _ , _ )) -> false
704
+ | _ -> true )
705
+ row.row_fields
706
+ in
707
+ let mode =
708
+ if all_constant then Value_mode. newvar ()
709
+ else p.pat_mode
710
+ in
711
+ let ty =
712
+ newty (Tvariant {row with row_closed= false ; row_more= newvar() })
713
+ in
714
+ ty, mode
679
715
end
680
- | Tpat_any | Tpat_var _ | Tpat_constant _
681
- | Tpat_array _ | Tpat_lazy _ -> p.pat_type
716
+ | Tpat_constant _ ->
717
+ let mode =
718
+ if Ctype. maybe_pointer_type ! env p.pat_type then p.pat_mode
719
+ else Value_mode. newvar ()
720
+ in
721
+ p.pat_type, mode
722
+ | Tpat_any | Tpat_var _
723
+ | Tpat_array _ | Tpat_lazy _ -> p.pat_type, p.pat_mode
682
724
683
725
let build_or_pat env loc mode lid =
684
726
let path, decl = Env. lookup_type ~loc: lid.loc lid.txt env in
@@ -1623,11 +1665,11 @@ and type_pat_aux
1623
1665
assert construction_not_used_in_counterexamples;
1624
1666
type_pat Value sq expected_ty (fun q ->
1625
1667
begin_def () ;
1626
- let ty_var = build_as_type env q in
1668
+ let ty_var, mode = build_as_type_and_mode env q in
1627
1669
end_def () ;
1628
1670
generalize ty_var;
1629
1671
let id =
1630
- enter_variable ~is_as_variable: true loc name alloc_mode. mode
1672
+ enter_variable ~is_as_variable: true loc name mode
1631
1673
ty_var sp.ppat_attributes
1632
1674
in
1633
1675
rvp k {
0 commit comments