Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
677822d
migrate wip
zth Aug 24, 2025
663ef1a
wip migrate
zth Aug 25, 2025
c994f7b
pipe chain example
zth Aug 25, 2025
a6e3af7
migrations for Js_option
zth Aug 28, 2025
89d3015
migrations for Js_null
zth Aug 28, 2025
abfbdc7
rename migration template for pipe chains
zth Aug 28, 2025
9e76d0f
migrations for Js_null_undefined
zth Aug 28, 2025
4e27a20
js_float migrations
zth Aug 28, 2025
aaa668d
Js_int migrations
zth Aug 28, 2025
ffc960a
format
zth Aug 28, 2025
8523d22
dict migrations
zth Aug 28, 2025
7a25a64
migrations for Js_date
zth Aug 29, 2025
9116fcd
migrations for Js_re
zth Aug 29, 2025
990d89f
migrations for Js_math
zth Aug 29, 2025
9b83514
one more test
zth Aug 29, 2025
08555bf
migrations for js_undefined
zth Aug 30, 2025
d04aba6
deprecate Js_OO
zth Aug 30, 2025
b0bfe1f
migrations for Js_extern
zth Aug 30, 2025
80cbefe
migrations for Js_global
zth Aug 30, 2025
81ea287
migrations for Js_obj
zth Aug 30, 2025
b6e3570
make parsing of @deprecated with migration info an experimental feature
zth Aug 30, 2025
b2e0bdc
Revert "make parsing of @deprecated with migration info an experiment…
zth Aug 31, 2025
a5834db
typed array migrations
zth Aug 31, 2025
dfe4425
format
zth Aug 31, 2025
84e04c7
support replacing types
zth Aug 31, 2025
1cc2b54
more type replacement migrations
zth Aug 31, 2025
c36e4fa
support @apply.transforms for applying transforms, and add migrations…
zth Aug 31, 2025
4862be9
refactor a bit and add transform for dropping unit args in apply
zth Aug 31, 2025
ff36697
refactor
zth Aug 31, 2025
e78f030
finish js_json migration
zth Sep 1, 2025
9be8a97
more migrations
zth Sep 1, 2025
6d1169d
remove unused Match template
zth Sep 1, 2025
1b4f4be
more migrations
zth Sep 4, 2025
82c3b52
update test fixtures
zth Sep 4, 2025
deb56cb
update test fixtures
zth Sep 4, 2025
866eea7
more fixtures
zth Sep 4, 2025
d95b2a7
remove
zth Sep 4, 2025
cd5e1a3
more
zth Sep 4, 2025
cfd915a
more
zth Sep 4, 2025
d8cc568
migrate .resi files as well
zth Sep 4, 2025
c5cce74
fix resi
zth Sep 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ Do not use, npm package broken.

- Add optional `message` argument to `Result.getOrThrow` and improve default error message. https://github.com/rescript-lang/rescript/pull/7630
- Add `RegExp.escape` binding. https://github.com/rescript-lang/rescript/pull/7695
- Add `Array.fromString`. https://github.com/rescript-lang/rescript/pull/7693

#### :bug: Bug fix

Expand All @@ -183,6 +184,7 @@ Do not use, npm package broken.
- Suggest related functions with the expected arity in errors when it makes sense. https://github.com/rescript-lang/rescript/pull/7712
- Improve error when a constructor expects an inline record. https://github.com/rescript-lang/rescript/pull/7713
- Remove `@meth` attribute. https://github.com/rescript-lang/rescript/pull/7684
> > > > > > > 00815832f (changelog)

#### :house: Internal

Expand Down
14 changes: 14 additions & 0 deletions analysis/src/Cmt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,17 @@ let fullsFromModule ~package ~moduleName =
let loadFullCmtFromPath ~path =
let uri = Uri.fromPath path in
fullFromUri ~uri

let loadCmtInfosFromPath ~path =
let uri = Uri.fromPath path in
match Packages.getPackage ~uri with
| None -> None
| Some package -> (
let moduleName =
BuildSystem.namespacedName package.namespace (FindFiles.getName path)
in
match Hashtbl.find_opt package.pathsForModule moduleName with
| Some paths ->
let cmt = getCmtPath ~uri paths in
Shared.tryReadCmt cmt
| None -> None)
4 changes: 4 additions & 0 deletions compiler/ext/ext_list.ml
Original file line number Diff line number Diff line change
Expand Up @@ -774,3 +774,7 @@ let filter lst p =
| x :: l -> if p x then find (x :: accu) l ~p else find accu l ~p
in
find [] lst ~p

