Skip to content

Commit d1d4c6b

Browse files
committed
Better direct support for ocaml.ppwarning attribute.
Previously, there was a dedicated traversal of the Parsetree to collect and report all ocaml.ppwarning attributes. This approach has the drawback that ocaml.warning settings for the current scope around the ocaml.ppwarnign attribute were not taken into account. Thanks to previous commits, we have a specific place in the code were all attributes go through. So we re-use it to detect ocaml.ppwarning attributes, completely avoiding the dedicated traversal and the drawback mentioned above.
1 parent b074e56 commit d1d4c6b

File tree

6 files changed

+170
-127
lines changed

6 files changed

+170
-127
lines changed

.depend

+86-84
Large diffs are not rendered by default.

Changes

+7-2
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,11 @@ Working version
200200
with an OPAM package called "num".
201201
(Xavier Leroy)
202202

203+
- GPR#1248: support "ocaml.warning" in all attribute contexts, and
204+
arrange so that "ocaml.ppwarning" is correctly scoped by surrounding
205+
"ocaml.warning" attributes
206+
(Alain Frisch, review by ...)
207+
203208
### Manual and documentation:
204209

205210
- MPR#6548: remove obsolete limitation in the description of private
@@ -242,9 +247,9 @@ Working version
242247

243248
- GPR#1187: Minimal documentation for compiler plugins
244249
(Florian Angeletti)
245-
250+
246251
- GPR#1202: Fix Typos in comments as well as basic grammar errors.
247-
(JP Rodi, review and suggestions by David Allsopp, Max Mouratov,
252+
(JP Rodi, review and suggestions by David Allsopp, Max Mouratov,
248253
Florian Angeletti, Xavier Leroy, Mark Shinwell and Damien Doligez)
249254

250255
- GPR#1220: Fix "-keep-docs" option in ocamlopt manpage

parsing/builtin_attributes.ml

+6-25
Original file line numberDiff line numberDiff line change
@@ -117,30 +117,6 @@ let rec deprecated_of_str = function
117117
| _ -> None
118118

119119

120-
let emit_external_warnings =
121-
(* Note: this is run as a preliminary pass when type-checking an
122-
interface or implementation. This allows to cover all kinds of
123-
attributes, but the drawback is that it doesn't take local
124-
configuration of warnings (with '@@warning'/'@@warnerror'
125-
attributes) into account. We should rather check for
126-
'ppwarning' attributes during the actual type-checking, making
127-
sure to cover all contexts (easier and more ugly alternative:
128-
duplicate here the logic which control warnings locally). *)
129-
let open Ast_iterator in
130-
{
131-
default_iterator with
132-
attribute = (fun _ a ->
133-
match a with
134-
| {txt="ocaml.ppwarning"|"ppwarning"},
135-
PStr[{pstr_desc=Pstr_eval({pexp_desc=Pexp_constant
136-
(Pconst_string (s, _))},_);
137-
pstr_loc}] ->
138-
Location.prerr_warning pstr_loc (Warnings.Preprocessor s)
139-
| _ -> ()
140-
)
141-
}
142-
143-
144120
let warning_attribute =
145121
let process loc txt errflag payload =
146122
match string_of_payload payload with
@@ -161,13 +137,18 @@ let warning_attribute =
161137
process loc txt false payload
162138
| ({txt = ("ocaml.warnerror"|"warnerror") as txt; loc}, payload) ->
163139
process loc txt true payload
140+
| {txt="ocaml.ppwarning"|"ppwarning"},
141+
PStr[{pstr_desc=Pstr_eval({pexp_desc=Pexp_constant
142+
(Pconst_string (s, _))},_);
143+
pstr_loc}] ->
144+
Location.prerr_warning pstr_loc (Warnings.Preprocessor s)
164145
| _ ->
165146
()
166147

167148
let warning_scope attrs f =
168149
let prev = Warnings.backup () in
169150
try
170-
List.iter warning_attribute attrs;
151+
List.iter warning_attribute (List.rev attrs);
171152
let ret = f () in
172153
Warnings.restore prev;
173154
ret

parsing/builtin_attributes.mli

+4-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ val error_of_extension: Parsetree.extension -> Location.error
4747
val warning_attribute: Parsetree.attribute -> unit
4848
(** Apply warning settings from the specified attribute.
4949
"ocaml.warning"/"ocaml.warnerror" (and variants without the prefix)
50-
are processed and other attributes are ignored. *)
50+
are processed and other attributes are ignored.
51+
52+
Also implement ocaml.ppwarning.
53+
*)
5154

