Skip to content

Commit 4088367

Browse files
authored
Merge pull request #9609 from gasche/unboxed-abstract-with-manifest
separability and with-constraints: fix for bug #9607
2 parents 957f10b + ec74335 commit 4088367

4 files changed

Lines changed: 42 additions & 195 deletions

File tree

Changes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ OCaml 4.11
123123
For instance, "val f: #F(X).t -> unit" is now allowed.
124124
(Florian Angeletti, review by Gabriel Scherer, suggestion by Leo White)
125125

126-
- MPR#7364, GPR#2188: improvement of the unboxability check for types
126+
- #7364, #2188, #9609: improvement of the unboxability check for types
127127
with a single constructor. Mutually-recursive type declarations can
128128
now contain unboxed types. This is based on the paper
129129
https://arxiv.org/abs/1811.02300

testsuite/tests/typing-unboxed/test.ml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,3 +468,16 @@ external idub : iub -> iub = "%identity";;
468468
type iub = I of int [@@unboxed]
469469
external idub : iub -> iub = "%identity"
470470
|}];;
471+
472+
(* #9607: separability was not computed on with-constraints *)
473+
module type T = sig type 'k t end
474+
module M : T with type 'k t = string = struct
475+
type 'k t = string
476+
end
477+
type t = T : 'k M.t -> t [@@unboxed]
478+
479+
[%%expect{|
480+
module type T = sig type 'k t end
481+
module M : sig type 'k t = string end
482+
type t = T : 'k M.t -> t [@@unboxed]
483+
|}];;

testsuite/tests/typing-unboxed/test.ocaml.reference

Lines changed: 0 additions & 191 deletions
This file was deleted.

typing/typedecl.ml

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,15 +1440,40 @@ let transl_with_constraint env id row_path orig_decl sdecl =
14401440
| Some ty -> raise(Error(sdecl.ptype_loc, Unbound_type_var(ty,decl)))
14411441
end;
14421442
let decl = name_recursion sdecl id decl in
1443-
let type_variance =
1443+
let new_type_variance =
14441444
try Typedecl_variance.compute_decl
14451445
env ~check:true decl (Typedecl_variance.variance_of_sdecl sdecl)
14461446
with Typedecl_variance.Error (loc, err) ->
14471447
raise (Error (loc, Variance err)) in
1448-
let type_immediate =
1448+
let new_type_immediate =
14491449
(* Typedecl_immediacy.compute_decl never raises *)
14501450
Typedecl_immediacy.compute_decl env decl in
1451-
let decl = {decl with type_variance; type_immediate} in
1451+
let new_type_separability =
1452+
try Typedecl_separability.compute_decl env decl
1453+
with Typedecl_separability.Error (loc, err) ->
1454+
raise (Error (loc, Separability err)) in
1455+
let decl =
1456+
(* we intentionally write this without a fragile { decl with ... }
1457+
to ensure that people adding new fields to type declarations
1458+
consider whether they need to recompute it here; for an example
1459+
of bug caused by the previous approach, see #9607 *)
1460+
{
1461+
type_params = decl.type_params;
1462+
type_arity = decl.type_arity;
1463+
type_kind = decl.type_kind;
1464+
type_private = decl.type_private;
1465+
type_manifest = decl.type_manifest;
1466+
type_unboxed = decl.type_unboxed;
1467+
type_is_newtype = decl.type_is_newtype;
1468+
type_expansion_scope = decl.type_expansion_scope;
1469+
type_loc = decl.type_loc;
1470+
type_attributes = decl.type_attributes;
1471+
type_uid = decl.type_uid;
1472+
1473+
type_variance = new_type_variance;
1474+
type_immediate = new_type_immediate;
1475+
type_separability = new_type_separability;
1476+
} in
14521477
Ctype.end_def();
14531478
generalize_decl decl;
14541479
{

0 commit comments

Comments
 (0)