Skip to content

Commit 5fa80fe

Browse files
authored
Don't track attributes inside attributes for warning 53 (#115)
This fixes attribute tracking both for serialized ast files and for attributes within attributes.
1 parent 8a69777 commit 5fa80fe

19 files changed

+7011
-6261
lines changed

.depend

+2-2
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ parsing/ast_mapper.cmo : \
300300
utils/load_path.cmi \
301301
utils/config.cmi \
302302
utils/clflags.cmi \
303-
parsing/builtin_attributes.cmi \
304303
parsing/asttypes.cmi \
305304
parsing/ast_helper.cmi \
306305
parsing/ast_mapper.cmi
@@ -312,7 +311,6 @@ parsing/ast_mapper.cmx : \
312311
utils/load_path.cmx \
313312
utils/config.cmx \
314313
utils/clflags.cmx \
315-
parsing/builtin_attributes.cmx \
316314
parsing/asttypes.cmi \
317315
parsing/ast_helper.cmx \
318316
parsing/ast_mapper.cmi
@@ -346,6 +344,7 @@ parsing/builtin_attributes.cmo : \
346344
utils/config.cmi \
347345
utils/clflags.cmi \
348346
parsing/asttypes.cmi \
347+
parsing/ast_iterator.cmi \
349348
parsing/ast_helper.cmi \
350349
parsing/builtin_attributes.cmi
351350
parsing/builtin_attributes.cmx : \
@@ -357,6 +356,7 @@ parsing/builtin_attributes.cmx : \
357356
utils/config.cmx \
358357
utils/clflags.cmx \
359358
parsing/asttypes.cmi \
359+
parsing/ast_iterator.cmx \
360360
parsing/ast_helper.cmx \
361361
parsing/builtin_attributes.cmi
362362
parsing/builtin_attributes.cmi : \

.depend.menhir

+27-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
1-
parsing/parser.cmo : parsing/syntaxerr.cmi parsing/parsetree.cmi \
2-
parsing/longident.cmi parsing/location.cmi parsing/docstrings.cmi \
3-
utils/clflags.cmi parsing/asttypes.cmi parsing/ast_helper.cmi \
1+
parsing/parser.cmo : \
2+
parsing/syntaxerr.cmi \
3+
parsing/parsetree.cmi \
4+
parsing/longident.cmi \
5+
parsing/location.cmi \
6+
parsing/extensions.cmi \
7+
parsing/docstrings.cmi \
8+
utils/clflags.cmi \
9+
parsing/builtin_attributes.cmi \
10+
parsing/asttypes.cmi \
11+
parsing/ast_helper.cmi \
412
parsing/parser.cmi
5-
parsing/parser.cmx : parsing/syntaxerr.cmx parsing/parsetree.cmi \
6-
parsing/longident.cmx parsing/location.cmx parsing/docstrings.cmx \
7-
utils/clflags.cmx parsing/asttypes.cmi parsing/ast_helper.cmx \
13+
parsing/parser.cmx : \
14+
parsing/syntaxerr.cmx \
15+
parsing/parsetree.cmi \
16+
parsing/longident.cmx \
17+
parsing/location.cmx \
18+
parsing/extensions.cmx \
19+
parsing/docstrings.cmx \
20+
utils/clflags.cmx \
21+
parsing/builtin_attributes.cmx \
22+
parsing/asttypes.cmi \
23+
parsing/ast_helper.cmx \
824
parsing/parser.cmi
9-
parsing/parser.cmi : parsing/parsetree.cmi parsing/location.cmi \
25+
parsing/parser.cmi : \
26+
parsing/parsetree.cmi \
27+
parsing/longident.cmi \
28+
parsing/location.cmi \
1029
parsing/docstrings.cmi
11-
parsing/parser.ml parsing/parser.mli: parsing/ast_helper.cmi parsing/asttypes.cmi utils/clflags.cmi parsing/docstrings.cmi parsing/location.cmi parsing/longident.cmi parsing/parsetree.cmi parsing/syntaxerr.cmi
30+
parsing/parser.ml parsing/parser.mli: parsing/ast_helper.cmi parsing/asttypes.cmi parsing/builtin_attributes.cmi utils/clflags.cmi parsing/docstrings.cmi parsing/extensions.cmi parsing/location.cmi parsing/longident.cmi parsing/parsetree.cmi parsing/syntaxerr.cmi

