Skip to content

Commit e8133a1

Browse files
committed
Fix external-external signature inclusion
Signature inclusion between two external declarations needs to be aware of polymorphic modes when comparing the underlying primitives.
1 parent 9840051 commit e8133a1

File tree

4 files changed

+41
-11
lines changed

4 files changed

+41
-11
lines changed

testsuite/tests/typing-local/local.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,11 +1630,20 @@ Error: This value escapes its region
16301630

16311631
(* Poly-moded eta expansion *)
16321632
module Heap32 : sig val add : int32 -> int32 -> int32 end = Int32
1633+
module Heap32E : sig external add : int32 -> int32 -> int32 = "%int32_add" end = Int32
16331634
module Local32 : sig val add : local_ int32 -> local_ int32 -> local_ int32 end = Int32
1635+
module Local32E : sig external add : local_ int32 -> local_ int32 -> local_ int32 = "%int32_add" end = Int32
16341636
[%%expect{|
16351637
module Heap32 : sig val add : int32 -> int32 -> int32 end
1638+
module Heap32E :
1639+
sig external add : int32 -> int32 -> int32 = "%int32_add" end
16361640
module Local32 :
16371641
sig val add : local_ int32 -> local_ int32 -> local_ int32 end
1642+
module Local32E :
1643+
sig
1644+
external add : local_ int32 -> local_ int32 -> local_ int32
1645+
= "%int32_add"
1646+
end
16381647
|}]
16391648
module Bad32 : sig val add : local_ int32 -> local_ int32 -> int32 end =
16401649
struct let add = Int32.add end

typing/includecore.ml

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,27 @@ let value_descriptions ~loc env name
3636
match vd1.val_kind with
3737
| Val_prim p1 ->
3838
let ty1, mode1 = Ctype.instance_prim_mode p1 vd1.val_type in
39-
if Ctype.moregeneral env true ty1 vd2.val_type then begin
40-
match vd2.val_kind with
41-
Val_prim p2 ->
42-
if p1 = p2 then Tcoerce_none else raise Dont_match
43-
| _ ->
44-
let pc =
45-
{pc_desc = p1; pc_type = vd2.Types.val_type; pc_poly_mode = mode1;
46-
pc_env = env; pc_loc = vd1.Types.val_loc; } in
47-
Tcoerce_primitive pc
48-
end else
49-
raise Dont_match
39+
begin match vd2.val_kind with
40+
| Val_prim p2 ->
41+
let ty2, _mode2 = Ctype.instance_prim_mode p2 vd2.val_type in
42+
if not (Ctype.moregeneral env true ty1 ty2) then
43+
raise Dont_match;
44+
let mode1 : Primitive.mode =
45+
match Btype.Alloc_mode.check_const mode1 with
46+
| Some Global -> Prim_global
47+
| Some Local -> Prim_local
48+
| None -> Prim_poly
49+
in
50+
let p1 = Primitive.inst_mode mode1 p1 in
51+
if p1 = p2 then Tcoerce_none else raise Dont_match
52+
| _ ->
53+
if not (Ctype.moregeneral env true ty1 vd2.val_type) then
54+
raise Dont_match;
55+
let pc =
56+
{pc_desc = p1; pc_type = vd2.Types.val_type; pc_poly_mode = mode1;
57+
pc_env = env; pc_loc = vd1.Types.val_loc; } in
58+
Tcoerce_primitive pc
59+
end
5060
| _ ->
5161
if Ctype.moregeneral env true vd1.val_type vd2.val_type then begin
5262
match vd2.val_kind with

typing/primitive.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,15 @@ let native_name_is_external p =
275275
let nat_name = native_name p in
276276
nat_name <> "" && nat_name.[0] <> '%'
277277

278+
let inst_mode mode p =
279+
let inst_repr = function
280+
| Prim_poly, r -> mode, r
281+
| (Prim_global|Prim_local) as m, r -> m, r
282+
in
283+
{ p with
284+
prim_native_repr_args = List.map inst_repr p.prim_native_repr_args;
285+
prim_native_repr_res = inst_repr p.prim_native_repr_res }
286+
278287
let report_error ppf err =
279288
match err with
280289
| Old_style_float_with_native_repr_attribute ->

typing/primitive.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ val byte_name: description -> string
8888
compiler itself. *)
8989
val native_name_is_external : description -> bool
9090

91+
val inst_mode : mode -> description -> description
92+
9193
type error =
9294
| Old_style_float_with_native_repr_attribute
9395
| Old_style_noalloc_with_noalloc_attribute

0 commit comments

Comments
 (0)