-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Suggest simplifications for overzealous shifts #59519
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
Suggest simplifications for overzealous shifts #59519
Conversation
Can this me made a regular error temporarily to run user/topXYZ? (I also sort of feel like we should make it a regular error in general...) |
Oh boy a failing self-check build :) Always error user/top600 results rolling in here. |
Are there other common ways people can end up with two enum members of the same value by accident? |
src/compiler/checker.ts
Outdated
case SyntaxKind.GreaterThanGreaterThanGreaterThanToken: | ||
case SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: | ||
const rhsEval = evaluate(right); | ||
if (typeof rhsEval.value === "number" && Math.abs(rhsEval.value) >= 32) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this convert the value to an integer or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Math.abs
also seems unnecessary - any value below 0 seems wrong and 1 << -1 == 1 << 31
, 1 << -2 == 1 << 30
etc. so Math.abs
"reverses" it.
Interestingly, 1 << -0.9 == 1 << 0
so I guess you want Math.trunc
(or | 0
) rather than Math.floor
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any value below 0 seems wrong
It's a useful shorthand. Similar to negative slice indices in python. Not doing an abs
on the evaluated result here, either - just using it to measure the magnitude of the number to issue the error or not.
Should this convert the value to an integer or something?
Eh. Don't really need to. Fractional parts just get dropped anyway. Issuing an error on any fractional literal in a shift position would probably be fine (0.5
is the same as 0
for this operator after all), but I don't think it's particularly related to this range error.
1ef0e40
to
70afb84
Compare
Other arithmetic errors in calculated enum values, perhaps, but it may also be intentional. Especially with flags enums and bitwise arithmetic - you may end up deriving two sets of flags that just so happen to resolve to the same thing via different means. |
@typescript-bot pack this |
Hey @gabritto, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build and an npm module you can use via |
@typescript-bot test it |
Hey @gabritto, the results of running the DT tests are ready. Everything looks the same! |
@gabritto Here are the results of running the user tests with tsc comparing Everything looks good! |
@gabritto Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
@typescript-bot perf test this faster |
@gabritto Here they are:
tscComparison Report - baseline..pr
System info unknown
Hosts
Scenarios
Developer Information: |
@weswigham there seems to be a slight increase in check times for our codebase but also for vscode, webpack and xstate. Any ideas of why that could be? Do we now issue more suggestions on those repos? Is it just the extra work of evaluating operators? |
@gabritto Here are the results of running the top 400 repos with tsc comparing Everything looks good! |
Yeah, just a little bit of extra work evaluating the shifts, I imagine. |
This PR adds a suggestion on bitwise shifts where the right side operand is evaluable (which is implicitly non-
bigint
) to be outside of the range-31
to31
to simplify the shift down into that range. Doing so should make it a bit more obvious when you've accidentally exceeded the maximum shift available for a number. 😄This suggestion is escalated to an error in the context of
enum
members, since that's where it's most likely an overshift may result in an unintentionally duplicatedenum
member that is otherwise silent.So this:
results in
while this:
results in
This logic is applied for all the shift operators -
<<
,>>
,>>>
,<<=
,>>=
, and>>>=
.