boot/menhir/parser.ml

+6,239-6,210
Large diffs are not rendered by default.

compilerlibs/Makefile.compilerlibs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ PARSING = \
6161
parsing/ast_helper.cmo \
6262
parsing/extensions_parsing.cmo parsing/extensions.cmo \
6363
parsing/pprintast.cmo \
64+
parsing/ast_iterator.cmo \
6465
parsing/builtin_attributes.cmo \
6566
parsing/camlinternalMenhirLib.cmo \
6667
parsing/parser.cmo \
6768
parsing/lexer.cmo \
6869
parsing/parse.cmo \
6970
parsing/printast.cmo \
7071
parsing/ast_mapper.cmo \
71-
parsing/ast_iterator.cmo \
7272
parsing/attr_helper.cmo \
7373
parsing/ast_invariants.cmo \
7474
parsing/depend.cmo

driver/pparse.ml

+3-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@ let file_aux ~tool_name inputfile (type a) parse_fun invariant_fun
187187
Location.input_lexbuf := Some lexbuf;
188188
Profile.record_call "parser" (fun () -> parse_fun lexbuf)
189189
end
190-
with x -> close_in ic; raise x
190+
with x ->
191+
close_in ic;
192+
raise x
191193
in
192194
close_in ic;
193195
Profile.record_call "-ppx" (fun () ->

dune

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767

6868
;; PARSING
6969
location longident docstrings syntaxerr ast_helper camlinternalMenhirLib
70-
parser lexer parse printast pprintast ast_mapper ast_iterator attr_helper
70+
ast_iterator parser lexer parse printast pprintast ast_mapper attr_helper
7171
builtin_attributes ast_invariants depend extensions_parsing extensions
7272
; manual update: mli only files
7373
asttypes parsetree

otherlibs/dynlink/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ COMPILERLIBS_SOURCES=\
9696
parsing/docstrings.ml \
9797
parsing/syntaxerr.ml \
9898
parsing/ast_helper.ml \
99+
parsing/ast_iterator.ml \
99100
parsing/builtin_attributes.ml \
100101
parsing/ast_mapper.ml \
101102
parsing/attr_helper.ml \

otherlibs/dynlink/dune

+5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
longident
4242
docstrings
4343
syntaxerr
44+
ast_iterator
4445
ast_helper
4546
ast_mapper
4647
attr_helper
@@ -120,6 +121,7 @@
120121
(copy_files ../../parsing/longident.ml)
121122
(copy_files ../../parsing/docstrings.ml)
122123
(copy_files ../../parsing/syntaxerr.ml)
124+
(copy_files ../../parsing/ast_iterator.ml)
123125
(copy_files ../../parsing/ast_helper.ml)
124126
(copy_files ../../parsing/ast_mapper.ml)
125127
(copy_files ../../parsing/attr_helper.ml)
@@ -172,6 +174,7 @@
172174
(copy_files ../../parsing/longident.mli)
173175
(copy_files ../../parsing/docstrings.mli)
174176
(copy_files ../../parsing/syntaxerr.mli)
177+
(copy_files ../../parsing/ast_iterator.mli)
175178
(copy_files ../../parsing/ast_helper.mli)
176179
(copy_files ../../parsing/ast_mapper.mli)
177180
(copy_files ../../parsing/attr_helper.mli)
@@ -273,6 +276,7 @@
273276
.dynlink_compilerlibs.objs/byte/dynlink_compilerlibs__Lazy_backtrack.cmo
274277
.dynlink_compilerlibs.objs/byte/dynlink_compilerlibs__Persistent_env.cmo
275278
.dynlink_compilerlibs.objs/byte/dynlink_compilerlibs__Docstrings.cmo
279+
.dynlink_compilerlibs.objs/byte/dynlink_compilerlibs__Ast_iterator.cmo
276280
.dynlink_compilerlibs.objs/byte/dynlink_compilerlibs__Ast_helper.cmo
277281
.dynlink_compilerlibs.objs/byte/dynlink_compilerlibs__Builtin_attributes.cmo
278282
.dynlink_compilerlibs.objs/byte/dynlink_compilerlibs__Type_immediacy.cmo
@@ -340,6 +344,7 @@
340344
.dynlink_compilerlibs.objs/native/dynlink_compilerlibs__Lazy_backtrack.cmx
341345
.dynlink_compilerlibs.objs/native/dynlink_compilerlibs__Persistent_env.cmx
342346
.dynlink_compilerlibs.objs/native/dynlink_compilerlibs__Docstrings.cmx
347+
.dynlink_compilerlibs.objs/native/dynlink_compilerlibs__Ast_iterator.cmx
343348
.dynlink_compilerlibs.objs/native/dynlink_compilerlibs__Ast_helper.cmx
344349
.dynlink_compilerlibs.objs/native/dynlink_compilerlibs__Builtin_attributes.cmx
345350
.dynlink_compilerlibs.objs/native/dynlink_compilerlibs__Type_immediacy.cmx

parsing/ast_helper.mli

-4
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ end
5757

5858
(** {1 Attributes} *)
5959
module Attr : sig
60-
(** This should be used by all external tools (e.g., ppxs) to create
61-
attributes. Inside the compiler, this should be used only when it is
62-
known the attribute does not need to be tracked for misplaced attribute
63-
warnings. Otherwise, use [Builtin_attributes.mk_internal]. *)
6460
val mk: ?loc:loc -> str -> payload -> attribute
6561
end
6662

parsing/ast_invariants.ml

+6-2
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,12 @@ let iterator =
184184
subtypes is not allowed."
185185
in
186186
let attribute self attr =
187-
super.attribute self attr;
188-
Builtin_attributes.register_attr attr.attr_name
187+
(* The change to `self` here avoids registering attributes within attributes
188+
for the purposes of warning 53, while keeping all the other invariant
189+
checks for attribute payloads. See comment on [attr_tracking_time] in
190+
[builtin_attributes.mli]. *)
191+
super.attribute { self with attribute = super.attribute } attr;
192+
Builtin_attributes.(register_attr Invariant_check attr.attr_name)
189193
in
190194
{ super with
191195
type_declaration

parsing/ast_mapper.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,7 @@ let extension_of_error {kind; main; sub} =
769769
List.map (fun msg -> Str.extension (extension_of_sub msg)) sub)
770770

771771
let attribute_of_warning loc s =
772-
Builtin_attributes.mk_internal
772+
Attr.mk
773773
{loc; txt = "ocaml.ppwarning" }
774774
(PStr ([Str.eval ~loc (Exp.constant (Pconst_string (s, loc, None)))]))
775775

parsing/builtin_attributes.ml

+17-7
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,14 @@ let builtin_attrs =
9292

9393
let is_builtin_attr s = Hashtbl.mem builtin_attrs s
9494

95-
let register_attr name =
96-
if is_builtin_attr name.txt
97-
then Attribute_table.replace unused_attrs name ()
98-
99-
let mk_internal ?(loc= !default_loc) name payload =
100-
register_attr name;
101-
Attr.mk ~loc name payload
95+
type attr_tracking_time = Parser | Invariant_check
10296

97+
let register_attr attr_tracking_time name =
98+
match attr_tracking_time with
99+
| Parser when !Clflags.all_ppx <> [] -> ()
100+
| Parser | Invariant_check ->
101+
if is_builtin_attr name.txt then
102+
Attribute_table.replace unused_attrs name ()
103103

104104
let ident_of_payload = function
105105
| PStr[{pstr_desc=Pstr_eval({pexp_desc=Pexp_ident {txt=Lident id}},_)}] ->
@@ -220,6 +220,16 @@ let mark_warn_on_literal_pattern_used l =
220220
| _ -> ())
221221
l
222222

