diff --git a/CHANGELOG.md b/CHANGELOG.md index f118a83561..b49a845ba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/jscomp/ml/ctype.ml b/jscomp/ml/ctype.ml index d615cefb75..901a0db72c 100644 --- a/jscomp/ml/ctype.ml +++ b/jscomp/ml/ctype.ml @@ -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 @@ -3960,12 +3965,12 @@ 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 @@ -3973,10 +3978,10 @@ let rec subtype_rec env trace t1 t2 cstrs = (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 diff --git a/jscomp/ml/variant_coercion.ml b/jscomp/ml/variant_coercion.ml index 17494a2e96..a178b4b5bd 100644 --- a/jscomp/ml/variant_coercion.ml +++ b/jscomp/ml/variant_coercion.ml @@ -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