5255
val warning_scope: Parsetree.attributes -> (unit -> 'a) -> 'a
5356
(** Execute a function in a new scope for warning settings. This
@@ -60,8 +63,6 @@ val warning_scope: Parsetree.attributes -> (unit -> 'a) -> 'a
6063
is executed.
6164
*)
6265

63-
val emit_external_warnings: Ast_iterator.iterator
64-
6566
val warn_on_literal_pattern: Parsetree.attributes -> bool
6667
val explicit_arity: Parsetree.attributes -> bool
6768

testsuite/tests/typing-deprecated/deprecated.ml

+67
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,70 @@ Line _, characters 10-13:
415415
Warning 3: deprecated: X.t
416416
type t = [ `A of X.t | `B of X.s | `C of X.u ]
417417
|}]
418+
419+
420+
(* Test for ocaml.ppwarning, and its interactions with ocaml.warning *)
421+
422+
423+
[@@@ocaml.ppwarning "Pp warning!"]
424+
;;
425+
[%%expect{|
426+
Line _, characters 20-33:
427+
Warning 22: Pp warning!
428+
|}]
429+
430+
431+
let x = () [@ocaml.ppwarning "Pp warning 1!"]
432+
[@@ocaml.ppwarning "Pp warning 2!"]
433+
;;
434+
[%%expect{|
435+
Line _, characters 24-39:
436+
Warning 22: Pp warning 2!
437+
Line _, characters 29-44:
438+
Warning 22: Pp warning 1!
439+
val x : unit = ()
440+
|}]
441+
442+
type t = unit
443+
[@ocaml.ppwarning "Pp warning!"]
444+
;;
445+
[%%expect{|
446+
Line _, characters 22-35:
447+
Warning 22: Pp warning!
448+
type t = unit
449+
|}]
450+
451+
module X = struct
452+
[@@@ocaml.warning "-22"]
453+
454+
[@@@ocaml.ppwarning "Pp warning1!"]
455+
456+
[@@@ocaml.warning "+22"]
457+
458+
[@@@ocaml.ppwarning "Pp warning2!"]
459+
end
460+
;;
461+
[%%expect{|
462+
Line _, characters 22-36:
463+
Warning 22: Pp warning2!
464+
module X : sig end
465+
|}]
466+
467+
let x = ((() [@ocaml.ppwarning "Pp warning 1!"]) [@ocaml.warning "-22"]) [@ocaml.ppwarning "Pp warning 2!"]
468+
;;
469+
[%%expect{|
470+
Line _, characters 31-46:
471+
Warning 22: Pp warning 1!
472+
val x : unit = ()
473+
|}]
474+
475+
type t = ((unit [@ocaml.ppwarning "Pp warning 1!"]) [@ocaml.warning "-22"]) [@ocaml.ppwarning "Pp warning 2!"]
476+
[@@ocaml.ppwarning "Pp warning 3!"]
477+
;;
478+
[%%expect{|
479+
Line _, characters 21-36:
480+
Warning 22: Pp warning 3!
481+
Line _, characters 34-49:
482+
Warning 22: Pp warning 1!
483+
type t = unit
484+
|}]

typing/typemod.ml

-13
Original file line numberDiff line numberDiff line change
@@ -1515,10 +1515,6 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope =
15151515

15161516
let type_toplevel_phrase env s =
15171517
Env.reset_required_globals ();
1518-
begin
1519-
let iter = Builtin_attributes.emit_external_warnings in
1520-
iter.Ast_iterator.structure iter s
1521-
end;
15221518
let (str, sg, env) =
15231519
type_structure ~toplevel:true false None env s Location.none in
15241520
let (str, _coerce) = ImplementationHooks.apply_hooks
@@ -1628,11 +1624,6 @@ let type_implementation sourcefile outputprefix modulename initial_env ast =
16281624
try
16291625
Typecore.reset_delayed_checks ();
16301626
Env.reset_required_globals ();
1631-
begin
1632-
let iter = Builtin_attributes.emit_external_warnings in
1633-
iter.Ast_iterator.structure iter ast
1634-
end;
1635-
16361627
let (str, sg, finalenv) =
16371628
type_structure initial_env ast (Location.in_file sourcefile) in
16381629
let simple_sg = simplify_signature sg in
@@ -1700,10 +1691,6 @@ let save_signature modname tsg outputprefix source_file initial_env cmi =
17001691
(Cmt_format.Interface tsg) (Some source_file) initial_env (Some cmi)
17011692

17021693
let type_interface sourcefile env ast =
1703-
begin
1704-
let iter = Builtin_attributes.emit_external_warnings in
1705-
iter.Ast_iterator.signature iter ast
1706-
end;
17071694
InterfaceHooks.apply_hooks { Misc.sourcefile } (transl_signature env ast)
17081695

17091696
(* "Packaging" of several compilation units into one unit

0 commit comments

Comments
 (0)