@@ -216862,6 +216862,7 @@ type error =
216862
216862
| Illegal_letrec_pat
216863
216863
| Labels_omitted of string list
216864
216864
| Empty_record_literal
216865
+ | Field_not_optional of string * type_expr
216865
216866
exception Error of Location.t * Env.t * error
216866
216867
exception Error_forward of Location.error
216867
216868
@@ -216969,6 +216970,7 @@ type error =
216969
216970
| Illegal_letrec_pat
216970
216971
| Labels_omitted of string list
216971
216972
| Empty_record_literal
216973
+ | Field_not_optional of string * type_expr
216972
216974
exception Error of Location.t * Env.t * error
216973
216975
exception Error_forward of Location.error
216974
216976
@@ -217204,6 +217206,19 @@ let extract_concrete_variant env ty =
217204
217206
| (p0, p, {type_kind=Type_open}) -> (p0, p, [])
217205
217207
| _ -> raise Not_found
217206
217208
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 ())
217207
217222
217208
217223
(* unification inside type_pat*)
217209
217224
let unify_pat_types loc env ty ty' =
@@ -218046,15 +218061,8 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env
218046
218061
Some (p0, p), expected_ty
218047
218062
with Not_found -> None, newvar ()
218048
218063
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
218054
218064
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
218058
218066
let isFromPamatch = match pat.ppat_desc with
218059
218067
| Ppat_construct ({txt = Lident s}, _) ->
218060
218068
String.length s >= 2 && s.[0] = '#' && s.[1] = '$'
@@ -218773,15 +218781,8 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected =
218773
218781
unify_exp env (re exp) (instance env ty_expected);
218774
218782
exp
218775
218783
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
218781
218784
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
218785
218786
if label_is_optional ld && not exp_optional_attr then
218786
218787
let lid = mknoloc (Longident.(Ldot (Lident "*predef*", "Some"))) in
218787
218788
let e = Ast_helper.Exp.construct ~loc:e.pexp_loc lid (Some e)
@@ -220693,6 +220694,11 @@ let report_error env ppf = function
220693
220694
(String.concat ", " labels)
220694
220695
| Empty_record_literal ->
220695
220696
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
+
220696
220702
220697
220703
let super_report_error_no_wrap_printing_env = report_error
220698
220704
0 commit comments