Skip to content

Commit 82bf1f0

Browse files
flambda-backend: Fix check_and_update_generalized_ty_jkind (#2615)
* Add `Warning` to jkind history * Reword `check_and_update_generalized_ty_jkind` * Remove duplicate warnings * Give up on soundness * Reimplement `has_warned` --------- Co-authored-by: Diana Kalinichenko <[email protected]>
1 parent 99c556a commit 82bf1f0

File tree

6 files changed

+55
-80
lines changed

6 files changed

+55
-80
lines changed

testsuite/tests/typing-layouts/erasable_annot.ml

Lines changed: 9 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ can't be erased for compatibility with upstream OCaml.
6767
module type S = sig type _ g = MkG : ('a : immediate). 'a g end
6868
|}];;
6969

70-
(* CR layouts: only show the warning once; same for tests below *)
7170
let f (type a : immediate): a -> a = fun x -> x
7271
[%%expect {|
7372
Line 1, characters 4-5:
@@ -76,12 +75,6 @@ Line 1, characters 4-5:
7675
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
7776
can't be erased for compatibility with upstream OCaml.
7877

79-
Line 1, characters 6-47:
80-
1 | let f (type a : immediate): a -> a = fun x -> x
81-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
82-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
83-
can't be erased for compatibility with upstream OCaml.
84-
8578
val f : ('a : immediate). 'a -> 'a = <fun>
8679
|}];;
8780

@@ -93,12 +86,6 @@ Line 1, characters 4-5:
9386
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
9487
can't be erased for compatibility with upstream OCaml.
9588

96-
Line 1, characters 6-31:
97-
1 | let f x = (x : (_ : immediate))
98-
^^^^^^^^^^^^^^^^^^^^^^^^^
99-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
100-
can't be erased for compatibility with upstream OCaml.
101-
10289
val f : ('a : immediate). 'a -> 'a = <fun>
10390
|}];;
10491

@@ -110,12 +97,6 @@ Line 1, characters 4-5:
11097
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
11198
can't be erased for compatibility with upstream OCaml.
11299

113-
Line 1, characters 6-63:
114-
1 | let f v: ((_ : immediate)[@error_message "Custom message"]) = v
115-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
116-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
117-
can't be erased for compatibility with upstream OCaml.
118-
119100
val f : ('a : immediate). 'a -> 'a = <fun>
120101
|}];;
121102

@@ -182,12 +163,6 @@ Line 1, characters 4-5:
182163
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
183164
can't be erased for compatibility with upstream OCaml.
184165

185-
Line 1, characters 6-49:
186-
1 | let f (type a : immediate64): a -> a = fun x -> x
187-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
188-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
189-
can't be erased for compatibility with upstream OCaml.
190-
191166
val f : ('a : immediate64). 'a -> 'a = <fun>
192167
|}];;
193168

@@ -199,12 +174,6 @@ Line 1, characters 4-5:
199174
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
200175
can't be erased for compatibility with upstream OCaml.
201176

202-
Line 1, characters 6-33:
203-
1 | let f x = (x : (_ : immediate64))
204-
^^^^^^^^^^^^^^^^^^^^^^^^^^^
205-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
206-
can't be erased for compatibility with upstream OCaml.
207-
208177
val f : ('a : immediate64). 'a -> 'a = <fun>
209178
|}];;
210179

@@ -216,12 +185,6 @@ Line 1, characters 4-5:
216185
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
217186
can't be erased for compatibility with upstream OCaml.
218187

219-
Line 1, characters 6-65:
220-
1 | let f v: ((_ : immediate64)[@error_message "Custom message"]) = v
221-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
222-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
223-
can't be erased for compatibility with upstream OCaml.
224-
225188
val f : ('a : immediate64). 'a -> 'a = <fun>
226189
|}];;
227190

@@ -289,15 +252,13 @@ Line 5, characters 4-5:
289252
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
290253
can't be erased for compatibility with upstream OCaml.
291254

292-
Line 5, characters 6-50:
293-
5 | let f (module _ : S with type t = 'a) (x : 'a) = x
294-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
295-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in f
296-
can't be erased for compatibility with upstream OCaml.
297-
298255
val f : ('a : immediate). (module S with type t = 'a) -> 'a -> 'a = <fun>
299256
|}]
300257

