Skip to content

Commit

Permalink
Erase global_ by moving the modality to a [@globalized] attribute (
Browse files Browse the repository at this point in the history
  • Loading branch information
dvulakh authored Jan 14, 2025
1 parent 9b29b6b commit 35aaa33
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 11 deletions.
39 changes: 39 additions & 0 deletions lib/Normalize_std_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ let is_doc = function
| {attr_name= {Location.txt= "ocaml.doc" | "ocaml.text"; _}; _} -> true
| _ -> false

let globalized_attr =
Ast_helper.Attr.mk ~loc:Location.none
(Location.mknoloc "globalized")
(PStr [])

(* We rewrite both "[@immediate]" and "[@ocaml.immediate]" into ":
immediate", which is then turned into just "[@immediate]" if we are
erasing jane syntax. This means "[@ocaml.immediate]" get rewritten to
Expand Down Expand Up @@ -478,6 +483,38 @@ let make_mapper conf ~ignore_doc_comments ~erase_jane_syntax =
else ext )
|> Ast_mapper.default_mapper.extension_constructor m
in
let label_declaration (m : Ast_mapper.mapper) ld =
(* CR modes: Develop a more general mechanism for "erasing" modalities
into attributes *)
let global__ =
List.exists ld.pld_modalities ~f:(function
| {Location.txt= Modality "global"; _} -> true
| {txt= Modality _; _} -> false )
in
let ld = Ast_mapper.default_mapper.label_declaration m ld in
{ ld with
pld_attributes=
( if erase_jane_syntax && global__ then
globalized_attr :: ld.pld_attributes
else ld.pld_attributes ) }
in
let constructor_argument (m : Ast_mapper.mapper) ca =
(* CR modes: Develop a more general mechanism for "erasing" modalities
into attributes *)
let global__ =
List.exists ca.pca_modalities ~f:(function
| {Location.txt= Modality "global"; _} -> true
| {txt= Modality _; _} -> false )
in
let ca = Ast_mapper.default_mapper.constructor_argument m ca in
{ ca with
pca_type=
( if erase_jane_syntax && global__ then
{ ca.pca_type with
ptyp_attributes= globalized_attr :: ca.pca_type.ptyp_attributes
}
else ca.pca_type ) }
in
{ Ast_mapper.default_mapper with
location
; attribute
Expand All @@ -486,10 +523,12 @@ let make_mapper conf ~ignore_doc_comments ~erase_jane_syntax =
; signature
; class_signature
; class_structure
; constructor_argument
; expr
; pat
; typ
; type_declaration
; label_declaration
; modes
; modalities
; value_binding
Expand Down
7 changes: 5 additions & 2 deletions test/passing/tests/local_erased.ml.ref
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ let f () =
let () = g (fun () -> ()) in
"asdfasdfasdfasdfasdfasdfasdf"

type 'a r = {mutable a: 'a; b: 'a; c: 'a}
type 'a r = {mutable a: 'a; b: 'a; c: 'a [@globalized]}

type 'a r = Foo of 'a | Bar of 'a * 'a | Baz of int * string * 'a
type 'a r =
| Foo of ('a[@globalized])
| Bar of 'a * ('a[@globalized])
| Baz of (int[@globalized]) * string * ('a[@globalized])

type ('a, 'b) cfn = a:'a -> ?b:b -> 'a -> int -> 'b

Expand Down
12 changes: 8 additions & 4 deletions test/passing/tests/modes-erased.ml.ref
Original file line number Diff line number Diff line change
Expand Up @@ -370,15 +370,19 @@ module Interaction_with_existing_syntax = struct

(* modalities on record fields *)

type t = {x: t}
type t = {x: t [@globalized]}

type t = A of {x: t}
type t = A of {x: t [@globalized]}

(* modalities on constructor arguments *)

type t = A of typ | B of typ1 * typ2
type t =
| A of (typ[@globalized])
| B of (typ1[@globalized]) * (typ2[@globalized])

type t = A : typ -> t | B : typ1 * typ2 -> t
type t =
| A : (typ[@globalized]) -> t
| B : (typ1[@globalized]) * (typ2[@globalized]) -> t
end

module Regressions = struct
Expand Down
18 changes: 14 additions & 4 deletions vendor/parser-extended/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -280,18 +280,28 @@ let global_loc = mknoloc "extension.global"
let global_attr =
Attr.mk ~loc:Location.none (global_loc) (PStr [])

let globalized_attr = Attr.mk ~loc:Location.none (mknoloc "globalized") (PStr [])

let mkld_global ld =
if Erase_jane_syntax.should_erase () then ld else
{ ld with pld_attributes = global_attr :: ld.pld_attributes }
let attr =
if Erase_jane_syntax.should_erase ()
then globalized_attr
else global_attr
in
{ ld with pld_attributes = attr :: ld.pld_attributes }

let mkld_global_maybe gbl ld =
match gbl with
| Global -> mkld_global ld
| Nothing -> ld

let mkcty_global cty =
if Erase_jane_syntax.should_erase () then cty else
{ cty with ptyp_attributes = global_attr :: cty.ptyp_attributes }
let attr =
if Erase_jane_syntax.should_erase ()
then globalized_attr
else global_attr
in
{ cty with ptyp_attributes = attr :: cty.ptyp_attributes }

let mkcty_global_maybe gbl cty =
match gbl with
Expand Down
5 changes: 4 additions & 1 deletion vendor/parser-standard/ast_mapper.ml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type mapper = {
constant: mapper -> constant -> constant;
constructor_declaration: mapper -> constructor_declaration
-> constructor_declaration;
constructor_argument: mapper -> constructor_argument -> constructor_argument;
directive_argument: mapper -> directive_argument -> directive_argument;
expr: mapper -> expression -> expression;
extension: mapper -> extension -> extension;
Expand Down Expand Up @@ -234,7 +235,7 @@ module T = struct
{ pca_type; pca_loc; pca_modalities }

let map_constructor_arguments sub = function
| Pcstr_tuple l -> Pcstr_tuple (List.map (map_constructor_argument sub) l)
| Pcstr_tuple l -> Pcstr_tuple (List.map (sub.constructor_argument sub) l)
| Pcstr_record l ->
Pcstr_record (List.map (sub.label_declaration sub) l)

Expand Down Expand Up @@ -896,6 +897,8 @@ let default_mapper =
~info:Docstrings.empty_info
);

constructor_argument = T.map_constructor_argument;

label_declaration =
(fun this {pld_name; pld_type; pld_loc; pld_mutable; pld_modalities; pld_attributes} ->
Type.field
Expand Down

0 comments on commit 35aaa33

Please sign in to comment.