@@ -98,7 +98,7 @@ type error =
9898 | Record_rest_invalid_type
9999 | Record_rest_requires_type_annotation of string
100100 | Record_rest_not_record of Longident .t
101- | Record_rest_field_not_optional of string * Longident .t
101+ | Record_rest_field_not_optional of string list * Longident .t
102102 | Record_rest_field_missing of string list * Longident .t
103103 | Record_rest_extra_field of string * Longident .t
104104
@@ -1609,19 +1609,20 @@ and type_pat_aux ~constrs ~labels ~no_existentials ~mode ~explode ~env sp
16091609 rest_labels
16101610 in
16111611 (* Validate: fields in both explicit and rest must be optional in the explicit pattern *)
1612- List. iter
1613- ( fun rest_field ->
1614- if
1612+ let not_optional =
1613+ List. filter
1614+ ( fun rest_field ->
16151615 List. mem rest_field explicit_fields
1616- && not (List. mem rest_field explicit_optional_fields)
1617- then
1618- raise
1619- (Error
1620- ( rest_pat.ppat_loc,
1621- ! env,
1622- Record_rest_field_not_optional
1623- (rest_field, rest_type_lid.txt) )))
1624- rest_field_names;
1616+ && not (List. mem rest_field explicit_optional_fields))
1617+ rest_field_names
1618+ in
1619+ if not_optional <> [] then
1620+ raise
1621+ (Error
1622+ ( rest_pat.ppat_loc,
1623+ ! env,
1624+ Record_rest_field_not_optional
1625+ (not_optional, rest_type_lid.txt) ));
16251626 (* Validate: all source fields must be in explicit or rest *)
16261627 (match lbl_pat_list with
16271628 | (_ , label1 , _ , _ ) :: _ ->
@@ -4961,11 +4962,23 @@ let report_error env loc ppf error =
49614962 " Type %a is not a record type and cannot be used as a record rest \
49624963 pattern."
49634964 longident lid
4964- | Record_rest_field_not_optional (field , lid ) ->
4965- fprintf ppf
4966- " Field `%s` appears in both the explicit pattern and the rest type `%a`. \
4967- It must be marked as optional (`?%s`) in the explicit pattern."
4968- field longident lid field
4965+ | Record_rest_field_not_optional (fields , lid ) -> (
4966+ let field_list =
4967+ fields |> List. map (fun f -> " \n - " ^ f) |> String. concat " "
4968+ in
4969+ match fields with
4970+ | [field] ->
4971+ fprintf ppf
4972+ " The following field appears in both the explicit pattern and the rest \
4973+ type `%a`:%s\n\n \
4974+ Mark it as optional (`?%s`) in the explicit pattern."
4975+ longident lid field_list field
4976+ | _ ->
4977+ fprintf ppf
4978+ " The following fields appear in both the explicit pattern and the rest \
4979+ type `%a`:%s\n\n \
4980+ Mark them as optional (e.g. `?fieldName`) in the explicit pattern."
4981+ longident lid field_list)
49694982 | Record_rest_field_missing (fields , lid ) -> (
49704983 let field_list =
49714984 fields |> List. map (fun f -> " \n - " ^ f) |> String. concat " "
0 commit comments