Skip to content

Hide Stdlib in output #7305

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#### :nail_care: Polish

- Deprecate JSON.Classify.classify. https://github.com/rescript-lang/rescript/pull/7315
- Hide stdlib modules in output. https://github.com/rescript-lang/rescript/pull/7305

#### :bug: Bug fix

Expand Down
16 changes: 12 additions & 4 deletions compiler/ml/printtyp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,32 @@ let ident ppf id = pp_print_string ppf (ident_name id)
(* Print a path *)

let ident_pervasives = Ident.create_persistent "Pervasives"
let ident_stdlib = Ident.create_persistent "Stdlib"
let printing_env = ref Env.empty
let non_shadowed_pervasive = function
let non_shadowed_pervasive_or_stdlib = function
| Pdot (Pident id, s, _pos) as path -> (
Ident.same id ident_pervasives
(Ident.same id ident_pervasives || Ident.same id ident_stdlib)
&&
try Path.same path (Env.lookup_type (Lident s) !printing_env)
with Not_found -> true)
| _ -> false

let rec tree_of_path = function
| Pident id -> Oide_ident (ident_name id)
| Pdot (_, s, _pos) as path when non_shadowed_pervasive path -> Oide_ident s
| Pdot (_, s, _pos) as path when non_shadowed_pervasive_or_stdlib path ->
Oide_ident s
| Pdot (p, s, _pos) when String.starts_with (Path.name p) ~prefix:"Stdlib_" ->
let path_name = Path.name p in
let ident_without_stdlib_prefix =
String.sub path_name 7 (String.length path_name - 7)
in
Oide_dot (Oide_ident ident_without_stdlib_prefix, s)
Comment on lines -66 to +74
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could list all Stdlib_* with proper idents here if we wanted..? Instead of doing a string match.

There's also the question of whether stdlib types should be dug to when possible (Date.t -> date), but that's probably a separate question from this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And especially Promise.t -> promise as that's a built-in type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a much better example, especially since date does not exist 🤦 😄

| Pdot (p, s, _pos) -> Oide_dot (tree_of_path p, s)
| Papply (p1, p2) -> Oide_apply (tree_of_path p1, tree_of_path p2)