223+
let mark_payload_attrs_used payload =
224+
let iter =
225+
{ Ast_iterator.default_iterator
226+
with attribute = fun self a ->
227+
mark_used a.attr_name;
228+
Ast_iterator.default_iterator.attribute self a
229+
}
230+
in
231+
iter.payload iter payload
232+
223233
let alerts_of_attrs l =
224234
List.fold_left
225235
(fun acc (_, kind, message) ->

parsing/builtin_attributes.mli

+27-10
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,26 @@
3939
*)
4040

4141

42-
(** Used by the compiler for attributes that may be compiler built-ins. These
43-
are tracked for misplaced attribute warnings. This should be used rather
44-
than Attr.mk for all built-in attributes. *)
45-
val mk_internal:
46-
?loc:Location.t -> string Location.loc -> Parsetree.payload ->
47-
Parsetree.attribute
48-
49-
(** Used to record attributes that should be tracked for the purpose of
50-
misplaced attribute warnings. *)
51-
val register_attr: string Location.loc -> unit
42+
(** [register_attr] must be called on the locations of all attributes that
43+
should be tracked for the purpose of misplaced attribute warnings. In
44+
particular, it should be called on all attributes that are present in the
45+
source program except those that are contained in the payload of another
46+
attribute (because these may be left behind by a ppx and intentionally
47+
ignored by the compiler).
48+
49+
The [attr_tracking_time] argument indicates when the attr is being added for
50+
tracking - either when it is created in the parser or when we see it while
51+
running the check in the [Ast_invariants] module. This ensures that we
52+
track only attributes from the final version of the parse tree: we skip
53+
adding attributes at parse time if we can see that a ppx will be run later,
54+
because the [Ast_invariants] check is always run on the result of a ppx.
55+
56+
Note that the [Ast_invariants] check is also run on parse trees created from
57+
marshalled ast files if no ppx is being used, ensuring we don't miss
58+
attributes in that case.
59+
*)
60+
type attr_tracking_time = Parser | Invariant_check
61+
val register_attr : attr_tracking_time -> string Location.loc -> unit
5262