let is_empty = function
| [] -> true
| _ :: _ -> false
2 changes: 2 additions & 0 deletions compiler/ext/ext_list.mli
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,5 @@ val filter : 'a list -> ('a -> bool) -> 'a list

val array_list_filter_map :
'a array -> 'b list -> ('a -> 'b -> 'c option) -> 'c list

val is_empty : 'a list -> bool
56 changes: 53 additions & 3 deletions compiler/ml/builtin_attributes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,60 @@ let rec deprecated_of_attrs = function
Some (string_of_opt_payload p)
| _ :: tl -> deprecated_of_attrs tl

let check_deprecated loc attrs s =
match deprecated_of_attrs attrs with
let rec deprecated_of_attrs_with_migrate = function
| [] -> None
| ( {txt = "deprecated"; _},
PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_record (fields, _)}, _)}]
)
:: _ -> (
let reason =
fields
|> List.find_map (fun field ->
match field with
| {
lid = {txt = Lident "reason"};
x = {pexp_desc = Pexp_constant (Pconst_string (reason, _))};
} ->
Some reason
| _ -> None)
in
let migration_template =
fields
|> List.find_map (fun field ->
match field with
| {lid = {txt = Lident "migrate"}; x = migration_template} ->
Some migration_template
| _ -> None)
in
let migration_in_pipe_chain_template =
fields
|> List.find_map (fun field ->
match field with
| {
lid = {txt = Lident "migrateInPipeChain"};
x = migration_in_pipe_chain_template;
} ->
Some migration_in_pipe_chain_template
| _ -> None)
in

(* TODO: Validate and error if expected shape mismatches *)
match reason with
| Some reason ->
Some (reason, migration_template, migration_in_pipe_chain_template)
| None -> None)
| ({txt = "ocaml.deprecated" | "deprecated"; _}, p) :: _ ->
Some (string_of_opt_payload p, None, None)
| _ :: tl -> deprecated_of_attrs_with_migrate tl

let check_deprecated ?deprecated_context loc attrs s =
match deprecated_of_attrs_with_migrate attrs with
| None -> ()
| Some txt -> Location.deprecated loc (cat s txt)
| Some (txt, migration_template, migration_in_pipe_chain_template) ->
!Cmt_utils.record_deprecated_used
?deprecated_context ?migration_template ?migration_in_pipe_chain_template
loc txt;
Location.deprecated loc (cat s txt)

let check_deprecated_inclusion ~def ~use loc attrs1 attrs2 s =
match (deprecated_of_attrs attrs1, deprecated_of_attrs attrs2) with
Expand Down
7 changes: 6 additions & 1 deletion compiler/ml/builtin_attributes.mli
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@
ocaml.boxed / ocaml.unboxed
*)

val check_deprecated : Location.t -> Parsetree.attributes -> string -> unit
val check_deprecated :
?deprecated_context:Cmt_utils.deprecated_used_context ->
Location.t ->
Parsetree.attributes ->
string ->
unit
val check_deprecated_inclusion :
def:Location.t ->
use:Location.t ->
Expand Down
21 changes: 19 additions & 2 deletions compiler/ml/cmt_format.ml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type cmt_infos = {
cmt_imports : (string * Digest.t option) list;
cmt_interface_digest : Digest.t option;
cmt_use_summaries : bool;
cmt_extra_info: Cmt_utils.cmt_extra_info;
}

type error =
Expand Down Expand Up @@ -154,15 +155,30 @@ let read_cmi filename =

let saved_types = ref []
let value_deps = ref []
let deprecated_used = ref []

let clear () =
saved_types := [];
value_deps := []
value_deps := [];
deprecated_used := []

let add_saved_type b = saved_types := b :: !saved_types
let get_saved_types () = !saved_types
let set_saved_types l = saved_types := l

let record_deprecated_used ?deprecated_context ?migration_template ?migration_in_pipe_chain_template source_loc deprecated_text =
deprecated_used :=
{
Cmt_utils.source_loc;
deprecated_text;
migration_template;
migration_in_pipe_chain_template;
context = deprecated_context;
}
:: !deprecated_used

