Skip to content

Commit 37c0ed9

Browse files
committed
Ignore extensions inside attributes for the unused extension check
This means ppxlib doesn't emit a warning for code like `[@attr [%ext]]`. Previously, it would warn that `[%ext]` wasn't translated, however this is essentially always not the desired behaviour; the ppx that interprets the attribute will be called before the one that interprets the extension (assuming context free ppxes) so the attribute handling will have to handle the extension itself. If the attribute substitues the extension into generated code the warning will still trigger if that substituted extension point isn't expanded. I'm slightly nervous this will cause weird errors if you put extensions inside the payload of builtin attributes, however I don't think there are any that can have an extension in their payload so it's probably fine. Signed-off-by: Jack Rickard <jrickard@janestreet.com>
1 parent 18c0c1c commit 37c0ed9

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

src/extension.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ let collect_unhandled_extension_errors =
324324
"extension not expected here, Ppxlib.Extension needs updating!";
325325
]
326326

327+
(* Skip extensions in attributes, they will be handled by the PPX that
328+
handles each specific attribute. *)
329+
method! attribute _x acc = acc
330+
327331
method! core_type_desc x acc =
328332
match x with
329333
| Ptyp_extension ext -> acc @ unhandled_extension_error Core_type ext

test/driver/attributes/test.ml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,28 @@ let e = [%flag_ghost "bye" [@flag]]
262262
[%%expect{|
263263
val e : string * string = ("bye", "bye")
264264
|}]
265+
266+
(* Test extensions aren't flagged as unused inside attributes. *)
267+
268+
let () =
269+
let attr =
270+
Attribute.declare
271+
"ignore_me"
272+
Attribute.Context.core_type
273+
Ast_pattern.(__)
274+
ignore
275+
in
276+
let ext =
277+
Extension.V3.declare
278+
"ignore_me"
279+
Core_type
280+
Ast_pattern.(ptyp __)
281+
(fun ~ctxt:_ e -> let (_ : unit option) = Attribute.get attr e in e)
282+
in
283+
Driver.register_transformation "ignore_me" ~rules:[ Context_free.Rule.extension ext ]
284+
;;
285+
286+
type t = [%ignore_me: int[@ignore_me [%doesn't_exist]]]
287+
[%%expect{|
288+
type t = int
289+
|}]

0 commit comments

Comments
 (0)