Skip to content

Commit

Permalink
safeguard against infinite recursion monos
Browse files Browse the repository at this point in the history
  • Loading branch information
Simn committed Feb 1, 2024
1 parent 1939a7b commit 7f6d274
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions src/core/tUnification.ml
Original file line number Diff line number Diff line change
Expand Up @@ -235,25 +235,37 @@ module Monomorph = struct
and close m = match m.tm_type with
| Some _ ->
()
| None -> match classify_down_constraints m with
| None ->
let recursion_ok t =
let rec loop t = match t with
| TMono m2 when m == m2 ->
raise Exit
| _ ->
TFunctions.iter loop t
in
try
loop t;
true
with Exit ->
false
in
(* TODO: we never do anything with monos, I think *)
let monos,constraints = classify_down_constraints' m in
match constraints with
| CUnknown ->
()
| CTypes [(t,_)] ->
do_bind m t;
()
(* TODO: silently not binding doesn't seem correct, but it's likely better than infinite recursion *)
if recursion_ok t then do_bind m t;
| CTypes _ | CMixed _ ->
()
| CStructural(fields,_) ->
let check_recursion cf =
let rec loop t = match t with
| TMono m2 when m == m2 ->
if not (recursion_ok cf.cf_type) then begin
let pctx = print_context() in
let s = Printf.sprintf "%s appears in { %s: %s }" (s_type pctx t) cf.cf_name (s_type pctx cf.cf_type) in
let s = Printf.sprintf "%s appears in { %s: %s }" (s_type pctx (TMono m)) cf.cf_name (s_type pctx cf.cf_type) in
raise (Unify_error [Unify_custom "Recursive type";Unify_custom s]);
| _ ->
TFunctions.map loop t
in
ignore(loop cf.cf_type);
end
in
(* We found a bunch of fields but no type, create a merged structure type and bind to that *)
PMap.iter (fun _ cf -> check_recursion cf) fields;
Expand Down

0 comments on commit 7f6d274

Please sign in to comment.