258+
(* CR layouts: this example should raise a warning, but it does not.
259+
It's quite complicated, and missing it only means that this error
260+
will be caught by the upstream compiler later. We have decided that
261+
fixing this is not worth the effort. *)
301262
module type S = sig
302263
type t [@@immediate]
303264
end
@@ -312,7 +273,10 @@ module type S = sig type t : immediate end
312273
val x : int = 15
313274
|}]
314275

315-
(* CR layouts: this should raise a warning *)
276+
(* CR layouts: this example should raise a warning, but it does not.
277+
It's quite complicated, and missing it only means that this error
278+
will be caught by the upstream compiler later. We have decided that
279+
fixing this is not worth the effort. *)
316280
let y =
317281
ignore (fun (type a : immediate) (x : a) ->
318282
let module _ : S = struct
@@ -580,12 +544,6 @@ Line 1, characters 21-26:
580544
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in fails
581545
can't be erased for compatibility with upstream OCaml.
582546

583-
Line 1, characters 27-68:
584-
1 | let[@warning "-187"] fails (type a : immediate): a -> a = fun x -> x
585-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
586-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in fails
587-
can't be erased for compatibility with upstream OCaml.
588-
589547
val fails : ('a : immediate). 'a -> 'a = <fun>
590548
|}]
591549

@@ -603,9 +561,7 @@ can't be erased for compatibility with upstream OCaml.
603561
module type S1 = sig type ('a : immediate) fails = int end
604562
|}]
605563

606-
(* Disabling the warning just in the signature isn't sufficient.
607-
608-
The check here is also ran twice for some reason. *)
564+
(* Disabling the warning just in the signature isn't sufficient. *)
609565
module M6 : sig
610566
[@@@warning "-187"]
611567
type ('a : immediate) t = 'a * 'a
@@ -619,12 +575,6 @@ Line 5, characters 2-35:
619575
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in t
620576
can't be erased for compatibility with upstream OCaml.
621577

622-
Line 5, characters 2-35:
623-
5 | type ('a : immediate) t = 'a * 'a
624-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
625-
Warning 187 [incompatible-with-upstream]: Usage of layout immediate/immediate64 in t
626-
can't be erased for compatibility with upstream OCaml.
627-
628578
module M6 : sig type ('a : immediate) t = 'a * 'a end
629579
|}]
630580

typing/ctype.ml

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2314,32 +2314,34 @@ let check_and_update_generalized_ty_jkind ?name ~loc ty =
23142314
| _ -> false)
23152315
in
23162316
if Language_extension.erasable_extensions_only ()
2317-
&& is_immediate jkind
2317+
&& is_immediate jkind && not (Jkind.has_warned jkind)
23182318
then
23192319
let id =
23202320
match name with
23212321
| Some id -> Ident.name id
23222322
| None -> "<unknown>"
23232323
in
23242324
Location.prerr_warning loc (Warnings.Incompatible_with_upstream
2325-
(Warnings.Immediate_erasure id))
2326-
else ()
2325+
(Warnings.Immediate_erasure id));
2326+
Jkind.with_warning jkind
2327+
else jkind
2328+
in
2329+
let generalization_check level jkind =
2330+
if level = generic_level then
2331+
Jkind.(update_reason jkind (Generalized (name, loc)))
2332+
else jkind
23272333
in
23282334
let rec inner ty =
23292335
let level = get_level ty in
2330-
if level = generic_level && try_mark_node ty then begin
2336+
if try_mark_node ty then begin
23312337
begin match get_desc ty with
23322338
| Tvar ({ jkind; _ } as r) ->
2333-
immediacy_check jkind;
2334-
let new_jkind =
2335-
Jkind.(update_reason jkind (Generalized (name, loc)))
2336-
in
2339+
let new_jkind = immediacy_check jkind in
2340+
let new_jkind = generalization_check level new_jkind in
23372341
set_type_desc ty (Tvar {r with jkind = new_jkind})
23382342
| Tunivar ({ jkind; _ } as r) ->
2339-
immediacy_check jkind;
2340-
let new_jkind =
2341-
Jkind.(update_reason jkind (Generalized (name, loc)))
2342-
in
2343+
let new_jkind = immediacy_check jkind in
2344+
let new_jkind = generalization_check level new_jkind in
23432345
set_type_desc ty (Tunivar {r with jkind = new_jkind})
23442346
| _ -> ()
23452347
end;

typing/jkind.ml

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -526,17 +526,22 @@ include Jkind_intf.History
526526

