Skip to content

Conversation

richard-viney
Copy link
Contributor

This PR adds a warning when targeting JavaScript and Int literals or constants outside JavaScript's safe range are encountered.

Fixes #3746.

@richard-viney richard-viney marked this pull request as ready for review October 31, 2024 23:51
Copy link
Member

@lpil lpil left a comment

Choose a reason for hiding this comment

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

Very nice! Thank you

.warning(Warning::JavaScriptIntUnsafe { location });
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Seeing as we want to use the int values in a few places should we do this string-to-int during parsing? To avoid each step of the compiler parsing it over and over

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The most recent commit to this branch attempts this. I'm not 100% sure it's what you were meaning, but it might be!

  • Token::Int gets an int_value: Option<BigInt> field, which flows through to UntypedExpr::Int, TypedExpr::Int, Pattern::Int, and Constant::Int.
  • This field is then used for the new warning.

Copy link
Member

Choose a reason for hiding this comment

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

Very nice! Why is it optional? Shouldn't it always be present?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes you're right, I've made it always present and fixed handling of leading underscores on parsing as bigint.

There are now three .expect("int value to parse as bigint") calls, but I believe these to be safe due to previous validation done during parsing.

fn javascript_unsafe_int() {
assert_js_warning!(
r#"
pub fn go() {
Copy link
Member

Choose a reason for hiding this comment

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

Split these into multiple tests please, each test should only test one case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have made the tests more granular

@@ -1046,6 +1046,22 @@ See: https://tour.gleam.run/functions/pipelines/",
}),
}
}

type_::Warning::JavaScriptIntUnsafe { location } => Diagnostic {
title: "Int is outside JavaScript's safe integer range".into(),
Copy link
Member

Choose a reason for hiding this comment

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

It's not clear what this means, could you add more information to the test please 🙏

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have filled in the text member, the output is now:

warning: Int is outside the safe range on JavaScript
  ┌─ /Users/richard/Desktop/int_test/src/int_test.gleam:1:15
  │
1 │ pub const i = 9_007_199_254_740_992
  │               ^^^^^^^^^^^^^^^^^^^^^ This is not a safe integer on JavaScript

This integer value is too large to be represented accurately by
JavaScript's number type. To avoid this warning integer values must be in
the range -(2^53 - 1) - (2^53 - 1).

See JavaScript's Number.MAX_SAFE_INTEGER and Number.MIN_SAFE_INTEGER
properties for more information.

Copy link
Member

Choose a reason for hiding this comment

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

That's really nice!

@lpil lpil marked this pull request as draft November 1, 2024 12:53
@richard-viney richard-viney force-pushed the js-warn-on-unsafe-int branch 2 times, most recently from 28c2b0a to dadac1c Compare November 2, 2024 00:16
@richard-viney richard-viney marked this pull request as ready for review November 2, 2024 01:22
@richard-viney richard-viney force-pushed the js-warn-on-unsafe-int branch 3 times, most recently from 5327f05 to 54ffd42 Compare November 3, 2024 09:23
@richard-viney
Copy link
Contributor Author

Rebased to fix merge conflicts

Copy link
Member

@lpil lpil left a comment

Choose a reason for hiding this comment

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

Fantastic!! Thank you!

@lpil lpil merged commit 50b15f6 into gleam-lang:main Nov 4, 2024
12 checks passed
@richard-viney richard-viney deleted the js-warn-on-unsafe-int branch November 4, 2024 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Emit a warning if an int literal is too large to be represented on JavaScript
2 participants