let rec path ppf = function
| Pident id -> ident ppf id
| Pdot (_, s, _pos) as path when non_shadowed_pervasive path ->
| Pdot (_, s, _pos) as path when non_shadowed_pervasive_or_stdlib path ->
pp_print_string ppf s
| Pdot (p, s, _pos) ->
path ppf p;
Expand Down
14 changes: 7 additions & 7 deletions tests/analysis_tests/tests/src/expected/Completion.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,13 @@ Path Array.
"label": "getSymbol",
"kind": 12,
"tags": [],
"detail": "(array<'a>, Stdlib_Symbol.t) => option<'b>",
"detail": "(array<'a>, Symbol.t) => option<'b>",
"documentation": null
}, {
"label": "getSymbolUnsafe",
"kind": 12,
"tags": [],
"detail": "(array<'a>, Stdlib_Symbol.t) => 'b",
"detail": "(array<'a>, Symbol.t) => 'b",
"documentation": null
}, {
"label": "findIndexOpt",
Expand Down Expand Up @@ -218,7 +218,7 @@ Path Array.
"label": "sort",
"kind": 12,
"tags": [],
"detail": "(array<'a>, ('a, 'a) => Stdlib_Ordering.t) => unit",
"detail": "(array<'a>, ('a, 'a) => Ordering.t) => unit",
"documentation": {"kind": "markdown", "value": "\n`sort(array, comparator)` sorts `array` in-place using the `comparator` function.\n\nBeware this will *mutate* the array.\n\nSee [`Array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) on MDN.\n\n## Examples\n\n```rescript\nlet array = [3, 2, 1]\narray->Array.sort((a, b) => float(a - b))\narray->assertEqual([1, 2, 3])\n```\n"}
}, {
"label": "length",
Expand Down Expand Up @@ -326,7 +326,7 @@ Path Array.
"label": "compare",
"kind": 12,
"tags": [],
"detail": "(\n array<'a>,\n array<'a>,\n ('a, 'a) => Stdlib_Ordering.t,\n) => Stdlib_Ordering.t",
"detail": "(array<'a>, array<'a>, ('a, 'a) => Ordering.t) => Ordering.t",
"documentation": null
}, {
"label": "join",
Expand Down Expand Up @@ -404,7 +404,7 @@ Path Array.
"label": "setSymbol",
"kind": 12,
"tags": [],
"detail": "(array<'a>, Stdlib_Symbol.t, 'b) => unit",
"detail": "(array<'a>, Symbol.t, 'b) => unit",
"documentation": null
}, {
"label": "equal",
Expand Down Expand Up @@ -458,7 +458,7 @@ Path Array.
"label": "toSorted",
"kind": 12,
"tags": [],
"detail": "(array<'a>, ('a, 'a) => Stdlib_Ordering.t) => array<'a>",
"detail": "(array<'a>, ('a, 'a) => Ordering.t) => array<'a>",
"documentation": {"kind": "markdown", "value": "\n`toSorted(array, comparator)` returns a new, sorted array from `array`, using the `comparator` function.\n\nSee [`Array.toSorted`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [3, 2, 1]\n\nsomeArray\n->Array.toSorted(Int.compare)\n->assertEqual([1, 2, 3])\n\nsomeArray->assertEqual([3, 2, 1]) // Original unchanged\n```\n"}
}, {
"label": "reduceWithIndex",
Expand Down Expand Up @@ -518,7 +518,7 @@ Path Array.
"label": "fromIterator",
"kind": 12,
"tags": [],
"detail": "Stdlib_Iterator.t<'a> => array<'a>",
"detail": "Iterator.t<'a> => array<'a>",
"documentation": {"kind": "markdown", "value": "\n`fromIterator(iterator)`\n\nCreates an array from the provided `iterator`\n\n## Examples\n\n```rescript\nMap.fromArray([(\"foo\", 1), (\"bar\", 2)])\n->Map.values\n->Array.fromIterator\n->assertEqual([1, 2])\n```\n"}
}, {
"label": "forEach",
Expand Down
14 changes: 7 additions & 7 deletions tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ Path Stdlib.Int.
"label": "Int.compare",
"kind": 12,
"tags": [],
"detail": "(int, int) => Stdlib_Ordering.t",
"detail": "(int, int) => Ordering.t",
"documentation": null
}, {
"label": "Int.toPrecision",
Expand Down Expand Up @@ -387,7 +387,7 @@ Path Stdlib.Int.
"label": "Int.compare",
"kind": 12,
"tags": [],
"detail": "(int, int) => Stdlib_Ordering.t",
"detail": "(int, int) => Ordering.t",
"documentation": null
}, {
"label": "Int.toPrecision",
Expand Down Expand Up @@ -751,7 +751,7 @@ Path Stdlib.String.s
"label": "->String.searchOpt",
"kind": 12,
"tags": [],
"detail": "(string, Stdlib_RegExp.t) => option<int>",
"detail": "(string, RegExp.t) => option<int>",
"documentation": {"kind": "markdown", "value": "\n`searchOpt(str, regexp)`. Like `search`, but return an `option<int>`.\n\n## Examples\n\n```rescript\nString.searchOpt(\"testing 1 2 3\", %re(\"/\\d+/\")) == Some(8)\nString.searchOpt(\"no numbers\", %re(\"/\\d+/\")) == None\n```\n"},
"sortText": "searchOpt",
"insertText": "->String.searchOpt",
Expand All @@ -763,7 +763,7 @@ Path Stdlib.String.s
"label": "->String.splitByRegExpAtMost",
"kind": 12,
"tags": [],
"detail": "(\n string,\n Stdlib_RegExp.t,\n ~limit: int,\n) => array<option<string>>",
"detail": "(string, RegExp.t, ~limit: int) => array<option<string>>",
"documentation": {"kind": "markdown", "value": "\n`splitByRegExpAtMost(str, regexp, ~limit)` splits the given `str` at every\noccurrence of `regexp` and returns an array of the first `limit` resulting\nsubstrings. If `limit` is negative or greater than the number of substrings, the\narray will contain all the substrings.\nSee [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) on MDN.\n\n## Examples\n\n```rescript\nString.splitByRegExpAtMost(\"Hello World. How are you doing?\", %re(\"/ /\"), ~limit=3) == [\n Some(\"Hello\"),\n Some(\"World.\"),\n Some(\"How\"),\n]\n```\n"},
"sortText": "splitByRegExpAtMost",
"insertText": "->String.splitByRegExpAtMost",
Expand Down Expand Up @@ -799,7 +799,7 @@ Path Stdlib.String.s
"label": "->String.setSymbol",
"kind": 12,
"tags": [],
"detail": "(string, Stdlib_Symbol.t, 'a) => unit",
"detail": "(string, Symbol.t, 'a) => unit",
"documentation": null,
"sortText": "setSymbol",
"insertText": "->String.setSymbol",
Expand All @@ -811,7 +811,7 @@ Path Stdlib.String.s
"label": "->String.splitByRegExp",
"kind": 12,
"tags": [],
"detail": "(string, Stdlib_RegExp.t) => array<option<string>>",
"detail": "(string, RegExp.t) => array<option<string>>",
"documentation": {"kind": "markdown", "value": "\n`splitByRegExp(str, regexp)` splits the given `str` at every occurrence of\n`regexp` and returns an array of the resulting substrings.\nSee [`String.split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split) on MDN.\n\n## Examples\n\n```rescript\nString.splitByRegExp(\"Jan,Feb,Mar\", %re(\"/,/\")) == [Some(\"Jan\"), Some(\"Feb\"), Some(\"Mar\")]\n```\n"},
"sortText": "splitByRegExp",
"insertText": "->String.splitByRegExp",
Expand Down Expand Up @@ -859,7 +859,7 @@ Path Stdlib.String.s
"label": "->String.search",
"kind": 12,
"tags": [],
"detail": "(string, Stdlib_RegExp.t) => int",
"detail": "(string, RegExp.t) => int",
"documentation": {"kind": "markdown", "value": "\n`search(str, regexp)` returns the starting position of the first match of\n`regexp` in the given `str`, or -1 if there is no match.\nSee [`String.search`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search) on MDN.\n\n## Examples\n\n```rescript\nString.search(\"testing 1 2 3\", %re(\"/\\d+/\")) == 8\nString.search(\"no numbers\", %re(\"/\\d+/\")) == -1\n```\n"},
"sortText": "search",
"insertText": "->String.search",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Path date
"label": "None",
"kind": 12,
"tags": [],
"detail": "Stdlib.Date.t",
"detail": "Date.t",
"documentation": {"kind": "markdown", "value": "\nA type representing a JavaScript date.\n"}
}, {
"label": "Some(_)",
"kind": 12,
"tags": [],
"detail": "Stdlib.Date.t",
"detail": "Date.t",
"documentation": {"kind": "markdown", "value": "\nA type representing a JavaScript date.\n"},
"insertText": "Some(${1:_})",
"insertTextFormat": 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ module type FT = {
let make: (~name: string) => React.element
}
}
module NormaList = Stdlib.List
module NormaList = List
module BeltList = Belt.List
module type MT2 = ModTyp
module rec RM: ModTyp
Expand Down
2 changes: 1 addition & 1 deletion tests/analysis_tests/tests/src/expected/Firebase.res.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Path Firebase.Firestore.
"label": "->Firestore.getDoc",
"kind": 12,
"tags": [],
"detail": "documentReference<\n 'documentdata,\n> => Stdlib.Promise.t<documentSnapshot<'documentdata>>",
"detail": "documentReference<\n 'documentdata,\n> => Promise.t<documentSnapshot<'documentdata>>",
"documentation": null,
"sortText": "getDoc",
"insertText": "->Firestore.getDoc",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

We've found a bug for you!
/.../fixtures/stdlib_removed_in_error.res:3:12-42

1 │ type x = Stdlib.Promise.t<int>
2 │
3 │ let x: x = Stdlib.Promise.resolve("hello")
4 │

This has type: Promise.t<string> (defined as promise<string>)
But it's expected to have type: x (defined as promise<int>)

The incompatible parts:
string vs int

You can convert string to int with Belt.Int.fromString.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type x = Stdlib.Promise.t<int>

let x: x = Stdlib.Promise.resolve("hello")