527527
type t = type_expr Jkind_types.t
528528

529-
let fresh_jkind jkind ~why = { jkind; history = Creation why }
529+
let fresh_jkind jkind ~why =
530+
{ jkind; history = Creation why; has_warned = false }
530531

531532
(******************************)
532533
(* constants *)
533534

534535
let any_dummy_jkind =
535-
{ jkind = Jkind_desc.max; history = Creation (Any_creation Dummy_jkind) }
536+
{ jkind = Jkind_desc.max;
537+
history = Creation (Any_creation Dummy_jkind);
538+
has_warned = false
539+
}
536540

537541
let value_v1_safety_check =
538542
{ jkind = Jkind_desc.value;
539-
history = Creation (Value_creation V1_safety_check)
543+
history = Creation (Value_creation V1_safety_check);
544+
has_warned = false
540545
}
541546

542547
(* CR layouts: Should we be doing more memoization here? *)
@@ -761,6 +766,10 @@ let has_imported_history t =
761766

762767
let update_reason t reason = { t with history = Creation reason }
763768

769+
let with_warning t = { t with has_warned = true }
770+
771+
let has_warned t = t.has_warned
772+
764773
let printtyp_path = ref (fun _ _ -> assert false)
765774

766775
let set_printtyp_path f = printtyp_path := f
@@ -1225,8 +1234,9 @@ end
12251234
(******************************)
12261235
(* relations *)
12271236

1228-
let equate_or_equal ~allow_mutation { jkind = jkind1; history = _ }
1229-
{ jkind = jkind2; history = _ } =
1237+
let equate_or_equal ~allow_mutation
1238+
{ jkind = jkind1; history = _; has_warned = _ }
1239+
{ jkind = jkind2; history = _; has_warned = _ } =
12301240
Jkind_desc.equate_or_equal ~allow_mutation jkind1 jkind2
12311241

12321242
(* CR layouts v2.8: Switch this back to ~allow_mutation:false *)
@@ -1272,7 +1282,12 @@ let combine_histories reason lhs rhs =
12721282
let intersection ~reason t1 t2 =
12731283
match Jkind_desc.intersection t1.jkind t2.jkind with
12741284
| None -> Error (Violation.of_ (No_intersection (t1, t2)))
1275-
| Some jkind -> Ok { jkind; history = combine_histories reason t1 t2 }
1285+
| Some jkind ->
1286+
Ok
1287+
{ jkind;
1288+
history = combine_histories reason t1 t2;
1289+
has_warned = t1.has_warned || t2.has_warned
1290+
}
12761291

12771292
(* this is hammered on; it must be fast! *)
12781293
let check_sub sub super = Jkind_desc.sub sub.jkind super.jkind
@@ -1470,7 +1485,7 @@ module Debug_printers = struct
14701485
lhs_history Jkind_desc.Debug_printers.t rhs_jkind history rhs_history
14711486
| Creation c -> fprintf ppf "Creation (%a)" creation_reason c
14721487

1473-
let t ppf ({ jkind; history = h } : t) : unit =
1488+
let t ppf ({ jkind; history = h; has_warned = _ } : t) : unit =
14741489
fprintf ppf "@[<v 2>{ jkind = %a@,; history = %a }@]"
14751490
Jkind_desc.Debug_printers.t jkind history h
14761491
end

typing/jkind.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,12 @@ val has_imported_history : t -> bool
304304

305305
val update_reason : t -> creation_reason -> t
306306

307+
(* Mark the jkind as having produced a compiler warning. *)
308+
val with_warning : t -> t
309+
310+
(* Whether this jkind has produced a compiler warning. *)
311+
val has_warned : t -> bool
312+
307313
(******************************)
308314
(* relations *)
309315

typing/jkind_types.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,8 @@ type 'type_expr history =
350350

351351
type 'type_expr t =
352352
{ jkind : 'type_expr Jkind_desc.t;
353-
history : 'type_expr history
353+
history : 'type_expr history;
354+
has_warned : bool
354355
}
355356

356357
type const =

typing/jkind_types.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ type 'type_expr history =
129129

130130
type 'type_expr t =
131131
{ jkind : 'type_expr Jkind_desc.t;
132-
history : 'type_expr history
132+
history : 'type_expr history;
133+
has_warned : bool
133134
}
134135

135136
type annotation = const * Jane_syntax.Jkind.annotation

0 commit comments

Comments
 (0)