@@ -216862,6 +216862,7 @@ type error =
216862216862 | Illegal_letrec_pat
216863216863 | Labels_omitted of string list
216864216864 | Empty_record_literal
216865+ | Field_not_optional of string * type_expr
216865216866exception Error of Location.t * Env.t * error
216866216867exception Error_forward of Location.error
216867216868
@@ -216969,6 +216970,7 @@ type error =
216969216970 | Illegal_letrec_pat
216970216971 | Labels_omitted of string list
216971216972 | Empty_record_literal
216973+ | Field_not_optional of string * type_expr
216972216974exception Error of Location.t * Env.t * error
216973216975exception Error_forward of Location.error
216974216976
@@ -217204,6 +217206,19 @@ let extract_concrete_variant env ty =
217204217206 | (p0, p, {type_kind=Type_open}) -> (p0, p, [])
217205217207 | _ -> raise Not_found
217206217208
217209+ let label_is_optional ld =
217210+ match ld.lbl_repres with
217211+ | Record_optional_labels lbls -> Ext_list.mem_string lbls ld.lbl_name
217212+ | Record_inlined {optional_labels} -> Ext_list.mem_string optional_labels ld.lbl_name
217213+ | _ -> false
217214+
217215+ let check_optional_attr env ld attrs loc =
217216+ let check_redundant () =
217217+ if not (label_is_optional ld) then
217218+ raise (Error (loc, env, Field_not_optional (ld.lbl_name, ld.lbl_res)));
217219+ true in
217220+ Ext_list.exists attrs (fun ({txt}, _) ->
217221+ txt = "ns.optional" && check_redundant ())
217207217222
217208217223(* unification inside type_pat*)
217209217224let unify_pat_types loc env ty ty' =
@@ -218046,15 +218061,8 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
218046218061 Some (p0, p), expected_ty
218047218062 with Not_found -> None, newvar ()
218048218063 in
218049- let label_is_optional ld =
218050- match ld.lbl_repres with
218051- | Record_optional_labels lbls -> Ext_list.mem_string lbls ld.lbl_name
218052- | Record_inlined {optional_labels} -> Ext_list.mem_string optional_labels ld.lbl_name
218053- | _ -> false in
218054218064 let process_optional_label (ld, pat) =
218055- let exp_optional_attr =
218056- Ext_list.exists pat.ppat_attributes (fun ({txt },_) -> txt = "ns.optional")
218057- in
218065+ let exp_optional_attr = check_optional_attr !env ld pat.ppat_attributes pat.ppat_loc in
218058218066 let isFromPamatch = match pat.ppat_desc with
218059218067 | Ppat_construct ({txt = Lident s}, _) ->
218060218068 String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
@@ -218773,15 +218781,8 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
218773218781 unify_exp env (re exp) (instance env ty_expected);
218774218782 exp
218775218783 in
218776- let label_is_optional ld =
218777- match ld.lbl_repres with
218778- | Record_optional_labels lbls -> Ext_list.mem_string lbls ld.lbl_name
218779- | Record_inlined {optional_labels} -> Ext_list.mem_string optional_labels ld.lbl_name
218780- | _ -> false in
218781218784 let process_optional_label (id, ld, e) =
218782- let exp_optional_attr =
218783- Ext_list.exists e.pexp_attributes (fun ({txt },_) -> txt = "ns.optional")
218784- in
218785+ let exp_optional_attr = check_optional_attr env ld e.pexp_attributes e.pexp_loc in
218785218786 if label_is_optional ld && not exp_optional_attr then
218786218787 let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
218787218788 let e = Ast_helper.Exp.construct ~loc:e.pexp_loc lid (Some e)
@@ -220693,6 +220694,11 @@ let report_error env ppf = function
220693220694 (String.concat ", " labels)
220694220695 | Empty_record_literal ->
220695220696 fprintf ppf "Empty record literal {} should be type annotated or used in a record context."
220697+ | Field_not_optional (name, typ) ->
220698+ fprintf ppf
220699+ "Field @{<info>%s@} is not optional in type %a. Use without ?" name
220700+ type_expr typ
220701+
220696220702
220697220703let super_report_error_no_wrap_printing_env = report_error
220698220704
0 commit comments