let _ = Cmt_utils.record_deprecated_used := record_deprecated_used

let record_value_dependency vd1 vd2 =
if vd1.Types.val_loc <> vd2.Types.val_loc then
value_deps := (vd1, vd2) :: !value_deps
Expand Down Expand Up @@ -197,8 +213,9 @@ let save_cmt filename modname binary_annots sourcefile initial_env cmi =
cmt_imports = List.sort compare (Env.imports ());
cmt_interface_digest = this_crc;
cmt_use_summaries = need_to_clear_env;
cmt_extra_info = {deprecated_used = !deprecated_used};
} in
output_cmt oc cmt)
end;
clear ()
#endif
#endif
9 changes: 9 additions & 0 deletions compiler/ml/cmt_format.mli
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type cmt_infos = {
cmt_imports: (string * Digest.t option) list;
cmt_interface_digest: Digest.t option;
cmt_use_summaries: bool;
cmt_extra_info: Cmt_utils.cmt_extra_info;
}

type error = Not_a_typedtree of string
Expand Down Expand Up @@ -111,6 +112,14 @@ val set_saved_types : binary_part list -> unit
val record_value_dependency :
Types.value_description -> Types.value_description -> unit

val record_deprecated_used :
?deprecated_context:Cmt_utils.deprecated_used_context ->
?migration_template:Parsetree.expression ->
?migration_in_pipe_chain_template:Parsetree.expression ->
Location.t ->
string ->
unit

