@@ -69,7 +69,26 @@ let () =
6969            l l')
7070    |  _  -> None )
7171
72- exception  Subtype  of (type_expr *  type_expr) list  *  (type_expr *  type_expr) list 
72+ type  subtype_context  =
73+   | Generic  of  {errorCode : string }
74+   | Primitive_coercion_target_variant_not_unboxed  of  {
75+       variant_name : Path .t ; 
76+       primitive : Path .t ; 
77+     }
78+   | Primitive_coercion_target_variant_no_catch_all  of  {
79+       variant_name : Path .t ; 
80+       primitive : Path .t ; 
81+     }
82+   | Variant_constructor_runtime_representation_mismatch  of  {
83+       variant_name : Path .t ; 
84+       issues : Variant_coercion .variant_runtime_representation_issue  list ; 
85+     }
86+ 
87+ exception 
88+   Subtype  of
89+     (type_expr *  type_expr) list 
90+     *  (type_expr *  type_expr) list 
91+     *  subtype_context option 
7392
7493exception  Cannot_expand 
7594
@@ -3544,8 +3563,8 @@ let enlarge_type env ty =
35443563
35453564let  subtypes =  TypePairs. create 17 
35463565
3547- let  subtype_error  env  trace  = 
3548-   raise (Subtype  (expand_trace env (List. rev trace), [] ))
3566+ let  subtype_error  ? ctx   env  trace  = 
3567+   raise (Subtype  (expand_trace env (List. rev trace), [] , ctx ))
35493568
35503569let  extract_concrete_typedecl_opt  env  t  = 
35513570  match  extract_concrete_typedecl env t with 
@@ -3563,7 +3582,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
35633582    with  Not_found  ->  (
35643583      TypePairs. add subtypes (t1, t2) () ;
35653584      match  (t1.desc, t2.desc) with 
3566-       |  Tvar  _ , _  |  _ , Tvar  _  -> (trace, t1, t2, ! univar_pairs) :: cstrs
3585+       |  Tvar  _ , _  |  _ , Tvar  _  -> (trace, t1, t2, ! univar_pairs,  None ) :: cstrs
35673586      |  Tarrow  (l1, t1, u1, _, _), Tarrow  (l2, t2, u2, _, _)
35683587        when  Asttypes.Noloc. same_arg_label l1 l2 ->
35693588        let  cstrs =  subtype_rec env ((t2, t1) :: trace) t2 t1 cstrs in 
@@ -3593,13 +3612,14 @@ let rec subtype_rec env trace t1 t2 cstrs =
35933612                    ( trace,
35943613                      newty2 t1.level (Ttuple  [t1]),
35953614                      newty2 t2.level (Ttuple  [t2]),
3596-                       ! univar_pairs )
3615+                       ! univar_pairs,
3616+                       None  )
35973617                    :: cstrs
35983618                else  subtype_rec env ((t1, t2) :: trace) t1 t2 cstrs
35993619              else  if  cn then  subtype_rec env ((t2, t1) :: trace) t2 t1 cstrs
36003620              else  cstrs)
36013621            cstrs decl.type_variance (List. combine tl1 tl2)
3602-         with  Not_found  ->  (trace, t1, t2, ! univar_pairs) :: cstrs)
3622+         with  Not_found  ->  (trace, t1, t2, ! univar_pairs,  None ) :: cstrs)
36033623      |  Tconstr  (p1 , _ , _ ), _  when  generic_private_abbrev env p1 ->
36043624        subtype_rec env trace (expand_abbrev_opt env t1) t2 cstrs
36053625      |  Tconstr  (p1, [] , _), Tconstr  (p2, [] , _)
@@ -3617,13 +3637,34 @@ let rec subtype_rec env trace t1 t2 cstrs =
36173637          Variant_coercion. can_try_coerce_variant_to_primitive_opt
36183638            (extract_concrete_typedecl_opt env t2)
36193639        with 
3620-         |  Some  (constructors , true ) ->
3640+         |  Some  (p , _ , false ) ->
3641+           (*  Not @unboxed *) 
3642+           ( trace,
3643+             t1,
3644+             t2,
3645+             ! univar_pairs,
3646+             Some 
3647+               (Primitive_coercion_target_variant_not_unboxed 
3648+                  {variant_name =  p; primitive =  path}) )
3649+           :: cstrs
3650+         |  Some  (p , constructors , true ) ->
36213651          if 
36223652            Variant_coercion. variant_has_catch_all_case constructors (fun  p  ->
36233653                Path. same p path)
36243654          then  cstrs
3625-           else  (trace, t1, t2, ! univar_pairs) :: cstrs
3626-         |  _  -> (trace, t1, t2, ! univar_pairs) :: cstrs)
3655+           else 
3656+             ( trace,
3657+               t1,
3658+               t2,
3659+               ! univar_pairs,
3660+               Some 
3661+                 (Primitive_coercion_target_variant_no_catch_all 
3662+                    {variant_name =  p; primitive =  path}) )
3663+             :: cstrs
3664+         |  None  ->
3665+           (*  Unclear when this case actually happens. *) 
3666+           (trace, t1, t2, ! univar_pairs, Some  (Generic  {errorCode =  " VCPMMVD"  }))
3667+           :: cstrs)
36273668      |  Tconstr  (_, [] , _), Tconstr  (path, [] , _)
36283669        when  Variant_coercion. can_coerce_primitive path
36293670             &&  extract_concrete_typedecl_opt env t1
@@ -3634,15 +3675,25 @@ let rec subtype_rec env trace t1 t2 cstrs =
36343675          Variant_coercion. can_try_coerce_variant_to_primitive_opt
36353676            (extract_concrete_typedecl_opt env t1)
36363677        with 
3637-         |  Some  (constructors , unboxed ) ->
3638-           if 
3678+         |  Some  (p ,  constructors , unboxed ) ->
3679+           let  runtime_representation_issues  = 
36393680            constructors
36403681            |>  Variant_coercion 
36413682               .variant_has_same_runtime_representation_as_target
36423683                 ~target_path: path ~unboxed 
3643-           then  cstrs
3644-           else  (trace, t1, t2, ! univar_pairs) :: cstrs
3645-         |  None  -> (trace, t1, t2, ! univar_pairs) :: cstrs)
3684+           in 
3685+           if  List. length runtime_representation_issues <>  0  then 
3686+             ( trace,
3687+               t1,
3688+               t2,
3689+               ! univar_pairs,
3690+               Some 
3691+                 (Variant_constructor_runtime_representation_mismatch 
3692+                    {issues =  runtime_representation_issues; variant_name =  p})
3693+             )
3694+             :: cstrs
3695+           else  cstrs
3696+         |  None  -> (trace, t1, t2, ! univar_pairs, None ) :: cstrs)
36463697      |  Tconstr  (_ , [] , _ ), Tconstr  (_ , [] , _ ) -> (
36473698        (*  type coercion for variants and records *) 
36483699        match 
@@ -3655,11 +3706,11 @@ let rec subtype_rec env trace t1 t2 cstrs =
36553706            Variant_coercion. variant_configuration_can_be_coerced t1attrs
36563707              t2attrs
36573708            =  false 
3658-           then  (trace, t1, t2, ! univar_pairs) :: cstrs
3709+           then  (trace, t1, t2, ! univar_pairs,  None ) :: cstrs
36593710          else 
36603711            let  c1_len =  List. length c1 in 
36613712            if  c1_len >  List. length c2 then 
3662-               (trace, t1, t2, ! univar_pairs) :: cstrs
3713+               (trace, t1, t2, ! univar_pairs,  None ) :: cstrs
36633714            else 
36643715              let  constructor_map =  Hashtbl. create c1_len in 
36653716              c2
@@ -3716,7 +3767,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
37163767                         else  false 
37173768                       |  _  -> false )
37183769              then  cstrs
3719-               else  (trace, t1, t2, ! univar_pairs) :: cstrs
3770+               else  (trace, t1, t2, ! univar_pairs,  None ) :: cstrs
37203771        |  ( (_, _, {type_kind =  Type_record  (fields1, repr1)}),
37213772            (_, _, {type_kind =  Type_record  (fields2, repr2)}) ) ->
37223773          let  same_repr = 
@@ -3732,21 +3783,21 @@ let rec subtype_rec env trace t1 t2 cstrs =
37323783            let  violation, tl1, tl2 = 
37333784              Record_coercion. check_record_fields fields1 fields2
37343785            in 
3735-             if  violation then  (trace, t1, t2, ! univar_pairs) :: cstrs
3786+             if  violation then  (trace, t1, t2, ! univar_pairs,  None ) :: cstrs
37363787            else  subtype_list env trace tl1 tl2 cstrs
3737-           else  (trace, t1, t2, ! univar_pairs) :: cstrs
3738-         |  _  -> (trace, t1, t2, ! univar_pairs) :: cstrs
3739-         |  exception  Not_found  -> (trace, t1, t2, ! univar_pairs) :: cstrs)
3788+           else  (trace, t1, t2, ! univar_pairs,  None ) :: cstrs
3789+         |  _  -> (trace, t1, t2, ! univar_pairs,  None ) :: cstrs
3790+         |  exception  Not_found  -> (trace, t1, t2, ! univar_pairs,  None ) :: cstrs)
37403791      (*  | (_, Tconstr(p2, _, _)) when generic_private_abbrev false env p2 ->
37413792         subtype_rec env trace t1 (expand_abbrev_opt env t2) cstrs *)  
37423793      |  Tobject  (f1, _), Tobject  (f2, _)
37433794        when  is_Tvar (object_row f1) &&  is_Tvar (object_row f2) ->
37443795        (*  Same row variable implies same object. *) 
3745-         (trace, t1, t2, ! univar_pairs) :: cstrs
3796+         (trace, t1, t2, ! univar_pairs,  None ) :: cstrs
37463797      |  Tobject  (f1 , _ ), Tobject  (f2 , _ ) -> subtype_fields env trace f1 f2 cstrs
37473798      |  Tvariant  row1 , Tvariant  row2  -> (
37483799        try  subtype_row env trace row1 row2 cstrs
3749-         with  Exit  ->  (trace, t1, t2, ! univar_pairs) :: cstrs)
3800+         with  Exit  ->  (trace, t1, t2, ! univar_pairs,  None ) :: cstrs)
37503801      |  Tvariant  {row_closed =  true ; row_fields}, Tconstr  (_, [] , _)
37513802        when  extract_concrete_typedecl_opt env t2
37523803             |>  Variant_coercion. type_is_variant -> (
@@ -3758,8 +3809,8 @@ let rec subtype_rec env trace t1 t2 cstrs =
37583809              ~variant_constructors  ~type_attributes 
37593810          with 
37603811          |  Ok  _  -> cstrs
3761-           |  Error  _  -> (trace, t1, t2, ! univar_pairs) :: cstrs)
3762-         |  _  -> (trace, t1, t2, ! univar_pairs) :: cstrs)
3812+           |  Error  _  -> (trace, t1, t2, ! univar_pairs,  None ) :: cstrs)
3813+         |  _  -> (trace, t1, t2, ! univar_pairs,  None ) :: cstrs)
37633814      |  Tvariant  v , _  when  ! variant_is_subtype env (row_repr v) t2 -> cstrs
37643815      |  Tpoly  (u1 , [] ), Tpoly  (u2 , [] ) -> subtype_rec env trace u1 u2 cstrs
37653816      |  Tpoly  (u1 , tl1 ), Tpoly  (u2 , [] ) ->
@@ -3769,7 +3820,7 @@ let rec subtype_rec env trace t1 t2 cstrs =
37693820        try 
37703821          enter_poly env univar_pairs u1 tl1 u2 tl2 (fun  t1  t2  ->
37713822              subtype_rec env trace t1 t2 cstrs)
3772-         with  Unify  _  ->  (trace, t1, t2, ! univar_pairs) :: cstrs)
3823+         with  Unify  _  ->  (trace, t1, t2, ! univar_pairs,  None ) :: cstrs)
37733824      |  Tpackage  (p1 , nl1 , tl1 ), Tpackage  (p2 , nl2 , tl2 ) -> (
37743825        try 
37753826          let  ntl1 =  complete_type_list env nl2 t1.level (Mty_ident  p1) nl1 tl1
@@ -3779,24 +3830,25 @@ let rec subtype_rec env trace t1 t2 cstrs =
37793830          in 
37803831          let  cstrs' = 
37813832            List. map
3782-               (fun  (n2 , t2 ) -> (trace, List. assoc n2 ntl1, t2, ! univar_pairs))
3833+               (fun  (n2 , t2 ) ->
3834+                 (trace, List. assoc n2 ntl1, t2, ! univar_pairs, None ))
37833835              ntl2
37843836          in 
37853837          if  eq_package_path env p1 p2 then  cstrs' @  cstrs
37863838          else 
37873839            (*  need to check module subtyping *) 
37883840            let  snap =  Btype. snapshot ()  in 
37893841            try 
3790-               List. iter (fun  (_ , t1 , t2 , _ ) -> unify env t1 t2) cstrs';
3842+               List. iter (fun  (_ , t1 , t2 , _ ,  _ ) -> unify env t1 t2) cstrs';
37913843              if  ! package_subtype env p1 nl1 tl1 p2 nl2 tl2 then  (
37923844                Btype. backtrack snap;
37933845                cstrs' @  cstrs)
37943846              else  raise (Unify  [] )
37953847            with  Unify  _  -> 
37963848              Btype. backtrack snap;
37973849              raise Not_found 
3798-         with  Not_found  ->  (trace, t1, t2, ! univar_pairs) :: cstrs)
3799-       |  _ , _  -> (trace, t1, t2, ! univar_pairs) :: cstrs)
3850+         with  Not_found  ->  (trace, t1, t2, ! univar_pairs,  None ) :: cstrs)
3851+       |  _ , _  -> (trace, t1, t2, ! univar_pairs,  None ) :: cstrs)
38003852
38013853and  subtype_list  env  trace  tl1  tl2  cstrs  = 
38023854  if  List. length tl1 <>  List. length tl2 then  subtype_error env trace;
@@ -3814,7 +3866,11 @@ and subtype_fields env trace ty1 ty2 cstrs =
38143866    else  if  miss1 =  []  then 
38153867      subtype_rec env ((rest1, rest2) :: trace) rest1 rest2 cstrs
38163868    else 
3817-       (trace, build_fields (repr ty1).level miss1 rest1, rest2, ! univar_pairs)
3869+       ( trace,
3870+         build_fields (repr ty1).level miss1 rest1,
3871+         rest2,
3872+         ! univar_pairs,
3873+         None  )
38183874      :: cstrs
38193875  in 
38203876  let  cstrs = 
@@ -3823,7 +3879,8 @@ and subtype_fields env trace ty1 ty2 cstrs =
38233879      ( trace,
38243880        rest1,
38253881        build_fields (repr ty2).level miss2 (newvar () ),
3826-         ! univar_pairs )
3882+         ! univar_pairs,
3883+         None  )
38273884      :: cstrs
38283885  in 
38293886  List. fold_left
@@ -3880,12 +3937,14 @@ let subtype env ty1 ty2 =
38803937  |  ()  ->
38813938    List. iter
38823939      (function 
3883-         |  trace0 , t1 , t2 , pairs  -> (
3940+         |  trace0 , t1 , t2 , pairs ,  ctx  -> (
38843941          try  unify_pairs (ref  env) t1 t2 pairs
38853942          with  Unify  trace  -> 
38863943            raise
38873944              (Subtype 
3888-                  (expand_trace env (List. rev trace0), List. tl (List. tl trace)))))
3945+                  ( expand_trace env (List. rev trace0),
3946+                    List. tl (List. tl trace),
3947+                    ctx ))))
38893948      (List. rev cstrs)
38903949
38913950(* ******************) 
0 commit comments