@@ -314,6 +314,14 @@ let extract_concrete_record env ty =
314314 | p0 , p , {type_kind = Type_record (fields , repr )} -> (p0, p, fields, repr)
315315 | _ -> raise Not_found
316316
317+ let private_record_allows_mutation env label =
318+ match extract_concrete_typedecl env label.lbl_res with
319+ | _, _, {type_kind = Type_record _; type_private = Private ; type_attributes}
320+ ->
321+ Builtin_attributes. has_allow_mutation type_attributes
322+ | _ -> false
323+ | exception Not_found -> false
324+
317325let extract_concrete_variant env ty =
318326 match extract_concrete_typedecl env ty with
319327 | p0 , p , {type_kind = Type_variant cstrs } -> (p0, p, cstrs)
@@ -3463,7 +3471,13 @@ and type_label_exp ~call_context create env loc ty_expected
34633471 end_def () ;
34643472 (* Generalize information merged from ty_expected *)
34653473 generalize_structure ty_arg);
3466- if label.lbl_private = Private then
3474+ let allow_private_assignment =
3475+ match call_context with
3476+ | `SetRecordField when not create ->
3477+ private_record_allows_mutation env label
3478+ | _ -> false
3479+ in
3480+ if label.lbl_private = Private && not allow_private_assignment then
34673481 if create then raise (Error (loc, env, Private_type ty_expected))
34683482 else raise (Error (lid.loc, env, Private_label (lid.txt, ty_expected)));
34693483 let arg =
0 commit comments