5363
(** Marks alert attributes used for the purposes of misplaced attribute
5464
warnings. Call this when moving things with alert attributes into the
@@ -61,6 +71,13 @@ val mark_alerts_used : Parsetree.attributes -> unit
6171
attributes into the environment. *)
6272
val mark_warn_on_literal_pattern_used : Parsetree.attributes -> unit
6373

74+
(** Marks the attributes hiding in the payload of another attribute used, for
75+
the purposes of misplaced attribute warnings (see comment on
76+
[attr_tracking_time] above). In the parser, it's simplest to add these to
77+
the table and remove them later, rather than threading through state
78+
tracking whether we're in an attribute payload. *)
79+
val mark_payload_attrs_used : Parsetree.payload -> unit
80+
6481
(** Issue misplaced attribute warnings for all attributes created with
6582
[mk_internal] but not yet marked used. *)
6683
val warn_unused : unit -> unit

parsing/parser.mly

+21-13
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,12 @@ let mkuplus ~oploc name arg =
151151

152152
let local_ext_loc loc = mkloc "extension.local" loc
153153

154+
let mk_attr ~loc name payload =
155+
Builtin_attributes.(register_attr Parser name);
156+
Attr.mk ~loc name payload
157+
154158
let local_attr loc =
155-
Builtin_attributes.mk_internal ~loc (local_ext_loc loc) (PStr [])
159+
mk_attr ~loc (local_ext_loc loc) (PStr [])
156160

157161
let local_extension loc =
158162
Exp.mk ~loc:Location.none
@@ -161,8 +165,7 @@ let local_extension loc =
161165
let include_functor_ext_loc loc = mkloc "extension.include_functor" loc
162166

163167
let include_functor_attr loc =
164-
Builtin_attributes.mk_internal ~loc:loc (include_functor_ext_loc loc)
165-
(PStr [])
168+
mk_attr ~loc:loc (include_functor_ext_loc loc) (PStr [])
166169

167170
let mkexp_stack ~loc ~kwd_loc exp =
168171
ghexp ~loc (Pexp_apply(local_extension (make_loc kwd_loc), [Nolabel, exp]))
@@ -189,8 +192,7 @@ let wrap_exp_local_if p exp loc =
189192
if p then wrap_exp_stack exp (make_loc loc) else exp
190193

191194
let curry_attr loc =
192-
Builtin_attributes.mk_internal ~loc:Location.none
193-
(mkloc "extension.curry" loc) (PStr [])
195+
mk_attr ~loc:Location.none (mkloc "extension.curry" loc) (PStr [])
194196

195197
let is_curry_attr attr =
196198
attr.attr_name.txt = "extension.curry"
@@ -208,12 +210,12 @@ let maybe_curry_typ typ loc =
208210
let global_loc loc = mkloc "extension.global" loc
209211

210212
let global_attr loc =
211-
Builtin_attributes.mk_internal ~loc:loc (global_loc loc) (PStr [])
213+
mk_attr ~loc:loc (global_loc loc) (PStr [])
212214

213215
let nonlocal_loc loc = mkloc "extension.nonlocal" loc
214216

215217
let nonlocal_attr loc =
216-
Builtin_attributes.mk_internal ~loc:Location.none (nonlocal_loc loc) (PStr [])
218+
mk_attr ~loc:Location.none (nonlocal_loc loc) (PStr [])
217219

218220
let mkld_global ld loc =
219221
{ ld with pld_attributes = global_attr loc :: ld.pld_attributes }
@@ -4177,17 +4179,17 @@ attr_id:
41774179
) { $1 }
41784180
;
41794181
attribute:
4180-
LBRACKETAT attr_id payload RBRACKET
4181-
{ Builtin_attributes.mk_internal ~loc:(make_loc $sloc) $2 $3 }
4182+
LBRACKETAT attr_id attr_payload RBRACKET
4183+
{ mk_attr ~loc:(make_loc $sloc) $2 $3 }
41824184
;
41834185
post_item_attribute:
4184-
LBRACKETATAT attr_id payload RBRACKET
4185-
{ Builtin_attributes.mk_internal ~loc:(make_loc $sloc) $2 $3 }
4186+
LBRACKETATAT attr_id attr_payload RBRACKET
4187+
{ mk_attr ~loc:(make_loc $sloc) $2 $3 }
41864188
;
41874189
floating_attribute:
4188-
LBRACKETATATAT attr_id payload RBRACKET
4190+
LBRACKETATATAT attr_id attr_payload RBRACKET
41894191
{ mark_symbol_docs $sloc;
4190-
Builtin_attributes.mk_internal ~loc:(make_loc $sloc) $2 $3 }
4192+
mk_attr ~loc:(make_loc $sloc) $2 $3 }
41914193
;
41924194
%inline post_item_attributes:
41934195
post_item_attribute*
@@ -4227,4 +4229,10 @@ payload:
42274229
| QUESTION pattern { PPat ($2, None) }
42284230
| QUESTION pattern WHEN seq_expr { PPat ($2, Some $4) }
42294231
;
4232+
attr_payload:
4233+
payload
4234+
{ Builtin_attributes.mark_payload_attrs_used $1;
4235+
$1
4236+
}
4237+
;
42304238
%%
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
let w53_ast =
2+
Pparse.parse_implementation ~tool_name:"w53_test" "w53.ml"
3+
4+
let () = Pparse.write_ast Pparse.Structure "w53.marshalled.ml" w53_ast

testsuite/tests/warnings/w53.ml

+3
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,6 @@ module TestPollStruct = struct
375375
"x"
376376
external z : int64 -> int64 = "x" [@@poll error] (* rejected *)
377377
end
378+
379+
(* Attributes in attributes shouldn't be tracked for w53 *)
380+
[@@@foo [@@@deprecated]]

0 commit comments

Comments
 (0)