@@ -10,6 +10,13 @@ module Parser = Res_parser
10
10
let mk_loc start_loc end_loc =
11
11
Location. {loc_start = start_loc; loc_end = end_loc; loc_ghost = false }
12
12
13
+ let rec skip_doc_comments p =
14
+ match p.Parser. token with
15
+ | DocComment _ ->
16
+ Parser. next p;
17
+ skip_doc_comments p
18
+ | _ -> ()
19
+
13
20
type inline_types_context = {
14
21
mutable found_inline_types :
15
22
(string * Warnings .loc * Parsetree .type_kind ) list ;
@@ -5165,8 +5172,37 @@ and parse_type_representation ?current_type_name_path ?inline_types_context p =
5165
5172
in
5166
5173
let kind =
5167
5174
match p.Parser. token with
5168
- | Bar | Uident _ | DocComment _ | At ->
5175
+ | Bar | Uident _ | DocComment _ ->
5169
5176
Parsetree. Ptype_variant (parse_type_constructor_declarations p)
5177
+ | At -> (
5178
+ (* Attributes can prefix either a variant (constructor list), a record, or an
5179
+ open/extensible variant marker (`..`). Peek past attributes and any doc
5180
+ comments to decide which kind it is. *)
5181
+ let after_attrs =
5182
+ Parser. lookahead p (fun state ->
5183
+ ignore (parse_attributes state);
5184
+ skip_doc_comments state;
5185
+ state.Parser. token)
5186
+ in
5187
+ match after_attrs with
5188
+ | Lbrace ->
5189
+ (* consume the attributes and any doc comments before the record *)
5190
+ ignore (parse_attributes p);
5191
+ skip_doc_comments p;
5192
+ Parsetree. Ptype_record
5193
+ (parse_record_declaration ?current_type_name_path
5194
+ ?inline_types_context p)
5195
+ | DotDot ->
5196
+ (* attributes before an open variant marker; consume attrs/docs then handle `..` *)
5197
+ ignore (parse_attributes p);
5198
+ skip_doc_comments p;
5199
+ Parser. next p;
5200
+ (* consume DotDot *)
5201
+ Ptype_open
5202
+ | _ ->
5203
+ (* fall back to variant constructor declarations; leave attributes for the
5204
+ constructor parsing so they attach to the first constructor. *)
5205
+ Parsetree. Ptype_variant (parse_type_constructor_declarations p))
5170
5206
| Lbrace ->
5171
5207
Parsetree. Ptype_record
5172
5208
(parse_record_declaration ?current_type_name_path ?inline_types_context
@@ -5727,22 +5763,42 @@ and parse_type_equation_and_representation ?current_type_name_path
5727
5763
let priv, kind = parse_type_representation p in
5728
5764
(None , priv, kind)
5729
5765
| At -> (
5730
- (* Attribute can start a variant constructor or a type manifest.
5731
- Look ahead past attributes; if a constructor -like token follows (Uident not immediately
5732
- followed by a Dot, or DotDotDot/Bar/DocComment), treat as variant; otherwise manifest *)
5733
- let is_variant_after_attrs =
5766
+ (* Attributes can start a representation ( variant/record/open variant) or a manifest.
5767
+ Look ahead past attributes (and doc comments). If a representation -like token follows,
5768
+ parse it as a representation; otherwise treat as a manifest. *)
5769
+ let is_representation_after_attrs =
5734
5770
Parser. lookahead p (fun state ->
5735
5771
ignore (parse_attributes state);
5772
+ (* optionally skip a run of doc comments before deciding *)
5773
+ skip_doc_comments state;
5736
5774
match state.Parser. token with
5775
+ | Lbrace -> (
5776
+ (* Disambiguate record declaration vs object type.
5777
+ Peek inside the braces; if it looks like an object (String/Dot/DotDot/DotDotDot),
5778
+ then this is a manifest type expression, not a representation. If it looks like
5779
+ a record field (e.g. Lident or attributes before one), treat as representation. *)
5780
+ Parser. next state;
5781
+ (* consume Lbrace *)
5782
+ ignore (parse_attributes state);
5783
+ skip_doc_comments state;
5784
+ match state.Parser. token with
5785
+ | String _ | Dot | DotDot | DotDotDot ->
5786
+ false (* object type => manifest *)
5787
+ | _ -> true
5788
+ (* record decl => representation *) )
5789
+ | Bar -> true (* variant constructor list *)
5790
+ | DotDot -> true (* extensible/open variant ".." *)
5737
5791
| Uident _ -> (
5792
+ (* constructor vs module-qualified manifest *)
5738
5793
Parser. next state;
5739
5794
match state.Parser. token with
5740
- | Dot -> false
5741
- | _ -> true )
5742
- | DotDotDot | Bar | DocComment _ -> true
5795
+ | Dot -> false (* M.t => manifest *)
5796
+ | _ -> true
5797
+ (* Uident starting a constructor *) )
5798
+ | DocComment _ -> true (* doc before constructor list *)
5743
5799
| _ -> false )
5744
5800
in
5745
- if is_variant_after_attrs then
5801
+ if is_representation_after_attrs then
5746
5802
let priv, kind = parse_type_representation p in
5747
5803
(None , priv, kind)
5748
5804
else
0 commit comments