@@ -167,6 +167,7 @@ let can_coerce_polyvariant_to_variant ~row_fields ~constructors ~type_attributes
167
167
Error `PolyvariantConstructorHasPayload
168
168
else
169
169
let is_unboxed = Ast_untagged_variants. has_untagged type_attributes in
170
+ print_endline (string_of_bool is_unboxed);
170
171
if
171
172
List. for_all
172
173
(fun polyvariant_value ->
@@ -179,15 +180,21 @@ let can_coerce_polyvariant_to_variant ~row_fields ~constructors ~type_attributes
179
180
| Some (String as_runtime_string ) ->
180
181
(* `@as("")`, does the configured string match the polyvariant value? *)
181
182
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
185
183
| Some _ ->
186
184
(* Any other `@as` can't match since it's by definition not a string *)
187
185
false
188
186
| 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
+ ))
191
198
polyvariant_runtime_representations
192
199
then Ok ()
193
200
else Error `Unknown
0 commit comments