Skip to content

fixed Not_found exception raised in certain coercion cases #6574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# 11.0.1 (Unreleased)

#### :bug: Bug Fix

- Fixed issue with coercions sometimes raising a `Not_found` instead of giving a proper error message. https://github.com/rescript-lang/rescript-compiler/pull/6574
- Fix issue with recursive modules and uncurried. https://github.com/rescript-lang/rescript-compiler/pull/6575

# 11.0.0
Expand Down
13 changes: 9 additions & 4 deletions jscomp/ml/ctype.ml
Original file line number Diff line number Diff line change
Expand Up @@ -3904,6 +3904,11 @@ let subtypes = TypePairs.create 17
let subtype_error env trace =
raise (Subtype (expand_trace env (List.rev trace), []))

let extract_concrete_typedecl_opt env t =
match extract_concrete_typedecl env t with
| v -> Some v
| exception Not_found -> None

let rec subtype_rec env trace t1 t2 cstrs =
let t1 = repr t1 in
let t2 = repr t2 in
Expand Down Expand Up @@ -3960,23 +3965,23 @@ let rec subtype_rec env trace t1 t2 cstrs =
| (Tconstr(p1, [], _), Tconstr(p2, [], _)) when Path.same p1 Predef.path_int && Path.same p2 Predef.path_float ->
cstrs
| (Tconstr(path, [], _), Tconstr(_, [], _)) when Variant_coercion.can_coerce_primitive path &&
extract_concrete_typedecl env t2 |> Variant_coercion.can_try_coerce_variant_to_primitive |> Option.is_some
extract_concrete_typedecl_opt env t2 |> Variant_coercion.can_try_coerce_variant_to_primitive_opt |> Option.is_some
->
(* type coercion for primitives (int/float/string) to elgible unboxed variants:
- must be unboxed
- must have a constructor case with a supported and matching primitive payload *)
(match Variant_coercion.can_try_coerce_variant_to_primitive (extract_concrete_typedecl env t2) with
(match Variant_coercion.can_try_coerce_variant_to_primitive_opt (extract_concrete_typedecl_opt env t2) with
| Some (constructors, true) ->
if Variant_coercion.variant_has_catch_all_case constructors (fun p -> Path.same p path) then
cstrs
else
(trace, t1, t2, !univar_pairs)::cstrs
| _ -> (trace, t1, t2, !univar_pairs)::cstrs)
| (Tconstr(_, [], _), Tconstr(path, [], _)) when Variant_coercion.can_coerce_primitive path &&
extract_concrete_typedecl env t1 |> Variant_coercion.can_try_coerce_variant_to_primitive |> Option.is_some
extract_concrete_typedecl_opt env t1 |> Variant_coercion.can_try_coerce_variant_to_primitive_opt |> Option.is_some
->
(* type coercion for variants to primitives *)
(match Variant_coercion.can_try_coerce_variant_to_primitive (extract_concrete_typedecl env t1) with
(match Variant_coercion.can_try_coerce_variant_to_primitive_opt (extract_concrete_typedecl_opt env t1) with
| Some (constructors, unboxed) ->
if constructors |> Variant_coercion.variant_has_same_runtime_representation_as_target ~targetPath:path ~unboxed then
cstrs
Expand Down
5 changes: 5 additions & 0 deletions jscomp/ml/variant_coercion.ml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ let can_try_coerce_variant_to_primitive
Some (constructors, type_attributes |> Ast_untagged_variants.has_untagged)
| _ -> None

let can_try_coerce_variant_to_primitive_opt p =
match p with
| None -> None
| Some p -> can_try_coerce_variant_to_primitive p

let variant_representation_matches (c1_attrs : Parsetree.attributes)
(c2_attrs : Parsetree.attributes) =
match
Expand Down