File: attributes.html

package info (click to toggle)
ocaml-doc 4.11-2
  • links: PTS, VCS
  • area: non-free
  • in suites: bookworm, bullseye, sid, trixie
  • size: 20,580 kB
  • sloc: sh: 37; makefile: 11
file content (513 lines) | stat: -rw-r--r-- 39,899 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
<!DOCTYPE html>
<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="generator" content="hevea 2.32">

  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<link rel="stylesheet" type="text/css" href="manual.css">
<title>8.12  Attributes</title>
</head>
<body>
<a href="bigarray.html"><img src="previous_motif.svg" alt="Previous"></a>
<a href="extn.html"><img src="contents_motif.svg" alt="Up"></a>
<a href="extensionnodes.html"><img src="next_motif.svg" alt="Next"></a>
<hr>
<h2 class="section" id="s:attributes"><a class="section-anchor" href="#s:attributes" aria-hidden="true"></a>8.12  Attributes</h2>
<ul>
<li><a href="attributes.html#ss%3Abuiltin-attributes">8.12.1  Built-in attributes</a>
</li></ul>
<p><a id="hevea_manual.kwd227"></a></p><p>(Introduced in OCaml 4.02,
infix notations for constructs other than expressions added in 4.03)</p><p>Attributes are “decorations” of the syntax tree which are mostly
ignored by the type-checker but can be used by external tools. An
attribute is made of an identifier and a payload, which can be a
structure, a type expression (prefixed with <span class="c003">:</span>), a signature
(prefixed with <span class="c003">:</span>) or a pattern (prefixed with <span class="c003">?</span>) optionally
followed by a <span class="c003">when</span> clause:</p><div class="syntax"><table class="display dcenter"><tr class="c019"><td class="dcell"><table class="c001 cellpading0"><tr><td class="c018">
<a class="syntax" id="attr-id"><span class="c010">attr-id</span></a></td><td class="c015">::=</td><td class="c017">
<a class="syntax" href="lex.html#lowercase-ident"><span class="c010">lowercase-ident</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017">  <a class="syntax" href="lex.html#capitalized-ident"><span class="c010">capitalized-ident</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017">  <a class="syntax" href="#attr-id"><span class="c010">attr-id</span></a> <span class="c004">.</span>  <a class="syntax" href="#attr-id"><span class="c010">attr-id</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" id="attr-payload"><span class="c010">attr-payload</span></a></td><td class="c015">::=</td><td class="c017">
[ <a class="syntax" href="modules.html#module-items"><span class="c010">module-items</span></a> ]
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017">  <span class="c004">:</span> <a class="syntax" href="types.html#typexpr"><span class="c010">typexpr</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017">  <span class="c004">:</span> [ <a class="syntax" href="modtypes.html#specification"><span class="c010">specification</span></a> ]
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017">  <span class="c004">?</span> <a class="syntax" href="patterns.html#pattern"><span class="c010">pattern</span></a>  [<span class="c004">when</span> <a class="syntax" href="expr.html#expr"><span class="c010">expr</span></a>]
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
</table></td></tr>
</table></div><p>The first form of attributes is attached with a postfix notation on
“algebraic” categories:</p><div class="syntax"><table class="display dcenter"><tr class="c019"><td class="dcell"><table class="c001 cellpading0"><tr><td class="c018">
<a class="syntax" id="attribute"><span class="c010">attribute</span></a></td><td class="c015">::=</td><td class="c017">
<span class="c004">[@</span> <a class="syntax" href="#attr-id"><span class="c010">attr-id</span></a>  <a class="syntax" href="#attr-payload"><span class="c010">attr-payload</span></a> <span class="c004">]</span>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="expr.html#expr"><span class="c010">expr</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="expr.html#expr"><span class="c010">expr</span></a>  <a class="syntax" href="#attribute"><span class="c010">attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="types.html#typexpr"><span class="c010">typexpr</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="types.html#typexpr"><span class="c010">typexpr</span></a>  <a class="syntax" href="#attribute"><span class="c010">attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="patterns.html#pattern"><span class="c010">pattern</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="patterns.html#pattern"><span class="c010">pattern</span></a>  <a class="syntax" href="#attribute"><span class="c010">attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="modules.html#module-expr"><span class="c010">module-expr</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="modules.html#module-expr"><span class="c010">module-expr</span></a>  <a class="syntax" href="#attribute"><span class="c010">attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a>  <a class="syntax" href="#attribute"><span class="c010">attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">class-expr</span></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#class-expr"><span class="c010">class-expr</span></a>  <a class="syntax" href="#attribute"><span class="c010">attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">class-type</span></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#class-type"><span class="c010">class-type</span></a>  <a class="syntax" href="#attribute"><span class="c010">attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
</table></td></tr>
</table></div><p>This form of attributes can also be inserted after the <span class="c004">`</span><a class="syntax" href="names.html#tag-name"><span class="c010">tag-name</span></a>
in polymorphic variant type expressions (<a class="syntax" href="types.html#tag-spec-first"><span class="c010">tag-spec-first</span></a>, <a class="syntax" href="types.html#tag-spec"><span class="c010">tag-spec</span></a>,
<a class="syntax" href="types.html#tag-spec-full"><span class="c010">tag-spec-full</span></a>) or after the <a class="syntax" href="names.html#method-name"><span class="c010">method-name</span></a> in <a class="syntax" href="types.html#method-type"><span class="c010">method-type</span></a>.</p><p>The same syntactic form is also used to attach attributes to labels and
constructors in type declarations:</p><div class="syntax"><table class="display dcenter"><tr class="c019"><td class="dcell"><table class="c001 cellpading0"><tr><td class="c018">
<span class="c010">field-decl</span></td><td class="c015">::=</td><td class="c017">
[<span class="c004">mutable</span>] <a class="syntax" href="names.html#field-name"><span class="c010">field-name</span></a> <span class="c004">:</span>  <a class="syntax" href="types.html#poly-typexpr"><span class="c010">poly-typexpr</span></a>  {<a class="syntax" href="#attribute"><span class="c010">attribute</span></a>}
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="typedecl.html#constr-decl"><span class="c010">constr-decl</span></a></td><td class="c015">::=</td><td class="c017">
(<a class="syntax" href="names.html#constr-name"><span class="c010">constr-name</span></a> ∣  <span class="c004">()</span>) [ <span class="c004">of</span> <a class="syntax" href="typedecl.html#constr-args"><span class="c010">constr-args</span></a> ]  {<a class="syntax" href="#attribute"><span class="c010">attribute</span></a>}
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
</table></td></tr>
</table></div><p>Note: when a label declaration is followed by a semi-colon, attributes
can also be put after the semi-colon (in which case they are merged to
those specified before).</p><p>The second form of attributes are attached to “blocks” such as type
declarations, class fields, etc:</p><div class="syntax"><table class="display dcenter"><tr class="c019"><td class="dcell"><table class="c001 cellpading0"><tr><td class="c018">
<a class="syntax" id="item-attribute"><span class="c010">item-attribute</span></a></td><td class="c015">::=</td><td class="c017">
<span class="c004">[@@</span> <a class="syntax" href="#attr-id"><span class="c010">attr-id</span></a>  <a class="syntax" href="#attr-payload"><span class="c010">attr-payload</span></a> <span class="c004">]</span>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">typedef</span></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="typedecl.html#typedef"><span class="c010">typedef</span></a>  <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">exception-definition</span></td><td class="c015">::=</td><td class="c017">
<span class="c004">exception</span> <a class="syntax" href="typedecl.html#constr-decl"><span class="c010">constr-decl</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">exception</span> <a class="syntax" href="names.html#constr-name"><span class="c010">constr-name</span></a> <span class="c004">=</span>  <a class="syntax" href="names.html#constr"><span class="c010">constr</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">module-items</span></td><td class="c015">::=</td><td class="c017">
[<span class="c004">;;</span>] ( <a class="syntax" href="modules.html#definition"><span class="c010">definition</span></a> ∣  <a class="syntax" href="expr.html#expr"><span class="c010">expr</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> } )  { [<span class="c004">;;</span>] <a class="syntax" href="modules.html#definition"><span class="c010">definition</span></a> ∣  <span class="c004">;;</span> <a class="syntax" href="expr.html#expr"><span class="c010">expr</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> } }  [<span class="c004">;;</span>]
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">class-binding</span></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#class-binding"><span class="c010">class-binding</span></a>  <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">class-spec</span></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#class-spec"><span class="c010">class-spec</span></a>  <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">classtype-def</span></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#classtype-def"><span class="c010">classtype-def</span></a>  <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="modules.html#definition"><span class="c010">definition</span></a></td><td class="c015">::=</td><td class="c017">
<span class="c004">let</span> [<span class="c004">rec</span>] <a class="syntax" href="expr.html#let-binding"><span class="c010">let-binding</span></a>  { <span class="c004">and</span> <a class="syntax" href="expr.html#let-binding"><span class="c010">let-binding</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">external</span> <a class="syntax" href="names.html#value-name"><span class="c010">value-name</span></a> <span class="c004">:</span>  <a class="syntax" href="types.html#typexpr"><span class="c010">typexpr</span></a> <span class="c004">=</span>  <a class="syntax" href="intfc.html#external-declaration"><span class="c010">external-declaration</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="typedecl.html#type-definition"><span class="c010">type-definition</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="typedecl.html#exception-definition"><span class="c010">exception-definition</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#class-definition"><span class="c010">class-definition</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#classtype-definition"><span class="c010">classtype-definition</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">module</span> <a class="syntax" href="names.html#module-name"><span class="c010">module-name</span></a>  { <span class="c004">(</span> <a class="syntax" href="names.html#module-name"><span class="c010">module-name</span></a> <span class="c004">:</span>  <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a> <span class="c004">)</span> }
 [ <span class="c004">:</span> <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a> ]  <span class="c004">=</span>  <a class="syntax" href="modules.html#module-expr"><span class="c010">module-expr</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">module</span> <span class="c004">type</span> <a class="syntax" href="names.html#modtype-name"><span class="c010">modtype-name</span></a> <span class="c004">=</span>  <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">open</span> <a class="syntax" href="names.html#module-path"><span class="c010">module-path</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">include</span> <a class="syntax" href="modules.html#module-expr"><span class="c010">module-expr</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">module</span> <span class="c004">rec</span> <a class="syntax" href="names.html#module-name"><span class="c010">module-name</span></a> <span class="c004">:</span>  <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a> <span class="c004">=</span> 
 <a class="syntax" href="modules.html#module-expr"><span class="c010">module-expr</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> } 
 { <span class="c004">and</span> <a class="syntax" href="names.html#module-name"><span class="c010">module-name</span></a> <span class="c004">:</span>  <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a> <span class="c004">=</span>  <a class="syntax" href="modules.html#module-expr"><span class="c010">module-expr</span></a> 
 { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> } }
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="modtypes.html#specification"><span class="c010">specification</span></a></td><td class="c015">::=</td><td class="c017">
<span class="c004">val</span> <a class="syntax" href="names.html#value-name"><span class="c010">value-name</span></a> <span class="c004">:</span>  <a class="syntax" href="types.html#typexpr"><span class="c010">typexpr</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">external</span> <a class="syntax" href="names.html#value-name"><span class="c010">value-name</span></a> <span class="c004">:</span>  <a class="syntax" href="types.html#typexpr"><span class="c010">typexpr</span></a> <span class="c004">=</span>  <a class="syntax" href="intfc.html#external-declaration"><span class="c010">external-declaration</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="typedecl.html#type-definition"><span class="c010">type-definition</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">exception</span> <a class="syntax" href="typedecl.html#constr-decl"><span class="c010">constr-decl</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#class-specification"><span class="c010">class-specification</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#classtype-definition"><span class="c010">classtype-definition</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">module</span> <a class="syntax" href="names.html#module-name"><span class="c010">module-name</span></a> <span class="c004">:</span>  <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">module</span> <a class="syntax" href="names.html#module-name"><span class="c010">module-name</span></a>  { <span class="c004">(</span> <a class="syntax" href="names.html#module-name"><span class="c010">module-name</span></a> <span class="c004">:</span>  <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a> <span class="c004">)</span> }
<span class="c004">:</span>  <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">module</span> <span class="c004">type</span> <a class="syntax" href="names.html#modtype-name"><span class="c010">modtype-name</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">module</span> <span class="c004">type</span> <a class="syntax" href="names.html#modtype-name"><span class="c010">modtype-name</span></a> <span class="c004">=</span>  <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">open</span> <a class="syntax" href="names.html#module-path"><span class="c010">module-path</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <span class="c004">include</span> <a class="syntax" href="modtypes.html#module-type"><span class="c010">module-type</span></a>  { <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a> }
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">class-field-spec</span></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#class-field-spec"><span class="c010">class-field-spec</span></a>  <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="classes.html#class-field"><span class="c010">class-field</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="classes.html#class-field"><span class="c010">class-field</span></a>  <a class="syntax" href="#item-attribute"><span class="c010">item-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
</table></td></tr>
</table></div><p>A third form of attributes appears as stand-alone structure or
signature items in the module or class sub-languages. They are not
attached to any specific node in the syntax tree:</p><div class="syntax"><table class="display dcenter"><tr class="c019"><td class="dcell"><table class="c001 cellpading0"><tr><td class="c018">
<a class="syntax" id="floating-attribute"><span class="c010">floating-attribute</span></a></td><td class="c015">::=</td><td class="c017">
<span class="c004">[@@@</span> <a class="syntax" href="#attr-id"><span class="c010">attr-id</span></a>  <a class="syntax" href="#attr-payload"><span class="c010">attr-payload</span></a> <span class="c004">]</span>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="modules.html#definition"><span class="c010">definition</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="#floating-attribute"><span class="c010">floating-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="modtypes.html#specification"><span class="c010">specification</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="#floating-attribute"><span class="c010">floating-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<span class="c010">class-field-spec</span></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="#floating-attribute"><span class="c010">floating-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
<tr><td class="c018">
<a class="syntax" href="classes.html#class-field"><span class="c010">class-field</span></a></td><td class="c015">::=</td><td class="c017"> ...
 </td></tr>
<tr><td class="c018">&nbsp;</td><td class="c015">∣</td><td class="c017"> <a class="syntax" href="#floating-attribute"><span class="c010">floating-attribute</span></a>
 </td></tr>
<tr><td class="c018">&nbsp;</td></tr>
</table></td></tr>
</table></div><p>(Note: contrary to what the grammar above describes, <span class="c010">item-attributes</span>
cannot be attached to these floating attributes in <a class="syntax" href="classes.html#class-field-spec"><span class="c010">class-field-spec</span></a>
and <a class="syntax" href="classes.html#class-field"><span class="c010">class-field</span></a>.)</p><p>It is also possible to specify attributes using an infix syntax. For instance:</p><pre>let[@foo] x = 2 in x + 1          === (let x = 2 [@@foo] in x + 1)
begin[@foo][@bar x] ... end       === (begin ... end)[@foo][@bar x]
module[@foo] M = ...              === module M = ... [@@foo]
type[@foo] t = T                  === type t = T [@@foo]
method[@foo] m = ...              === method m = ... [@@foo]
</pre><p>
For <span class="c003">let</span>, the attributes are applied to each bindings:</p><pre>let[@foo] x = 2 and y = 3 in x + y === (let x = 2 [@@foo] and y = 3 in x + y)
let[@foo] x = 2
and[@bar] y = 3 in x + y           === (let x = 2 [@@foo] and y = 3 [@@bar] in x + y)
</pre>
<h3 class="subsection" id="ss:builtin-attributes"><a class="section-anchor" href="#ss:builtin-attributes" aria-hidden="true"></a>8.12.1  Built-in attributes</h3>
<p>Some attributes are understood by the type-checker:
</p><ul class="itemize"><li class="li-itemize">
“ocaml.warning” or “warning”, with a string literal payload.
This can be used as floating attributes in a
signature/structure/object/object type. The string is parsed and has
the same effect as the <span class="c003">-w</span> command-line option, in the scope between
the attribute and the end of the current
signature/structure/object/object type. The attribute can also be
attached to any kind of syntactic item which support attributes
(such as an expression, or a type expression)
in which case its scope is limited to that item.
Note that it is not well-defined which scope is used for a specific
warning. This is implementation dependent and can change between versions.
Some warnings are even completely outside the control of “ocaml.warning”
(for instance, warnings 1, 2, 14, 29 and 50).</li><li class="li-itemize">“ocaml.warnerror” or “warnerror”, with a string literal payload.
Same as “ocaml.warning”, for the <span class="c003">-warn-error</span> command-line option.</li><li class="li-itemize">“ocaml.alert” or “alert”: see section <a href="alerts.html#s%3Aalerts">8.21</a>.</li><li class="li-itemize">“ocaml.deprecated” or “deprecated”: alias for the
“deprecated” alert, see section <a href="alerts.html#s%3Aalerts">8.21</a>.
</li><li class="li-itemize">“ocaml.deprecated_mutable” or “deprecated_mutable”.
Can be applied to a mutable record label. If the label is later
used to modify the field (with “expr.l &lt;- expr”), the “deprecated” alert
will be triggered. If the payload of the attribute is a string literal,
the alert message includes this text.
</li><li class="li-itemize">“ocaml.ppwarning” or “ppwarning”, in any context, with
a string literal payload. The text is reported as warning (22)
by the compiler (currently, the warning location is the location
of the string payload). This is mostly useful for preprocessors which
need to communicate warnings to the user. This could also be used
to mark explicitly some code location for further inspection.
</li><li class="li-itemize">“ocaml.warn_on_literal_pattern” or “warn_on_literal_pattern” annotate
constructors in type definition. A warning (52) is then emitted when this
constructor is pattern matched with a constant literal as argument. This
attribute denotes constructors whose argument is purely informative and
may change in the future. Therefore, pattern matching on this argument
with a constant literal is unreliable. For instance, all built-in exception
constructors are marked as “warn_on_literal_pattern”.
Note that, due to an implementation limitation, this warning (52) is only
triggered for single argument constructor.
</li><li class="li-itemize">“ocaml.tailcall” or “tailcall” can be applied to function
application in order to check that the call is tailcall optimized.
If it it not the case, a warning (51) is emitted.
</li><li class="li-itemize">“ocaml.inline” or “inline” take either “never”, “always”
or nothing as payload on a function or functor definition. If no payload
is provided, the default value is “always”. This payload controls when
applications of the annotated functions should be inlined.
</li><li class="li-itemize">“ocaml.inlined” or “inlined” can be applied to any function or functor
application to check that the call is inlined by the compiler. If the call
is not inlined, a warning (55) is emitted.
</li><li class="li-itemize">“ocaml.noalloc”, “ocaml.unboxed”and “ocaml.untagged” or
“noalloc”, “unboxed” and “untagged” can be used on external
definitions to obtain finer control over the C-to-OCaml interface. See
<a href="intfc.html#s%3AC-cheaper-call">20.11</a> for more details.
</li><li class="li-itemize">“ocaml.immediate” or “immediate” applied on an abstract type mark the type as
having a non-pointer implementation (e.g. “int”, “bool”, “char” or
enumerated types). Mutation of these immediate types does not activate the
garbage collector’s write barrier, which can significantly boost performance in
programs relying heavily on mutable state.
</li><li class="li-itemize">“ocaml.immediate64” or “immediate64” applied on an abstract type mark the
type as having a non-pointer implementation on 64 bit platforms. No assumption
is made on other platforms. In order to produce a type with the
“immediate64“ attribute, one must use “Sys.Immediate64.Make“ functor.
</li><li class="li-itemize"><span class="c003">ocaml.unboxed</span> or <span class="c003">unboxed</span> can be used on a type definition if the
type is a single-field record or a concrete type with a single
constructor that has a single argument. It tells the compiler to
optimize the representation of the type by removing the block that
represents the record or the constructor (i.e. a value of this type
is physically equal to its argument). In the case of GADTs, an
additional restriction applies: the argument must not be an
existential variable, represented by an existential type variable,
or an abstract type constructor applied to an existential type
variable.
</li><li class="li-itemize"><span class="c003">ocaml.boxed</span> or <span class="c003">boxed</span> can be used on type definitions to mean
the opposite of <span class="c003">ocaml.unboxed</span>: keep the unoptimized
representation of the type. When there is no annotation, the
default is currently <span class="c003">boxed</span> but it may change in the future.
</li><li class="li-itemize"><span class="c003">ocaml.local</span> or <span class="c003">local</span> take either <span class="c003">never</span>, <span class="c003">always</span>, <span class="c003">maybe</span> or
nothing as payload on a function definition. If no payload is
provided, the default is <span class="c003">always</span>. The attribute controls an
optimization which consists in compiling a function into a static
continuation. Contrary to inlining, this optimization does not
duplicate the function’s body. This is possible when all
references to the function are full applications, all sharing the
same continuation (for instance, the returned value of several
branches of a pattern matching). <span class="c003">never</span> disables the optimization,
<span class="c003">always</span> asserts that the optimization applies (otherwise a warning
55 is emitted) and <span class="c003">maybe</span> lets the optimization apply when
possible (this is the default behavior when the attribute is not
specified). The optimization is implicitly disabled when using the
bytecode compiler in debug mode (-g), and for functions marked with
an <span class="c003">ocaml.inline always</span> or <span class="c003">ocaml.unrolled</span> attribute which
supersede <span class="c003">ocaml.local</span>.
</li></ul><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">module</span> X = <span class="ocamlkeyword">struct</span>
   [@@@warning <span class="ocamlstring">"+9"</span>]  <span class="ocamlcomment">(* locally enable warning 9 in this structure *)</span>
 <span class="ocamlkeyword">end</span>
 [@@deprecated <span class="ocamlstring">"Please use module 'Y' instead."</span>]

 <span class="ocamlkeyword">let</span> x = <span class="ocamlkeyword">begin</span>[@warning <span class="ocamlstring">"+9"</span>] […] <span class="ocamlkeyword">end</span>

 <span class="ocamlkeyword">type</span> t = A | B
   [@@deprecated <span class="ocamlstring">"Please use type 's' instead."</span>]</div></div>

</div><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">let</span> fires_warning_22 x =
   <span class="ocamlkeyword">assert</span> (x &gt;= 0) [@ppwarning <span class="ocamlhighlight">"TODO: remove this later"</span>]</div>



<div class="pre caml-output warn"><span class="ocamlwarning">Warning</span> 22: TODO: remove this later</div></div>

</div><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">let</span> <span class="ocamlkeyword">rec</span> is_a_tail_call = <span class="ocamlkeyword">function</span>
   | [] -&gt; ()
   | _ :: q -&gt; (is_a_tail_call[@tailcall]) q

 <span class="ocamlkeyword">let</span> <span class="ocamlkeyword">rec</span> not_a_tail_call = <span class="ocamlkeyword">function</span>
   | [] -&gt; []
   | x :: q -&gt; x :: <span class="ocamlhighlight">(not_a_tail_call[@tailcall]) q</span></div>



<div class="pre caml-output warn"><span class="ocamlwarning">Warning</span> 51: expected tailcall</div></div>

</div><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">let</span> f x = x [@@inline]

 <span class="ocamlkeyword">let</span> () = (f[@inlined]) ()</div></div>

</div><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">type</span> fragile =
   | Int <span class="ocamlkeyword">of</span> int [@warn_on_literal_pattern]
   | String <span class="ocamlkeyword">of</span> string [@warn_on_literal_pattern]</div></div>

</div><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">let</span> fragile_match_1 = <span class="ocamlkeyword">function</span>
 | Int <span class="ocamlhighlight">0</span> -&gt; ()
 | _ -&gt; ()</div>



<div class="pre caml-output warn"><span class="ocamlwarning">Warning</span> 52: Code should not depend on the actual values of
this constructor's arguments. They are only for information
and may change in future versions. (See manual section 9.5)
val fragile_match_1 : fragile -&gt; unit = &lt;fun&gt;</div></div>

</div><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">let</span> fragile_match_2 = <span class="ocamlkeyword">function</span>
 | String <span class="ocamlhighlight">"constant"</span> -&gt; ()
 | _ -&gt; ()</div>



<div class="pre caml-output warn"><span class="ocamlwarning">Warning</span> 52: Code should not depend on the actual values of
this constructor's arguments. They are only for information
and may change in future versions. (See manual section 9.5)
val fragile_match_2 : fragile -&gt; unit = &lt;fun&gt;</div></div>

</div><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">module</span> Immediate: <span class="ocamlkeyword">sig</span>
   <span class="ocamlkeyword">type</span> t [@@immediate]
   <span class="ocamlkeyword">val</span> x: t <span class="ocamlkeyword">ref</span>
 <span class="ocamlkeyword">end</span> = <span class="ocamlkeyword">struct</span>
   <span class="ocamlkeyword">type</span> t = A | B
   <span class="ocamlkeyword">let</span> x = <span class="ocamlkeyword">ref</span> A
 <span class="ocamlkeyword">end</span></div></div>

</div><div class="caml-example verbatim">

<div class="ocaml">



<div class="pre caml-input"> <span class="ocamlkeyword">module</span> Int_or_int64 : <span class="ocamlkeyword">sig</span>
   <span class="ocamlkeyword">type</span> t [@@immediate64]
   <span class="ocamlkeyword">val</span> zero : t
   <span class="ocamlkeyword">val</span> one : t
   <span class="ocamlkeyword">val</span> add : t -&gt; t -&gt; t
 <span class="ocamlkeyword">end</span> = <span class="ocamlkeyword">struct</span>

   <span class="ocamlkeyword">include</span> Sys.Immediate64.Make(Int)(Int64)

   <span class="ocamlkeyword">module</span> <span class="ocamlkeyword">type</span> S = <span class="ocamlkeyword">sig</span>
     <span class="ocamlkeyword">val</span> zero : t
     <span class="ocamlkeyword">val</span> one : t
     <span class="ocamlkeyword">val</span> add : t -&gt; t -&gt; t
   <span class="ocamlkeyword">end</span>

   <span class="ocamlkeyword">let</span> impl : (<span class="ocamlkeyword">module</span> S) =
     <span class="ocamlkeyword">match</span> repr <span class="ocamlkeyword">with</span>
     | Immediate -&gt;
         (<span class="ocamlkeyword">module</span> Int : S)
     | Non_immediate -&gt;
         (<span class="ocamlkeyword">module</span> Int64 : S)

   <span class="ocamlkeyword">include</span> (<span class="ocamlkeyword">val</span> impl : S)
 <span class="ocamlkeyword">end</span></div></div>

</div>
<hr>
<a href="bigarray.html"><img src="previous_motif.svg" alt="Previous"></a>
<a href="extn.html"><img src="contents_motif.svg" alt="Up"></a>
<a href="extensionnodes.html"><img src="next_motif.svg" alt="Next"></a>
</body>
</html>