@@ -167,6 +167,7 @@ let can_coerce_polyvariant_to_variant ~row_fields ~constructors ~type_attributes
167167 Error `PolyvariantConstructorHasPayload
168168 else
169169 let is_unboxed = Ast_untagged_variants. has_untagged type_attributes in
170+ print_endline (string_of_bool is_unboxed);
170171 if
171172 List. for_all
172173 (fun polyvariant_value ->
@@ -179,15 +180,21 @@ let can_coerce_polyvariant_to_variant ~row_fields ~constructors ~type_attributes
179180 | Some (String as_runtime_string ) ->
180181 (* `@as("")`, does the configured string match the polyvariant value? *)
181182 as_runtime_string = polyvariant_value
182- | Some (Untagged StringType) when is_unboxed ->
183- (* An unboxed variant that has a catch all case will match _any_ string, so it matches anything here. *)
184- true
185183 | Some _ ->
186184 (* Any other `@as` can't match since it's by definition not a string *)
187185 false
188186 | None ->
189- (* No `@as` means the runtime representation will be the constructor name as a string. *)
190- polyvariant_value = constructor_name))
187+ (* No `@as` means the runtime representation will be the constructor
188+ name as a string.
189+
190+ However, there's a special case with unboxed types where there's a
191+ string catch-all case. In that case, any polyvariant will match,
192+ since the catch-all case will match any string. *)
193+ (match c.cd_args with
194+ | Cstr_tuple [{desc= Tconstr (p, _, _)}]
195+ when is_unboxed && Path. same p Predef. path_string -> true
196+ | _ -> polyvariant_value = constructor_name)
197+ ))
191198 polyvariant_runtime_representations
192199 then Ok ()
193200 else Error `Unknown
0 commit comments