(*

val is_magic_number : string -> bool
Expand Down
31 changes: 31 additions & 0 deletions compiler/ml/cmt_utils.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
type deprecated_used_context = FunctionCall | Reference

type deprecated_used = {
source_loc: Location.t;
deprecated_text: string;
migration_template: Parsetree.expression option;
migration_in_pipe_chain_template: Parsetree.expression option;
context: deprecated_used_context option;
}

type cmt_extra_info = {deprecated_used: deprecated_used list}

let record_deprecated_used :
(?deprecated_context:deprecated_used_context ->
?migration_template:Parsetree.expression ->
?migration_in_pipe_chain_template:Parsetree.expression ->
Location.t ->
string ->
unit)
ref =
ref
(fun
?deprecated_context
?migration_template
?migration_in_pipe_chain_template
_
_
->
ignore deprecated_context;
ignore migration_template;
ignore migration_in_pipe_chain_template)
27 changes: 19 additions & 8 deletions compiler/ml/typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2246,17 +2246,18 @@ type lazy_args =
(Asttypes.Noloc.arg_label * (unit -> Typedtree.expression) option) list

type targs = (Asttypes.Noloc.arg_label * Typedtree.expression option) list
let rec type_exp ~context ?recarg env sexp =
let rec type_exp ?deprecated_context ~context ?recarg env sexp =
(* We now delegate everything to type_expect *)
type_expect ~context ?recarg env sexp (newvar ())
type_expect ?deprecated_context ~context ?recarg env sexp (newvar ())

(* Typing of an expression with an expected type.
This provide better error messages, and allows controlled
propagation of return type information.
In the principal case, [type_expected'] may be at generic_level.
*)

and type_expect ~context ?in_function ?recarg env sexp ty_expected =
and type_expect ~context ?deprecated_context ?in_function ?recarg env sexp
ty_expected =
(* Special errors for braced identifiers passed to records *)
let context =
match sexp.pexp_desc with
Expand All @@ -2271,14 +2272,15 @@ and type_expect ~context ?in_function ?recarg env sexp ty_expected =
let previous_saved_types = Cmt_format.get_saved_types () in
let exp =
Builtin_attributes.warning_scope sexp.pexp_attributes (fun () ->
type_expect_ ~context ?in_function ?recarg env sexp ty_expected)
type_expect_ ?deprecated_context ~context ?in_function ?recarg env sexp
ty_expected)
in
Cmt_format.set_saved_types
(Cmt_format.Partial_expression exp :: previous_saved_types);
exp

and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected
=
and type_expect_ ?deprecated_context ~context ?in_function ?(recarg = Rejected)
env sexp ty_expected =
let loc = sexp.pexp_loc in
(* Record the expression type before unifying it with the expected type *)
let rue exp =
Expand All @@ -2295,7 +2297,14 @@ and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected
in
match sexp.pexp_desc with
| Pexp_ident lid ->
let path, desc = Typetexp.find_value env lid.loc lid.txt in
let path, desc =
Typetexp.find_value
?deprecated_context:
(match deprecated_context with
| None -> Some Reference
| v -> v)
env lid.loc lid.txt
in
(if !Clflags.annotations then
let dloc = desc.Types.val_loc in
let annot =
Expand Down Expand Up @@ -2433,7 +2442,9 @@ and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected
assert (sargs <> []);
begin_def ();
(* one more level for non-returning functions *)
let funct = type_exp ~context:None env sfunct in
let funct =
type_exp ~deprecated_context:FunctionCall ~context:None env sfunct
in
let ty = instance env funct.exp_type in
end_def ();
wrap_trace_gadt_instances env (lower_args env []) ty;
Expand Down
8 changes: 5 additions & 3 deletions compiler/ml/typetexp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ let find_type env loc lid =
env loc lid
in
let decl = Env.find_type path env in
Builtin_attributes.check_deprecated loc decl.type_attributes (Path.name path);
Builtin_attributes.check_deprecated ~deprecated_context:Cmt_utils.Reference
loc decl.type_attributes (Path.name path);
(path, decl)

let find_constructor =
Expand All @@ -131,12 +132,13 @@ let find_all_constructors =
let find_all_labels =
find_component Env.lookup_all_labels (fun lid -> Unbound_label (lid, None))

let find_value env loc lid =
let find_value ?deprecated_context env loc lid =
Env.check_value_name (Longident.last lid) loc;
let ((path, decl) as r) =
find_component Env.lookup_value (fun lid -> Unbound_value lid) env loc lid
in
Builtin_attributes.check_deprecated loc decl.val_attributes (Path.name path);
Builtin_attributes.check_deprecated ?deprecated_context loc
decl.val_attributes (Path.name path);
r

let lookup_module ?(load = false) env loc lid =
Expand Down
6 changes: 5 additions & 1 deletion compiler/ml/typetexp.mli
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ val find_all_labels :
Longident.t ->
(label_description * (unit -> unit)) list
val find_value :
Env.t -> Location.t -> Longident.t -> Path.t * value_description
?deprecated_context:Cmt_utils.deprecated_used_context ->
Env.t ->
Location.t ->
Longident.t ->
Path.t * value_description
val find_module :
Env.t -> Location.t -> Longident.t -> Path.t * module_declaration
val lookup_module : ?load:bool -> Env.t -> Location.t -> Longident.t -> Path.t
Expand Down
40 changes: 35 additions & 5 deletions packages/@rescript/runtime/Js.res
Original file line number Diff line number Diff line change
Expand Up @@ -203,16 +203,46 @@ external undefined: undefined<'a> = "%undefined"
external typeof: 'a => string = "%typeof"

/** Equivalent to console.log any value. */
@val @scope("console")
@deprecated({
reason: "Use `Console.log` instead.",
migrate: Console.log(),
})
@val
@scope("console")
external log: 'a => unit = "log"

@val @scope("console") external log2: ('a, 'b) => unit = "log"
@val @scope("console") external log3: ('a, 'b, 'c) => unit = "log"
@deprecated({
reason: "Use `Console.log2` instead.",
migrate: Console.log2(),
})
@val
@scope("console")
external log2: ('a, 'b) => unit = "log"

@deprecated({
reason: "Use `Console.log3` instead.",
migrate: Console.log3(),
})
@val
@scope("console")
external log3: ('a, 'b, 'c) => unit = "log"

@val @scope("console") external log4: ('a, 'b, 'c, 'd) => unit = "log"
@deprecated({
reason: "Use `Console.log4` instead.",
migrate: Console.log4(),
})
@val
@scope("console")
external log4: ('a, 'b, 'c, 'd) => unit = "log"

/** A convenience function to console.log more than 4 arguments */
@val @scope("console") @variadic
@deprecated({
reason: "Use `Console.logMany` instead.",
migrate: Console.logMany(),
})
@val
@scope("console")
@variadic
external logMany: array<'a> => unit = "log"

external eqNull: ('a, null<'a>) => bool = "%equal_null"
Expand Down
Loading
Loading